Java基础--容器集合

1:Java 容器有那些 ?

Java 容器分为Collection 和 Map 两大类 ,其下又有很多子类,如下所示 :

  • Collection----接口
    • List----接口
      • ArrayList
      • LinkedList
      • Vector
    • Set----接口
      • HashSet----底层实现为HashMap
      • LinkedHashSet
  • Map----接口
    • HashMap
      • LinkedHashMap----继承HashMap
    • TreeMap
    • ConcurrentHashMap
    • Hashtable

2:Collection 和 Collections有什么区别 ?

  • Collection 是一个集合接口,它提供了对集合对象进行基本操作的通用接口方法,所有集合都是它的子类,比如 List、Set 等
  • Collections 是一个包装类,包含了很多静态方法,不能被实例化,就像一个工具类,比如提供的排序方法:Collections. sort(list)

3:List,Set,Map 之间的区别是什么 ?

  • 主要区别在于两个方面 : 元素是否排序,是否允许元素重复
    • 排序: List 不排序 ; HashSet 可排序; HashMap 可排序(按照 key 排序)
    • 元素重复: List 不去重 ; HashSet 去重; HashMap 去重(key 不能重复),value 可重复。
  • 总结: List 即不排序,也不去重 ; HashSet ,HashMap,即去重也排序,只不过 HashMap 是针对 key 值来说的
  • 代码如下
/**
     * 测试 是否排序
     * <p>
     * 运行结果:
     * ArrayList = [a, c, b]
     * HashSet = [a, b, c]
     * HashMap = {a=1, b=2, c=3}
     */
    void show1() {
        System.out.println("-------------------测试是否排序---------------------");
        List arrayList = new ArrayList();
        Set hashSet = new HashSet();
        Map hashMap = new HashMap();
        arrayList.add("a");
        arrayList.add("c");
        arrayList.add("b");
        System.out.println("ArrayList = " + arrayList);
        hashSet.add("a");
        hashSet.add("c");
        hashSet.add("b");
        System.out.println("HashSet = " + hashSet);
        hashMap.put("a", "1");
        hashMap.put("c", "3");
        hashMap.put("b", "2");
        System.out.println("HashMap = " + hashMap);
    }

4:HashMap 和 HashTable 区别 ?

  • 从代码架构上说:

    • HashMap继承自 AbstractMap 。
    • 而 HashTable继承自Dictionary类。
    • 不过都实现了 Map,Cloneable(可复制),Serializable(可序列化) 这三个接口。
  • 从功能方面说:

    • HashMap 中的 key-value 支持 key-value , null-null , key-null, null-value 四种形式。
    • 而HashTable 只支持 key-value 这一种形式。
    • 总结: 当判断HashMap 中某个key是否存在时,不能使用 get()
      方法取判断,因为当你的key=null时,返回的也是null,所以应该使用containsKey() 方法去判断。
  • 从线程安全说:

    • HashMap : 非线程安全(没有被synchronized) 。
    • HashTable : 线程安全(方法几乎被synchronized修饰)
    • 但是如果需要HashMap 是线程安全是怎么处理呢?
      • 可以使用 Collections.synchronizedMap(Map)
      • 也可以使用ConcurrentHashMap,它比HashTable 效率高好多倍,因为该类使用的是分段锁,并不对整个数据进行锁定。
  • 从容量初始化说:

    • HashMap 默认初始化 = 16 ,之后每次扩容为原来的 2 倍 。
    • HashTable 默认初始化 = 11 ,之后每次扩容为原来的 2n+1。
    • 计算hash值不一样:
      • HashMap : 为了得到元素的位置,首先需要根据元素的key计算出一个 hash 值,然后再用这个 hash 值来计算得到最终位置。
      • HashTable: 直接使用对象的 hashCode,hashCode 是 JDK 根据对象的地址或者字符串或者数字计算出来的 int 类型的数值,然后再使用保留余数获取最终的位置。
  • 总结: 对于HashMap 和 HashTable 的使用,应尽量使用HashMap,因为无论是否需要线程安全(需要线程安全时可以使用上面两种方式保持),HashMap都要 比 HashTable 效率高。

