Java基础知识回顾-2

各种jdk版本下载:http://www.oracle.com/technetwork/java/archive-139210.html

http://tianya23.blog.51cto.com/1081650/305251

  1. Java核心API需要掌握的程度 
  2.  
  3. Java的核心API是非常庞大的,这给开发者来说带来了很大的方便,经常人有评论,java让程序员变傻。  
  4.  
  5. 但是一些内容我认为是必须掌握的,否则不可以熟练运用java,也不会使用就很难办了。  
  6.  
  7. 1、java.lang包下的80%以上的类的功能的灵活运用。  
  8.  
  9. 2、java.util包下的80%以上的类的灵活运用,特别是集合类体系、正规表达式、时间、属性、和Timer.  
  10.  
  11. 3、java.io包下的60%以上的类的使用,理解IO体系的基于管道模型的设计思路以及常用IO类的特性和使用场合。  
  12.  
  13. 4、java.math包下的100%的内容。  
  14.  
  15. 5、java.net包下的60%以上的内容,对各个类的功能比较熟悉。  
  16.  
  17. 6、java.text包下的60%以上的内容,特别是各种格式化类。  
  18.  
  19. 7、熟练运用JDBC.  
  20.  
  21. 8、java.security包下40%以上的内容,如果对于安全没有接触的话根本就不可能掌握java.  
  22.  
  23. 9、AWT的基本内容,包括各种组件事件、监听器、布局管理器、常用组件、打印。  
  24.  
  25. 10、Swing的基本内容,和AWT的要求类似。  
  26.  
  27. 11、XML处理,熟悉SAX、DOM以及JDOM的优缺点并且能够使用其中的一种完成XML的解析及内容处理 

Apache下面的重要内容:

commons:http://commons.apache.org/

jakarta:http://jakarta.apache.org/

  1. commons-pool-1.3.jar 
  2. commons-logging-1.1.1.jar 
  3. commons-lang-2.5.jar 
  4. commons-io-1.4.jar 
  5. commons-dbcp-1.2.2.jar 
  6. commons-collections-3.1.jar 
  7. commons-beanutils-1.7.0.jar 

 

1、可变参数与foreach

  1. public class Demo01{ 
  2.     public static void main(String args[]){ 
  3.         System.out.print("不传递参数(fun()):") ; 
  4.         fun() ;         // 不传递参数 
  5.         System.out.print("\n传递一个参数(fun(1)):") ; 
  6.         fun(1) ;        // 传递一个参数 
  7.         System.out.print("\n传递五个参数(fun(1,2,3,4,5)):") ; 
  8.         fun(1,2,3,4,5) ; 
  9.     } 
  10.     public static void fun(int ... arg){    // 可变参数 
  11.         for(int x:arg){     // 使用foreach输出输出 
  12.             System.out.print(x + "、") ; 
  13.         } 
  14.     } 
  15. }; 

 2、多线程程序

(1)继承Thread类

  1. class MyThread extends Thread{  // 继承Thread类,作为线程的实现类 
  2.     private String name ;       // 表示线程的名称 
  3.     public MyThread(String name){ 
  4.         this.name = name ;      // 通过构造方法配置name属性 
  5.     } 
  6.     public void run(){  // 覆写run()方法,作为线程 的操作主体 
  7.         for(int i=0;i<10;i++){ 
  8.             System.out.println(name + "运行,i = " + i) ; 
  9.         } 
  10.     } 
  11. }; 
  12. public class ThreadDemo02{ 
  13.     public static void main(String args[]){ 
  14.         MyThread mt1 = new MyThread("线程A ") ;    // 实例化对象 
  15.         MyThread mt2 = new MyThread("线程B ") ;    // 实例化对象 
  16.         mt1.start() ;   // 调用线程主体 
  17.         mt2.start() ;   // 调用线程主体 
  18.     } 
  19. }; 

