java集合类笔记

java集合类是Java程序员经常使用的工具类。它里面的实现方式其实涵盖了很多的数据结果,比如:队列、栈。其中Java集合大致可以分为Set、List、Map三中体系。先主要从三个容器的使用、实现机制、使用场景做下分析总结。总结性概括:Set体系是无序的、不可重复的集合。List代表无序、可以重复。Map代表键值对。还有Queue体系结构。集合类的框架图如下:特性不同主要来源于实现的不一致性:



Set:set里面的元素是否相等的判断是通过 equal()方法进行。

public class SetTest {

    public static void main(String[] args) {
        Set set = new HashSet();
        set.add(new String("book1"));
        set.add(new String("book1")); //q,则两个对象,也是只插入一个数据
        System.out.println(set); //[book1]

        Set s = Collections.synchronizedSet(set) ;
    }

}


HashSet类:不能保证元素的排列顺序,且不是同步的需要使用工具保证同步,值可以是null;

 Set s = Collections.synchronizedSet(set) ;

HashSet判断两个元素相等的标准是通过equal()与HashCode()两个方法同时满足。

若equal通过,则HashCode不通过,则一样是两个不同的元素。放在不同的位置。hashCode是存放位置的值索引。

注意,如果需要重写equal的,也需要重写hashcode,使两者的步骤保持一致。如果hashCode相等,equal不等,则会放在同一个桶里,用链表存储。影响查询的性能。

LinkedHashSet类:保持插入的顺序

TreeSet类:

<pre name="code" class="java">public class TreeSetTest {
    public static void main(String[] args) {
        TreeSet set = new TreeSet();
        set.add(1);
        set.add(3);
        set.add(2);
        set.add(4);

        System.out.println(set);
        System.out.println(set.first());
        System.out.println(set.headSet(2));//比2小的元素
        System.out.println(set.tailSet(3));  //>=3的元素
        System.out.println(set.subSet(2, 3));// 2<=X <3
    }
}


 

TreeSet函数是compareTo(Object obj)进行比较的,所以如果要使用TreeSet进行对象的比较,对象需要实现Comparable接口,否则会抛异常
TreeSet treeSet = new TreeSet();
treeSet.add(new TreeSetTest());
treeSet.add(new TreeSetTest()); //抛异常
 

最好 不要对 HashSet 或者TreeSet集合引入可变对象,因为这样子,如果中间参数改变,则会影响treeSet的索引。

EnumSet类:专门为枚举类型而设计的一个集合类。

enum Eason{
    Spring,Summer,Autom,Winter
}

public class EnumSetTest {
    public static void main(String[] args){
        EnumSet enumSet = EnumSet.allOf(Eason.class);   //创建的集合包含全部的Eason
       // enumSet.add("test"); //抛异常,不是枚举Eason类型
       // enumSet.add(Eason.Winter);   //不会重复加进去
        System.out.println(enumSet);
        EnumSet nullEnumSet = EnumSet.noneOf(Eason.class);   //创建了个空集合
        System.out.println(nullEnumSet);
        EnumSet enumSet3 = EnumSet.of(Eason.Autom, Eason.Winter);   //[Autom, Winter]
        System.out.println(enumSet3);
        EnumSet enumSet4 = EnumSet.range(Eason.Summer,Eason.Winter); //[Summer, Autom, Winter]
        System.out.println(enumSet4);
    }
}


各Set实现类的性能分析:都是非线性安全的,需要靠工具来维护:
SortedSet sortedSet = Collections.synchronizedSortedSet(new TreeSet());

HashSet:添加、查询 

LinkedHashSet:遍历较快

TreeSet:保持有序 ,需要维护一个红黑树
EnumSet:性能最快,但是只能保存枚举值 


List:是一个有序的,可重复的集合。

判断两个元素是否相等,也是通过equals进行判断。List提供的是listIterator()方法,该方法返回的是一个ListIterator()对象,继承了Iterator接口,直接看代码看他有哪些方法:

Queue集合

模拟队列的数据结构。

add(object o); peek();//获取队列头部元素,但不删除此元素,如果此队列为空,则返回null;poll();//获取队列头部元素,并删除该元素

offer(object o);此方法与add的作用类似,但是这个比较适用于有容量的限制的。

PriorityQueue实现类

是一个比较标准的队列实现类。按元素的优先级进行排序的。如果要放入两种排序方式:

一个是自然排序:不允许插入null元素。需要对队列元素进行排序。要实现comparable接口,

一种是定制排序:

ArrayDeque实现类(双端队列):与ArrayList类似,底层都是实现一个动态的数组形式保存。

public class ArrayDequeTest {
    public static void main(String[] args) {
        ArrayDeque stack =new ArrayDeque();
        stack.push("try1");
        stack.push("try2");
        stack.push("try3");

        System.out.println(stack); // [try3, try2, try1]
        System.out.println(stack.peek());   //  try3
        System.out.println(stack);     // [try3, try2, try1]
        System.out.println(stack.pop());  // try3
        System.out.println(stack);  // [try2, try1]
    }
}

LinkedList是List接口的实现类,实现了Deque接口,可以当成一个双端队列来使用。是一个链表。

LinkedList 在随机访问的时候性能较差,但是插入与删除的 时候性能较好,只要改变一下指针地址的位置。

ArrayList与ArrayDeque的是以数组的形式存放的。

各个线性表的性能分析:

Java提供的List是一个线性表接口,而ArrayList、LinkedList又是线性表的典型实现。Deque代表了队列,双端队列,既可以作为队列使用,也可以作为栈使用。

性能比较:

public class PerformanceTest {
    public static void main(String args[]){
        String[] str1=new String[900000];
        for (int i=0;i<90000;i++){
            str1[i]=String.valueOf(i);
        }
        ArrayList al = new ArrayList();
        for (int i=0;i<90000;i++){
            al.add(str1[i]);
        }

        LinkedList l1 =new LinkedList();
        for (int i=0;i<90000;i++){
            l1.add(str1[i]);
        }

        long start=System.currentTimeMillis();
        for (Iterator it =al.iterator();it.hasNext();){
            it.next();
        }
        System.out.println(System.currentTimeMillis()-start);

        start=System.currentTimeMillis();
        for (Iterator it =l1.iterator();it.hasNext();){
            it.next();
        }
        System.out.println(System.currentTimeMillis()-start);
    }
}

比较会发现,ArrayList 与LinkList在时间上略大。

  1. 需遍历List集合元素时,可采用迭代器来遍历全部元素。ArrayList与Vector集合,适用随机访问。
  2. 经常的要使用插入与删除操作时,使用LinkList。因为ArrayList与Vector是数组分配,性能开销较大。
  3. 如果考虑到List被多个线程访问不安全,则可以考虑将Collections集合包装秤线程安全的集合。

参考资料:

《疯狂Java讲义》


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值