5:HashMap ,HashTable,TreeMap ,ConcurrentHashMap 各自特点 ?

  • 相同点:都是 Map 接口的实现类 ; 因此都 有 put(key,value),get(key) 的操作
  • 不同点:
    • HashMap :
      • 支持 key-value , null-null , key-null, null-value 四种形式。
      • 线程不安全。
      • 默认初始容量为16(1<<4)扩容方式为原来的2倍 。
      • 底层数据结构 : jdk1.8(数组 + 链表,当链表长度超过8时,链表转换为红黑树) 。
    • ConcurrentHashMap:
      • 只支持 key-value ((key == null || value == null) , 将抛出NullPinterException)
      • 线程安全 (分段锁)
      • 数组+链表+红黑树
    • HashTable:
      • 只支持 key-value
      • 线程安全
      • 数组+链表
    • TreeMap:
      • 只支持key-value 形式
      • 线程非安全
      • 红黑二叉树

6:HashSet 底层实现原理 ?

  • HashSet 是基于 HashMap 实现的,HashSet 底层使用 HashMap 来保存所有元素,因此 HashSet 的实现比较简单,相关 HashSet 的操作,基本上都是直接调用底层 HashMap 的相关方法来完成,HashSet 不允许重复的值。
  • 总结: HashSet 实现了Set相关接口,但是底层使用的HashMap来做事的,所以才会带个hash的名字。

7:ArrayList 和 LinkedList 的区别是什么 ?

  • 数据结构: ArrayList : 动态数组;LinkedList : 双向链表。
  • 总结:因此在频繁读取数据时用ArrayList; 在写数据时用LinkedList。

8:如何实现数组和 List 之间的转换?

  • 数组转 List:使用 Arrays. asList(array) 进行转换。
  • List 转数组:使用 List 自带的 toArray() 方法。

9:ArrayList 和 Vector 的区别是什么?

  • ArrayList
    • 线程安全:非线程安全
    • 性能:> Vector
    • 扩容:根据实际的需要动态的调整容量,增加 50%。
  • Vector
    • 线程安全:线程安全
    • 性能:< ArrayList
    • 扩容:根据实际的需要动态的调整容量,Vector 扩容每次会增加 1 倍。

10:在 Queue 中 poll()和 remove()有什么区别?

  • 相同点:都是返回第一个元素,并在队列中删除返回的对象。
  • 不同点:如果没有元素 remove()会直接抛出NoSuchElementException 异常,而 poll()会返回 null。
  • 代码示例:
Queue<String> queue = new LinkedList<String>();
queue. offer("string"); // add
System. out. println(queue. poll());
System. out. println(queue. remove());
System. out. println(queue. size());

11:那些集合类是线程安全的?那些是不安全的?

  • 线程安全:
    • List
      • Vector
    • Map
      • Hashtable
      • ConcurrentHashMap
    • Stack
  • 非线程安全:
    • List
      • ArrayList
      • LinkedList
    • Set
      • HashSet
      • LinedHashSet
    • Map
      • HashMap
      • TreeMap

12:迭代器 Iterator 是什么,使用,以及特点?

  • Iterator 接口提供遍历任何 Collection 的接口。我们可以从一个 Collection 中使用迭代器方法来获取迭代器实例。迭代器取代了 Java 集合框架中的 Enumeration,迭代器允许调用者在迭代过程中移除元素。
  • 特点:Iterator 的特点是更加安全,因为它可以确保,在当前遍历的集合元素被更改的时候,就会抛出 ConcurrentModificationException 异常。
  • 使用
/**
     * @return void
     * @Author ZQ
     * @Description 输出:
     * 张三
     * 李四
     * 王五
     * <p>
     * 特点:在两个线程同时操作该list的时可以保证线程安全
     * @Date 2020/2/6 13:46
     * @Param [args]
     **/
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add("张三");
        list.add("李四");
        list.add("王五");
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            String name = iterator.next();
            System.out.println(name);
        }
    }

13:怎么确保一个集合不能被修改?

  • 可以使用 Collections. unmodifiableCollection(Collection c) 方法来创建一个只读集合,这样改变集合的任何操作都会抛出 Java. lang. UnsupportedOperationException 异常。
  • 代码如下:
/**
     * @return void
     * @Author ZQ
     * @Description 报错信息: UnsupportedOperationException
     * @Date 2020/2/6 13:54
     * @Param [args]
     **/
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("xfj");
        Collection<String> clist = Collections.unmodifiableCollection(list);
        clist.add("zq");//运行到这报错,因为已经加载成不可被修改了,可以使用clist集合来进行只读的操作。
        System.out.println(list.size());
    }

14:代码地址

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值