首页 > 技术文章 > JAVA 集合总结

xiongyungang 2020-02-20 02:34 原文

ArrayList

  • 默认长度10
  • 底层数组实现
  • 查询快(下标获取),增删慢(移动元素),线程不安全
  • 有扩容机制(当元素个数达到容量,自动扩展n倍,容量可指定)
        ArrayList<Integer> list = new ArrayList<>();
        list.add(null);
        System.out.println(list.isEmpty());// false 添加null后,集合非空

迭代器

  • Iterator list.iterator() 返回当前集合的迭代器对象
  • Iterator.hasNext() 判断有无元素
  • Iterator.next()返回当前元素,索引后移
  • 异常ConcurrentModificationException,迭代中不能操作原集合对象
		ArrayList<Object> arrayTest = new ArrayList<>();
		arrayTest.add("123");
		arrayTest.add(567);
		arrayTest.add(false);
		arrayTest.add(new Date());
		for (Iterator<Object> iterator2 = arrayTest.iterator();    //  返回当前集合的迭代器对象
                    iterator2.hasNext();)  //  判断有无元素
		{
                        //arrayTest.add("123");  //【ConcurrentMod    ficationException】迭代中不能操作原集合对象
			System.out.println(iterator2.next());    //  返回当前元素,索引后移
		}

LinkedList

  • 查询慢(链表查询),增删快(百万级数据ArrayList速度优于LinkedList,ArrayList有扩容机制)
  • 双向循环链表。它也可以被当作堆栈、队列或双端队列进行操作。
  • LinkedList 实现 List 接口,能对它进行队列操作。
  • LinkedList 实现 Deque 接口,即能将LinkedList当作双端队列使用。
  • LinkedList 实现了Cloneable接口,即覆盖了函数clone(),能克隆。
  • LinkedList 实现java.io.Serializable接口,这意味着LinkedList支持序列化,能通过序列化去传输。
  • LinkedList 是非同步的,线程不安全。
		LinkedList<String> linklist = new LinkedList<>();

		// 增加
		linklist.add("hello");
		linklist.addLast("world");//同add(),底层调用同一个方法
		linklist.addFirst("java,");//头部添加,可以利用此方法实现先进后出
		
		//  获取
		get(1)://按照下标获取元素
		linklist.getFirst(); //获取首元素
		linklist.getLast();  //获取尾元素

		//  删除
		remove();//移除链表中第一个元素
		removeFirst()://移除链表中第一个元素,与remove类似; 
		removeLast()://移除链表中最后一个元素; 
		removeFirstOccurrence("hello")://移除链表中第一次出现所在位置的元素

		// push、pop、poll
		linkedList.push("four"); //同add()
		linkedList.push("five");
		linkedList.pop();    // 删除第一个元素,如果集合为空返回null
		linkedList.poll();    // 删除第一个元素,如果集合为空抛出NoSuchElementException

HashSet

  • 底层是一个hashMap
  • 判断重复:hashCode() + equals()
  • 实现Set Interface,不允许重复值
  • 元素无序,对象基于其哈希码插入。
  • 允许使用NULL元素。
  • 实现了Searlizable和Cloneable接口
		hashSet.add(null);
		System.out.println("hashSet = " + hashSet.isEmpty()); // false

		hashSet.add("hello");
		hashSet.add("world");
		hashSet.add("!");

		//  支持迭代器和加强for遍历
		for (Object e :
				hashSet) {
			System.out.println("e = " + e);
		}

		Iterator<String> iterator = hashSet.iterator();
		while (iterator.hasNext())
		{
			String next = iterator.next();
			System.out.println("next = " + next);
		}
  • HashSet底层是HashMap实现,add操作时put元素和常量PERSENT
    // jdk1.8
    private static final Object PRESENT = new Object();
    ...
    public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }

