JAVA 集合

Posted 赵杰A-124

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA 集合相关的知识,希望对你有一定的参考价值。

2016年3月换工作,面试图灵机器人的过程中被问到HashMap, Hashtable 和 TreeMap的区别,居然被问住了,虽然工作四年了,在解决具体问题时貌似还没遇到过翻不过去的坑。但是最近的面试也深刻的认识到基础知识该忘的忘,该不知道的不知道,究其原因,都是之前懒得或不屑总结。

就这个问题本身,回来学习后回答如下:

从两个方面分析

一,是否可以使用null,作为key或者value

HashMap,可以使用null值作为key或者value,当null作为key时,由于HashMap的key,不可重复,所以最多可以存入一个key为null的Entry。而当null作为value时,可以有多个value为null的Entry。

Hashtable,不可以将null值作为key或value,当向Hashtable中放入null值时,会报NullPointExecption。

以上两种,在内部实现时,均依靠key值使用Hash原理进行元素存储。他们均是Map接口的典型实现类。

TreeMap,是SortedMap接口的实现类,而SortedMap继承自Map接口。TreeMap内部维护以Key为排序依据的红黑树数据结构,当null作为key时,会NullPointException,但是当null用作value时可以有多个value为null的Entry。

验证代码如下:

import java.util.HashMap;
import java.util.Hashtable;
import java.util.TreeMap;

public class MapNullTest {

    public static void main(String[] args) {
        //1. HashMap null test
        HashMap<String, String> hashMap = new HashMap<>();
        hashMap.put(null, null);
        hashMap.put(null, null);
        hashMap.put("a", null);
        hashMap.put("b", null);
        System.out.println("hashMap: " + hashMap);
        
        //2. HashTable null test
        Hashtable<String, String> hashTable = new Hashtable();
        try {
            hashTable.put(null, "a");    
        } catch (NullPointerException e) {
            System.out.println("hashTable put (null, a) NullPointerException");
        }
        
        try {
            hashTable.put("a", null);
        } catch (Exception e) {
            System.out.println("hashTable put (a, null) NullPointerException");
        }
        System.out.println("hashTable: " + hashTable);
        
        //3. TreeMap null test
        TreeMap<String, String> treeMap = new TreeMap<>();
        try {
            treeMap.put(null, "a");    
        } catch (NullPointerException e) {
            System.out.println("treeMap put (null, a) NullPointException");
        }
        
        treeMap.put("a", null);
        treeMap.put("b", null);
        System.out.println("treeMap: " + treeMap);
    }

}

执行结果如下:

hashMap: {null=null, a=null, b=null}
hashTable put (null, a) NullPointerException
hashTable put (a, null) NullPointerException
hashTable: {}
treeMap put (null, a) NullPointException
treeMap: {a=null, b=null}

二、是否是线程安全的

HashMap 和 TreeMap均不是线程安全的,如需要线程安全时,可使用Collections的synchronizedXxx()方法获取到对应的线程安全对象。

Hashtable 是线程安全的。

 

Java 集合总结

java 集合类主要由两个接口派生而出,Collection 和 Map接口。

一、Collection 族 

其子接口有,Set,Queue和List接口。

1、Set 无序集合,集合中元素不可重复,常用Set类。

HashSet 元素的排列无序,不是线程同步的,集合中的元素可以为null,但是只可以有一个,其中的元素,因为不可以重复,所以需要判断两个对象是否相等,判断标准为两个对象通过equals()判断为true,且hashCode()方法返回值也相等。LinkedHashSet是其子类,它依然是一个HashSet,但内部使用链表记录了元素的添加顺序,所以其中元素的顺序与添加顺序是一致的。

TreeSet 内部使用红黑树来存储集合元素,加入TreeSet中的元素需要实现Comparable接口,因为TreeSet需要调用compareTo方法对元素进行比较从而排序,所以TreeSet中的元素顺序,不是插入顺序,而是compareTo的比较顺序。TreeSet判断两个对象是否相等的唯一标准就是compareTo返回值是否为0。若内部元素未实现Comparable接口,则需要在创建TreeSet对象时为其指名排序规则,以一个Comparator对象与集合关联,以指名排序规则。

EnumSet 专门为Enum对象设计的Set。

2、List 代表一个有序可重复的集合,且每一个元素都有对应的索引。

ArrayList 典型的List 实现类。

3、Queue 模拟队列的数据结构

PriorityQueue 标准的对列实现类,不过其队列中元素的排序并非按照入队顺序排列,而是依照元素实现的Comparable接口或者与集合绑定的Comparator对象定义的标准进行排列的,在出队时按照元素的排列顺序进行出队。

Deque 是Queue的子接口。

ArrayDeque是 Deque的典型实现类,实现双向队列,也可用作Stack来使用。

LinkedList 实现了List接口同时也实现了Deque接口,所以它是一个功能强大的结合,即可作为List使用,也可作为双向队列或栈来使用。

二、Map族

参照面试问题的回答,另外就是有几个重要的实现类:

WeakHashMap,保留对Key所引用对象的弱引用,可在key所引用的对象没有其它引用时,自动删除该key-value,以保证该元素的释放。

Properties,封装了对属性文件的读写,可以方便的将key-value的属性文件读入Properties对象中,也可方便的将Properties对象方便的存入属性文件中。

以上是关于JAVA 集合的主要内容,如果未能解决你的问题,请参考以下文章

201621123062《java程序设计》第九周作业总结

Java方法

金蝶handler中 collection 代码片段理解

Alfred常见使用

比较 C# 中的字符串片段并从集合中删除项目

带有红宝石集合/可枚举的酷技巧和富有表现力的片段[关闭]