(2)实现Runnable接口

  1. class MyThread implements Runnable{ // 实现Runnable接口,作为线程的实现类 
  2.     private String name ;       // 表示线程的名称 
  3.     public MyThread(String name){ 
  4.         this.name = name ;      // 通过构造方法配置name属性 
  5.     } 
  6.     public void run(){  // 覆写run()方法,作为线程 的操作主体 
  7.         for(int i=0;i<10;i++){ 
  8.             System.out.println(name + "运行,i = " + i) ; 
  9.         } 
  10.     } 
  11. }; 
  12. public class RunnableDemo01{ 
  13.     public static void main(String args[]){ 
  14.         MyThread mt1 = new MyThread("线程A ") ;    // 实例化对象 
  15.         MyThread mt2 = new MyThread("线程B ") ;    // 实例化对象 
  16.         Thread t1 = new Thread(mt1) ;       // 实例化Thread类对象 
  17.         Thread t2 = new Thread(mt2) ;       // 实例化Thread类对象 
  18.         t1.start() ;    // 启动多线程 
  19.         t2.start() ;    // 启动多线程 
  20.     } 
  21. }; 

[注意]在资源共享时,比如100张票,使用

  1. MyThread mt1 = new MyThread("线程A ") ;    // 实例化对象  
  2.     Thread t1 = new Thread(mt1) ;       // 实例化Thread类对象  
  3.     Thread t2 = new Thread(mt1) ;       // 实例化Thread类对象  
  4.     t1.start() ;    // 启动多线程  
  5.     t2.start() ;    // 启动多线程  

 

3、计划任务类:Timer、TimerTask 

  1. // 完成具体的任务操作  
  2. import java.util.TimerTask ; 
  3. import java.util.Date ; 
  4. import java.text.SimpleDateFormat ; 
  5. class MyTask extends TimerTask{ // 任务调度类都要继承TimerTask 
  6.     public void run(){ 
  7.         SimpleDateFormat sdf = null ; 
  8.         sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS") ; 
  9.         System.out.println("当前系统时间为:" + sdf.format(new Date())) ; 
  10.     } 
  11. }; 

 测试类,进行调度执行:

  1. import java.util.Timer ; 
  2. public class TestTask{ 
  3.     public static void main(String args[]){ 
  4.         Timer t = new Timer() ; // 建立Timer类对象 
  5.         MyTask mytask = new MyTask() ;  // 定义任务 
  6.         t.schedule(mytask,1000,2000) ;  // 设置任务的执行,1秒后开始,每2秒重复 
  7.     } 
  8. }; 

【注意】

执行计划任务是使用后台多线程实现的,如果主线程退出,则无法继续执行该计划任务。例如在单元测试中使用,需要将测试方法Thread.sleep(10000000);休眠主线程,保证其不退出方可达到预期的目的。

 

 4、观察着模式实现

  1. import java.util.* ; 
  2. class House extends Observable{ // 表示房子可以被观察 
  3.     private float price ;// 价钱 
  4.     public House(float price){ 
  5.         this.price = price ; 
  6.     } 
  7.     public float getPrice(){ 
  8.         return this.price ; 
  9.     } 
  10.     public void setPrice(float price){ 
  11.         // 每一次修改的时候都应该引起观察者的注意 
  12.         super.setChanged() ;    // 设置变化点 
  13.         super.notifyObservers(price) ;// 价格被改变 
  14.         this.price = price ; 
  15.     } 
  16.     public String toString(){ 
  17.         return "房子价格为:" + this.price ; 
  18.     } 
  19. };  
  20. class HousePriceObserver implements Observer{ 
  21.     private String name ; 
  22.     public HousePriceObserver(String name){ // 设置每一个购房者的名字 
  23.         this.name = name ; 
  24.     } 
  25.     public void update(Observable o,Object arg){ 
  26.         if(arg instanceof Float){ 
  27.             System.out.print(this.name + "观察到价格更改为:") ; 
  28.             System.out.println(((Float)arg).floatValue()) ; 
  29.         } 
  30.     } 
  31. }; 
  32. public class ObserDemo01{ 
  33.     public static void main(String args[]){ 
  34.         House h = new House(1000000) ; 
  35.         HousePriceObserver hpo1 = new HousePriceObserver("购房者A") ; 
  36.         HousePriceObserver hpo2 = new HousePriceObserver("购房者B") ; 
  37.         HousePriceObserver hpo3 = new HousePriceObserver("购房者C") ; 
  38.         h.addObserver(hpo1) ; 
  39.         h.addObserver(hpo2) ; 
  40.         h.addObserver(hpo3) ; 
  41.         System.out.println(h) ; // 输出房子价格 
  42.         h.setPrice(666666) ;    // 修改房子价格 
  43.         System.out.println(h) ; // 输出房子价格 
  44.     } 
  45. }; 

 5、本机字符编码

  1. public class CharSetDemo01{ 
  2.     public static void main(String args[]){ 
  3.         System.out.println("系统默认编码:" + 
  4.             System.getProperty("file.encoding")) ;  // 获取当前系统编码 
  5.     } 
  6. }; 


