鲜活的java 8 --- java 8 进化之路(一)

2014-11-23 22:14:57 · 作者: · 浏览: 0

最近在学习java8的新特性。 首先先来安装java8。 Java8 在 win7下很容易安装,但是官方不支持win XP. windows Xp java8无法安装。如果在xp下安装会报这样的错误:

无法定位程序输入点 RegDeleteKeyExA 于动态链接库 ADVAPI32.dll

\


如果非要在32位的xp系统,可以先下载java8的jdk的exe文件。然后使用7zip进行解压。再解压tools.zip文件。最后你能得到下面的目录结构:

\

在这个目录下执行如下的命令:

FOR /R %f IN (*.pack) DO "d:\java8\bin\unpack200.exe" -r -v "%f" "%~pf%~nf.jar"

注意d:\java8\bin\unpack200.exe 这个。这个是你的解压路径中的unpack200.exe。上面的命令就是使用解压中的unpack200.exe将整个解压路径中的.pack文件转换为.jar文件. 转换完之后,d:\java8这个路径就已经是JAVA_HOME路径。

下面就是IDE也能使用java1.8的新特性。下载一个新版本的eclipse。另外如果是eclipse kepler 可以在eclipse market中下载一个java8的插件“Eclipse Java Development Tools Patch with Java 8 support (for Kepler SR2)“。 然后在tab中windows->Pererfence->java->Installed JREs => "add.." => Standard VM => JRE home选择之前的那个解压路径。剩下的内容eclipse会帮你填充。然后一路点击确认就可以了。

\

然后将execute Environments 选中 javaSE-1.8, 然后选中 Java8 ,点击确定。

\

新建立一个工程。然后将Java Compiler选中 1.8的版本。

\

然后新建一个interface。编写如下代码。如果IDE没有报错。那么eclipse IDE就已经可以使用java8的新特性了。

public interface TestDefault {
    default void pirnt(){
        System.out.println();
    }
}
下面的图里没有编译错误

\

对于java8, 网上说了55条新特性。但详细看来,最有用的也就那么几条。下面罗列一下:

1. 消除持久代. 再也没有OutOfMemoryError. PermGen Space 这样的错误了。持久代(Interned 字符串, 类元数据和类静态变量)合并入Heap Space或者direct buffer. 以后可能更多的会OutOfMemoryError: Heap space.

2. Annotation更加强大。可以在函数参数中加入@notnull 这样的标记,来判断参数是否为null. 另外还有可以用来消除public, private 这些关键字。

3. 加密方面,AES使用了CPU指令,可以更快加解密。用SHA-224代替SHA-1. 支持了64位windows的PKCS#11,加解密AES,RSA支持更多的PKCS。

4. 加入JS 引擎。 可以运行js脚本。这对node.js, webview的使用意义更大

5. Http URL, 支持Http GET, POST 操作,这个是要在未来代替HttpClient吗?

6.使用平衡树处理HashMap中的冲突,对于频繁的冲突会将List替换成平衡树。这样做会提高HashMap的插入速度。

7. Base64终于可以名正言顺的使用。java.util.Base64.Encoder 和java.util.Base64.Decoder. 而不要使用过去的sun.misc.BASE64Encoder等。

8. 并发的支持。增加适用于频繁更新但非频繁读取的原子变量。ConcurrentHashMap更新,Fork-Join框架更新。Arrays.sort有了并发的sort => Arrays.parallelSort, 可以很好的利用多核的资源。据说性能在数据均衡的情况下最少提升了30%。

9. lamda表达式引入,接口中的default function以及stream


对于以上几点主要说说第8和第9点。对于第8点做了个小实验验证了一下并发情况下的排序性能提升:

public class TestJava8 {
    public static void main(String[] args) {
        int count =10000000;
        int[] k = new int[count];
        Random r = new Random();
        for (int j= 0; j < 5; j++) {
            for (int i = 0;i
  
   

在公司里的伪双核的机器上跑。反复几次,当如也有可能期间夹杂了gc()的影响。结果基本是这样的:

1398:parallel:
1373:serial:
1224:parallel:
1287:serial:
1261:parallel:
1274:serial:
1304:parallel:
1314:serial:
1234:parallel:
1480:serial:


从结果上看,基本上并发还是需要使用在数据量较大的情况下。但是如果数据量大是否能使用内存排序还是个问题。对于parallelSort, Java8还是使用的Fork-Join的模式。对于小数据量效果并不佳,因为开启线程还是要费些时间的。我个人认为java8 对于Arrays.sort()这个接口,还是默默的做并发/非并发判断比较好。毕竟多核都对java程序员隐藏的话,并发sort()啥的最好也能对java程序员隐藏。否则又要在上面包一层先判断一下数据量大小,然后再执行sort() or parallelSort(). 另外官方所说的数据均衡的情况下最少提升了30%。 这个意思是说官方的测试在比较均衡的数据集跑出来的,但是一般在生产环境中的数据集是不均衡的。


java8 最大的亮点就是lamda表达式。可以使用java进行函数式编程。这样的好处是什么呢?

1. 如果lamda表达式只对变量进行只读操作,那一定是threadSafe. 非只读的情况需要特殊判读是否是threadSafe.

2. 如果是threadSafe 一定可以并发执行

3. 从参数推出结果,是针对API接口编程。(这点有些虚)

4. 返回的结果也可以是函数


一段代码这样写:

// 求一个List中的最大值	
public static void main(String[] args) {
		List
    
      k = new ArrayList
     
      (); k.add(1); k.add(2); k.add(3); k.add(8); k.add(11); k.add(20); k.add(50); int max = Integer.MIN_VALUE; for (int j : k) { if (max < j) { max = j; } } System.out.println(max); }
     
    


假如这段代码中查找最大值成了性能瓶颈,那么需要将这段代码改为并发操作。想想就不容易。那现在使用lamda表达式这样写:

// 求一个链表中的最大值
public static void main(String[] args) {
		
		List
    
      k = new ArrayList
     
      (); k.add(1); k.add(2); k.add(