• Java8 集合框架 collections framework

    一.概述

    Java8发布已经有两年半了(2014年03月),是Java5以来改动最大的一次版本发布(具体新特性http://openjdk.java.net/projects/jdk8/features )。公司项目也已经用了两年(不得不佩服国外同事在新技术使用方面的先进性),不过国内大部分公司还是在使用Java7,甚至一些传统ERP公司还在使用Java6。Dzone上面有一篇ZK关于开发者使用JDK版本使用情况调查的文章https://dzone.com/articles/current-development-trends-of-java-web-programmers

                                                                        jdk_version

    • 注:开发使用的JDK版本情况和生产上会有差别,开发中新版本比例要比生产高,一般建议开发和生产使用同版本号(包括update的小版本号)。

    本文主要介绍Java8集合框架的架构、常用集合特点用法和工具类,因为集合框架是Java中被使用最多的类库。Java8对集合框架进行了大改进,支持lambda表达式、streams 和聚合操作,以提升对Collection对象功能的增强(其中streams支持List、Queue和Set, 不支持Map)。直接使用Java集合框架的类,而不是自己编写类和方法,有以下几个好处:

    • 减少编程量
    • 提高编程速度和质量
    • 减少学习和使用新APIs的工作量
    • 促进软件重用

    一个例子就是用BlockingQueue实现生产消费者模型(BlockingQueue的javadoc里有例子),而不是自己写wait和notifyAll,因为容易出错,当然其中的原理还是要懂。

    二.集合分类和实现

    Java 集合框架中Collection是最基础的接口,另一个基础接口是Map。Collection主要由Set、Queue和List这三种接口继承,并形成三种基本的数据结构。

    1.实现了集合接口的类通常具有<Implementation-style><Interface>形式的名称,下表总结了常用的实现:

    Interface Hash Table Resizable Array Balanced Tree Linked List Hash Table + Linked List
    Set HashSet TreeSet LinkedHashSet
    List ArrayList LinkedList
    Deque ArrayDeque LinkedList
    Map HashMap TreeMap LinkedHashMap

     

    2. Collection接口及子类子接口继承实现图:

    java_collections_framework

    3.Map接口及子类子接口继承实现图:

    map  

    三.集合类在一些流行框架里面的使用情况

    虽然有些集合类(如 WeakHashMap)我们自己写代码可能会比较少用,但在一些流行框架里面使用却非常广泛,了解这些集合的特点和适用场景对于学习这些框架的设计思想和源码会很有帮助。

    1.线程池框架:

    Executors是java.util.concurrent包里面的工厂类,可以用它来返回一个制定功能(包括执行策略、扩容、调度和拒绝策略等)的线程池,而这些线程池就用到了集合框架,了解这些集合的特性能更好地使用线程池和处理可能会出现的问题:

    • newFixedThreadPool:
    public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); 
    }

    • newCachedThreadPool:
    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
    }

    • newScheduledThreadPool:
    public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
        return new ScheduledThreadPoolExecutor(corePoolSize);
    }
    
    public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS, new DelayedWorkQueue());
    }
    • newSingleThreadExecutor:
    public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService(
            new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()));
    }
    • newSingleTheadScheduledExecutor:
    public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
        return new DelegatedScheduledExecutorService(new ScheduledThreadPoolExecutor(1));
    }

    可以看到这些线程池内部的集合类都是BlockingQueue的子类(ScheduledThreadPoolExecutor的内部集合类也是继承了AbstractQueue
    <Runnable>和实现了BlockingQueue<Runnable>)。所以了解BlockingQueue的特性对于了解线程池很有帮助。

    2.几种常用Java服务,在JVM heap中数量和占用内存top 15的情况:

    (1). 基于Spring MVC 4.x + Jetty 9.x的RESTful webservice

    SpringMVC  

    (2).基于Netty 5.x的RPC server

    netty  

    (3). 基于mina 2.x 的push服务

    mina  

     

  • Maven’s common problems and solutions

    1. No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK?

    As the error message display,perhaps you used JRE for maven, but it needs JDK(in fact, javac) as compiler. JRE is just the Java runtime environment, while JDK is the Java development kit containing the the compiler javac for java code. In fact, Eclipse uses JRE as its default environment, and used its own compiler JDT. So when using maven to compile, the operation fails.

    Solution: go into  Windows -> Perferences -> Java -> Installed JREs. Note the underlined part is jdk not jre.

    .jres

     

    2. Could not resolve dependencies for project XXX:jar:0.1: Failure to find XXX:jar:0.0.1 in https://repo.maven.apache.org/maven2 was cached in the local repository, resolution will not be reattempted until the update interval of central has elapsed or updates are forced.

    There are some files with the names ending in the .lastUplated suffix in your local repository, so maven will not compile again.

    Solution:

    1) for maven command: mvn clean install -U

    2) for Eclipse:

    mvn

     

    3. error reading C:\Users\Administrator\.m2\repository\XXX.jar; invalid LOC header (bad signature)

    That is because there are some incomplete in maven local repository. May be you can see some files with names ending in -in-progress suffix.

    123
    Solution: delete the whole folder which contains the incomplete jar file, and compile again.