异或=a`b+b`a

true ^true = false

false^false = flase

true^false = true

false^true =true

从这个关系上,我们可以看到 按位异或,同样的整数异或的结果为0。这样我们可以把 N整数和N-1的整数做异或运算,就知道最后一个数,就是2个数组差集。

代码如下:

JavaScript代码
  1. var a=[5,2,3,4,9]   
  2.   var b=[9,2,3,4]   
  3.   c=0   
  4.   for(var i=0;i<a.length;i++){   
  5.   c ^=a[i]   
  6.   }   
  7.   for(var j=0;j<b.length;j++){   
  8.   c ^=b[j]   
  9.   }   
  10.  alert(c)  

 7、NIO(新IO)解决IO吞吐慢的问题: Selector

  1. import java.net.InetSocketAddress ; 
  2. import java.net.ServerSocket ; 
  3. import java.util.Set ; 
  4. import java.util.Iterator ; 
  5. import java.util.Date ; 
  6. import java.nio.channels.ServerSocketChannel ; 
  7. import java.nio.ByteBuffer ; 
  8. import java.nio.channels.SocketChannel ; 
  9. import java.nio.channels.Selector  ; 
  10. import java.nio.channels.SelectionKey  ; 
  11. public class DateServer{ 
  12.     public static void main(String args[]) throws Exception { 
  13.         int ports[] = {8000,8001,8002,8003,8005,8006} ; // 表示五个监听端口 
  14.         Selector selector = Selector.open() ;   // 通过open()方法找到Selector 
  15.         for(int i=0;i<ports.length;i++){ 
  16.             ServerSocketChannel initSer = null ; 
  17.             initSer = ServerSocketChannel.open() ;  // 打开服务器的通道 
  18.             initSer.configureBlocking(false) ;  // 服务器配置为非阻塞 
  19.             ServerSocket initSock = initSer.socket() ; 
  20.             InetSocketAddress address = null ; 
  21.             address = new InetSocketAddress(ports[i]) ; // 实例化绑定地址 
  22.             initSock.bind(address) ;    // 进行服务的绑定 
  23.             initSer.register(selector,SelectionKey.OP_ACCEPT) ; // 等待连接 
  24.             System.out.println("服务器运行,在" + ports[i] + "端口监听。") ; 
  25.         } 
  26.         // 要接收全部生成的key,并通过连接进行判断是否获取客户端的输出 
  27.         int keysAdd = 0 ; 
  28.         while((keysAdd=selector.select())>0){   // 选择一组键,并且相应的通道已经准备就绪 
  29.             Set<SelectionKey> selectedKeys = selector.selectedKeys() ;// 取出全部生成的key 
  30.             Iterator<SelectionKey> iter = selectedKeys.iterator() ; 
  31.             while(iter.hasNext()){ 
  32.                 SelectionKey key = iter.next() ;    // 取出每一个key 
  33.                 if(key.isAcceptable()){ 
  34.                     ServerSocketChannel server = (ServerSocketChannel)key.channel() ; 
  35.                     SocketChannel client = server.accept() ;    // 接收新连接 
  36.                     client.configureBlocking(false) ;// 配置为非阻塞 
  37.                     ByteBuffer outBuf = ByteBuffer.allocateDirect(1024) ;   // 
  38.                     outBuf.put(("当前的时间为:" + new Date()).getBytes()) ;   // 向缓冲区中设置内容 
  39.                     outBuf.flip() ; 
  40.                     client.write(outBuf) ;  // 输出内容 
  41.                     client.close() ;    // 关闭 
  42.                 } 
  43.             } 
  44.             selectedKeys.clear() ;  // 清楚全部的key 
  45.         } 
  46.          
  47.     } 

 可以通过telnet连接该端口,进行同时的(即异步)接收数据。

 8、switch case中使用enum类型

  1. public enum Position { 
  2.     BOSS, ENGINEER, SALES; 

在switch、case语句中使用定义的枚举Postilion;【注意】case语句中不能出现Postilion这个枚举类型

  1. public class SalaryImpl implements Salary { 
  2.  
  3.     @Override 
  4.     public float getSalary(Position position) { 
  5.         float salary = 0.0f; 
  6.         switch (position) { 
  7.         case BOSS: 
  8.             salary = 7000f; 
  9.             break
  10.         case ENGINEER: 
  11.             salary = 5000f; 
  12.             break
  13.         case SALES: 
  14.             salary = 3000f; 
  15.             break
  16.         default:  
  17.             salary = 1000f; 
  18.         } 
  19.         return salary; 
  20.     } 

 9、将JSON格式转换为Set

  1. import java.io.File; 
  2. import java.io.IOException; 
  3. import java.util.HashSet; 
  4. import java.util.Set; 
  5. import net.sf.json.JSONArray; 
  6. import net.sf.json.JsonConfig; 
  7. import org.apache.commons.io.FileUtils; 
  8.  
  9. public class JsonFile { 
  10.     @SuppressWarnings("unchecked"
  11.     public static Set<String> load(String fileName) throws Exception { 
  12.         try { 
  13.             File newBackup = new File(fileName); 
  14.             String jsonStr = FileUtils.readFileToString(newBackup); 
  15.             JsonConfig config = new JsonConfig(); 
  16.             config.setRootClass(String.class);// 序列化前的元素类型 
  17.             config.setCollectionType(Set.class);// 序列化前的集合类型 
  18.             return (HashSet<String>) JSONArray.toCollection(JSONArray 
  19.                     .fromObject(jsonStr), config); 
  20.         } catch (IOException e) { 
  21.             throw new RuntimeException("load backup fail,path:" + fileName, e); 
  22.         } 
  23.  
  24.     } 

 10、通过URL取得链接的内容(html文档)

  1. public class GetURLContent { 
  2.  
  3.     public static String getContent(String urlname) { 
  4.         String message = ""
  5.         try { 
  6.             URL url = new URL(urlname); 
  7.             HttpURLConnection connect = (HttpURLConnection) url 
  8.                     .openConnection(); 
  9.             connect.setDoInput(true); 
  10.             connect.setDoOutput(true); 
  11.             BufferedReader in = new BufferedReader(new InputStreamReader( 
  12.                     connect.getInputStream())); 
  13.             String line = null
  14.             StringBuffer content = new StringBuffer(); 
  15.             while ((line = in.readLine()) != null) {// line为返回值,这就可以判断是否成功、 
  16.                 content.append(line); 
  17.             } 
  18.             in.close(); 
  19.             in = null
  20.             url = null
  21.             message = content.toString(); 
  22.             //System.err.println(message); 
  23.         } catch (IOException ex) { 
  24.             ex.printStackTrace(); 
  25.         } catch (Exception e) { 
  26.             System.out.println("出现错误" + e.getStackTrace()); 
  27.         } 
  28.         return message; 
  29.     } 
  30.  
  31.     public static void main(String[] args) { 
  32.         System.out 
  33.                 .println(GetURLContent 
  34.                         .getContent("http://10.20.136.29/r/aHR0cDovL3d3dy50YW9iYW8uY29t")); 
  35.     } 

 11、Junit4的断言加强:放弃旧的断言,使用hamcrest断言

1.         assertThat

2.         使用hamcrest的匹配方法

a)         更自然

3.         示例

  1. a) 
  2. assertThat( n, allOf( greaterThan(1), lessThan(15) ) ); 
  3. assertThat( n, anyOf( greaterThan(16), lessThan(8) ) ); 
  4. assertThat( n, anything() ); 
  5. assertThat( str, is( "bjsxt" ) ); 
  6. assertThat( str, not( "bjxxt" ) ); 
  7.  
  8. b)        
  9. assertThat( str, containsString( "bjsxt" ) ); 
  10. assertThat( str, endsWith("bjsxt" ) );  
  11. assertThat( str, startsWith( "bjsxt" ) );  
  12. assertThat( n, equalTo( nExpected ) );  
  13. assertThat( str, equalToIgnoringCase( "bjsxt" ) );  
  14. assertThat( str, equalToIgnoringWhiteSpace( "bjsxt" ) ); 
  15.  
  16. c)         
  17. assertThat( d, closeTo( 3.00.3 ) ); 
  18. assertThat( d, greaterThan(3.0) ); 
  19. assertThat( d, lessThan (10.0) ); 
  20. assertThat( d, greaterThanOrEqualTo (5.0) ); 
  21. assertThat( d, lessThanOrEqualTo (16.0) ); 
  22.  
  23. d)        
  24. assertThat( map, hasEntry( "bjsxt""bjsxt" ) ); 
  25. assertThat( iterable, hasItem ( "bjsxt" ) ); 
  26. assertThat( map, hasKey ( "bjsxt" ) ); 
  27. assertThat( map, hasValue ( "bjsxt" ) ); 

 

 12、oracle一个该死的BUG,后来查它的文档说叫限制. 

 from:http://blog.csdn.net/axman/archive/2006/07/07/887973.aspx

  1. import java.sql.Connection; 
  2. import java.sql.DriverManager; 
  3. import java.sql.PreparedStatement; 
  4. import java.sql.ResultSet; 
  5.  
  6. public class OracleBug { 
  7.     public static void main(String[] args) throws Exception { 
  8.         Class.forName("oracle.jdbc.driver.OracleDriver"); 
  9.         Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@10.20.136.24:1521:orcl","scott","tiger"); 
  10.          
  11.         PreparedStatement ps = conn.prepareStatement("select * from tb_test"
  12.                 ResultSet.TYPE_SCROLL_SENSITIVE, 
  13.                                 ResultSet.CONCUR_UPDATABLE); 
  14.       ResultSet rs = ps.executeQuery(); 
  15.       rs.moveToInsertRow(); 
  16.       rs.updateString("name","axmannn1111"); 
  17.       rs.insertRow(); 
  18.     } 

 会告诉你不能对只读结果集更新.竟然不能得到可更新结果集.
可是如果你"select col1,col2..... from tb_test",就可以,

 13、运行时异常的设计和使用

好处:不用改变接口(即向外声明的标准);运行时异常不用显示的捕获,也可以捕获,根据调用者的能力

1、实现:继承自java.lang.RuntimeException, 且选中“Constructors from superclass”, 再补充完整serialVersionUID即可, 代码如下:

  1. public class ServiceException extends RuntimeException { 
  2.  
  3.     private static final long serialVersionUID = 1L; 
  4.  
  5.     public ServiceException() { 
  6.         // TODO Auto-generated constructor stub 
  7.     } 
  8.  
  9.     public ServiceException(String message) { 
  10.         super(message); 
  11.         // TODO Auto-generated constructor stub 
  12.     } 
  13.  
  14.     public ServiceException(Throwable cause) { 
  15.         super(cause); 
  16.         // TODO Auto-generated constructor stub 
  17.     } 
  18.  
  19.     public ServiceException(String message, Throwable cause) { 
  20.         super(message, cause); 
  21.         // TODO Auto-generated constructor stub 
  22.     } 
  23.  

 调用方在catch中添加如下代码:throw new ServiceException(e.getMessage(),e);

 2、初始化时出现异常,特别是加载文件的时候,直接抛出初始化异常:throw new ExceptionInInitializerError(e);

 14、JSON到集合类型的转换

  1. String jsonStr = "[\"bac\",\"def\",\"him\"]"
  2.         System.out.println(jsonStr); 
  3.         Collection<String> list = JSONArray.toCollection(JSONArray.fromObject(jsonStr), String.class); 
  4.          for(String str : list){ 
  5.              System.out.println(str); 
  6.          } 

 输出结果:

  1. ["bac","def","him"
  2. bac 
  3. def 
  4. him 

15、  JDK自带命令native2ascii的用法 

 

native2ascii是sun java sdk提供的一个工具。用来将别的文本类文件(比如*.txt,*.ini,*.properties,*.java等等)编码转为Unicode编码。为什么要进行转码,原因在于程序的国际化。
用法:native2ascii [-reverse] [-encoding 编码] [输入文件 [输出文件]]
-[options]:表示命令开关,有两个选项可供选择
-reverse:将Unicode编码转为本地或者指定编码,不指定编码情况下,将转为本地编码。
-encoding encoding_name:转换为指定编码,encoding_name为编码名称。
[inputfile [outputfile]]
inputfile:表示输入文件全名。
outputfile:输出文件名。如果缺少此参数,将输出到控制台

JDK中自带的native2ascii功能还是比较强的。简单做以下介绍。

1、只转换特定字符

native2ascii

在控制台中可以输入汉字回车后,就可以看到转移后的字符了。
 Ctrl+C退出。
2、转换properties文件

Java基础知识回顾-2_职场native2ascii allMessages_zh_CN.input.properties allMessages_zh_CN.properties

将文件allMessages_zh_CN.input.properties编码后输出为allMessages_zh_CN.properties。
为了方便properties文件的管理,建议纯中文的配置文件用input命名。
3、反向单一properties文件

Java基础知识回顾-2_职场native2ascii -reverse allMessages_zh_CN.properties allMessages_zh_CN.txt

注意-reverse参数

4、批量反向所有的properties文件
使用工具UncodeReverse.exe
详见:批量转换Uncode编码的文件,地址 
http://blog.csdn.net/z3h/archive/2008/01/25/2065912.aspx

native2ascii相关链接:

 http://hi.baidu.com/suofang/blog/item/b38bb5019b6b0e03728da562.html

http://www.chinaitpower.com/A200507/2005-07-24/165716.html

 

 16、IdentityHashMap使用

允许key相同,而value不同

  1. Map<Person, String> map = new IdentityHashMap<Person, String>(); 
  2.         map.put(new Person("zhangsan",30), "zhangsan1"); 
  3.         map.put(new Person("zhangsan",30), "zhangsan2"); 
  4.         map.put(new Person("lisi",30), "lisi1"); 
  5.          
  6.         Set<Person> set = map.keySet(); 
  7.         for(Person person :  set){ 
  8.             System.out.println(person + ": " + map.get(person)); 
  9.         } 

 运行结果:

  1. Person [age=30, name=zhangsan]: zhangsan1 
  2. Person [age=30, name=zhangsan]: zhangsan2 
  3. Person [age=30, name=lisi]: lisi1 

 17、System类介绍

(1)得到系统的各种资源属性:System.getProperties();

  1. Properties pro = System.getProperties(); 
  2. pro.list(System.out); 

 18、setter方法的优雅处理

  1. public static final String DEFAULT_PATH_SEPARATOR = "/"
  2.  
  3.    private String pathSeparator = DEFAULT_PATH_SEPARATOR; 
  4.  
  5.    public void setPathSeparator(String pathSeparator) { 
  6.        this.pathSeparator = (pathSeparator != null ? pathSeparator : DEFAULT_PATH_SEPARATOR); 
  7.    } 

 19、 CAS 
 1、CAS:  CPU指令 和 程序并发原语中存在 CAS 概念, Compare and Set, 就是修改一个寄存器区域或变量值时,先检查 old value, old value相同再进行修改,否则放弃。 
   例如: 
   已知 int a = 1; 

引用
   非 CAS 赋值为:  a = 10; 
   CAS 赋值为   compareAndSet( 1, 10); 


  这样,在多线程并发操作时,最终 a 将被原子性的修改,而不会发生冲突的结果。 
   而数据库的事务中并发冲突的场景与之非常类似,都是对共享资源竞争访问时的突出问题。 

2. 基于CAS机制的数据库update操作 
   由CAS的原理,可以考虑以类似的方式处理数据库的update操作。 
   假定订单 OD_0100 的总价款为1100 元, 现在要将其修改为 1500 元, 

引用
   update sale_order set order_amount = 1500.00 
   where order_id = 'OD_0100' 



采用 CAS 机制进行修改,假定已经知道订单修改前的总价款 1100,则update SQL为 

引用

   update sale_order set order_amount = 1500.00 
   where order_id = 'OD_0100' 
     and order_amount = 1100.00 


  若出现并发冲突,例如:order_amount 已经先其他请求修改为 900, 那么上面的 update 语句的操作结果数为 0; 此时,客户端需要重新查询订单,再尝试第二次修改。 这类似于 CAS 中的自旋。 

3. 与其他事务机制比较 
  数据库事务有悲观锁和乐观锁,乐观锁有一种机制是基于 version 字段来控制并发修改冲突。 
  与version事务机制类似,CAS事务也是一种细粒度的锁。然而,version 为行级锁,粒度过大; 而 CAS 事务为列级锁,粒度更小。 根据锁机制的一般原则,粒度越小,并发性能越高。  

 20、三元运算符

在返回值需要有默认值时常用:

return zipCode == null ? "" : zipCode;//如果为null, 则使用"",否则使用zipCode值。

21、CopyOnWriteArrayList:支持并发改动的List

  1. List<Integer> list = new ArrayList<Integer>(); 
  2.     list.add(1); 
  3.     List<Integer> cw = list; 
  4.     cw.add(2); 
  5.     for(int a : list){ 
  6.         System.out.println(a); 
  7.     } 
  8.     System.out.println("----------"); 
  9.     for(int a : cw){ 
  10.         System.out.println(a); 
  11.     } 

 结果:

  1. ---------- 

使用CopyOnWriteArrayList, 则完全生成新的List, 实现深度拷贝。

  1. ---------- 

 22、网络编程相关

  1. @Test public void test1() throws Exception{ 
  2.     InetAddress localAddr = InetAddress.getLocalHost(); 
  3.     InetAddress remoteAddr = InetAddress.getByName("www.sina.com.cn"); 
  4.     System.out.println("local addr: " + localAddr.getHostAddress()); 
  5.     System.out.println("remote addr: " + remoteAddr.getHostAddress()); 
  6.      
  7.     boolean access = localAddr.isReachable(1000); //测试1000毫秒内是否可达
  8.     System.out.println(access); 

 URL类使用:

  1. URL url = new URL("http","www.mldnjava.cn",80,"/curriculum.htm") ; 
  2.     InputStream input = url.openStream() ;  // 打开输入流 
  3.     Scanner scan = new Scanner(input) ;     // 实例化Scanner类 
  4.     scan.useDelimiter("\n") ;   // 设置读取分隔符 
  5.     while(scan.hasNext()){ 
  6.         System.out.println(scan.next()) ; 
  7.     } 

 URLConnection类使用:

  1. URL url = new URL("http://www.mldnjava.cn") ; 
  2.     URLConnection urlCon = url.openConnection() ;   // 建立连接 
  3.     System.out.println("内容大小:" + urlCon.getContentLength()) ; 
  4.     System.out.println("内容类型:" + urlCon.getContentType()) ; 

 URLEncoder和URLDecoder使用:常常在有中文、空格之类需要网络传输的情况下使用

  1. String keyWord = "张三" ;   
  2. String encod = URLEncoder.encode(keyWord,"UTF-8") ; // 进行编码的操作 
  3. System.out.println("编码之后的内容:" + encod) ; 
  4. String decod = URLDecoder.decode(encod,"UTF-8") ; // 进行解码操作 
  5. System.out.println("解码之后的内容:" + decod) ;