TreeSet

  • TreeSet:能够对元素按照某种规律进行排序,comparator
  • 不能有重复的元素
  • 元素必须实现Comparable接口并重写compareTo()方法,该接口同时保证对象的排序和唯一
  • 底层实现TreeMap
		TreeSet<TestNoCompa> employees = new TreeSet<>();
		//employees.add(new TestNoCompa());  //对象未实现Comparator接口,java.lang.ClassCastException
  • 具有排序功能,排序方式:
  • A:自然排序,让元素所属的类实现自然排序comparable接口
  • B:比较器排序:让集合的构造方法接收一个比较器接口的子类对象Comparator
		//使用无参构造,默认自然排序
		//TreeSet<Integer> treeSet = new TreeSet<Integer>();

		//比较器排序,构造传入比较器对象
		TreeSet<Integer> treeSetDemo = new TreeSet<Integer>(new MyComparator());
		treeSetDemo.add(3);
		treeSetDemo.add(4);
		treeSetDemo.add(2);
		treeSetDemo.add(1);
		System.out.println("treeSetDemo = " + treeSetDemo); // treeSetDemo = [1, 2, 3, 4]

		//比较器排序,使用比较器对象,匿名内部内方式
		TreeSet<Integer> treeSet = new TreeSet<Integer>(new Comparator<Integer>() {

			@Override
			public int compare(Integer o1, Integer o2) {
				return o2-o1;
			}
		});
		treeSet.add(5);
		treeSet.add(2);
		treeSet.add(3);
		treeSet.add(4);
		treeSet.add(1);
		treeSet.add(5);
		System.out.println("treeSet = " + treeSet);  //  treeSet = [5, 4, 3, 2, 1]

HashMap

https://www.jianshu.com/p/ee0de4c99f87

  • HashMap由底层是数组+链表+红黑树,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的,链表长度大于8时用红黑树
  • 扩容机制: 当put操作时,判断当前元素是否达到阈值(默认16),扩容时将重新计算容量并添加到新的容器中
  • 线程不安全,因为多线程put时会导致数据不一致
  • 元素无序
        HashMap<Integer, String> integerStringHashMap = new HashMap<>();

        //  增加
        integerStringHashMap.put(1, "hello");
        integerStringHashMap.put(2, "world");
        integerStringHashMap.put(3, "!");

        //  删除
        integerStringHashMap.remove(3);

        // 替换
        integerStringHashMap.replace(2, "world!");//  底层调用put替换

        //  遍历
        //  使用Map.Entry键值对 对象遍历
        for (Map.Entry<Integer, String> entry :
                integerStringHashMap.entrySet()) {
            System.out.println("key = " + entry.getKey() + ", value = "+ entry.getValue());
        }

TreeMap

  • 元素默认按照keys的自然排序排列
  • 原始比较强key不可以为null
  • TreeMap为有序的KV集合,key必须实现Comparable接口(排序、去重)
  • TreeMap非同步线程不安全,内部实现红黑树
  TreeMap<Integer, String> integerStringTreeMap2 = new TreeMap<>();  // 默认构造,自然排序
        TreeMap<Integer, String> integerStringTreeMap = new TreeMap<>(Comparator.reverseOrder());  //  比较器构造

        //  添加
        integerStringTreeMap.put(2, "world");
        integerStringTreeMap.put(1, "hello");
        integerStringTreeMap.put(3, "!");
        System.out.println("integerStringTreeMap = " + integerStringTreeMap);  //integerStringTreeMap = {3=!, 2=world, 1=hello}

        //  修改
        integerStringTreeMap.put(1, "Hello");
        integerStringTreeMap.replaceAll((s1, s2)->{// lambda,接受<K, V> 返回新V替换旧V
            if (s1 > 1){
                s2 = s2.substring(0, 1).toUpperCase() + s2.substring(1);
            }

            return s2;
        });
        System.out.println("integerStringTreeMap = " + integerStringTreeMap); // integerStringTreeMap = {3=!, 2=World, 1=Hello}
        
        //  遍历
        Set<Map.Entry<Integer, String>> entries = integerStringTreeMap.entrySet();
        for (Map.Entry entry:
                entries) {
            System.out.println("entry = " + entry.toString());
        }

        //integerStringTreeMap.put(null, "13");//NullPointerException:原始比较器key不可以为null

        //  删除
        integerStringTreeMap.remove(1);
        integerStringTreeMap.clear();  //删除全部

推荐阅读