集合总结以及集合中泛型的使用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ilikejj0/article/details/82691666

Iterator

所有的集合类,都实现了Iterator接口,这是一个用于遍历集合中元素的接口,主要包含以下三种方法:
1.hasNext()是否还有下一个元素。
2.next()返回下一个元素。
3.remove()删除当前元素。

集合和数组的区别

1、数组可以存储基本数据类型或者引用数据类型,集合只能存储引用数据类型,如果存储基本数据类型,会自动转换为包装类型
2、数组在定义的时候,就会确定存储的数据类型,即只能存储一种数据类型,集合中如果没有泛型限制,默认存储的都是Object类型。
3、数组的长度是固定不变的,不能够进行自动增长,而集合是可以根据数据的多少进行自动增长。

List

List下面的三个子集合的区别
Vector 底层数据结构是数组 查询快 增删慢 线程安全 效率低 默认长度是10 超过就会100%延长 变成20 浪费空间
ArrayList 底层数据结构是数组 查询快 增删慢 线程不安全 效率高
默认长度是10 超过就会new一个新的数组 50%延长 节省空间
LinkedList 底层数据结构是链表(双向链表) 查询慢 增删快 线程不安全 效率高

LinkedList主要是用于查询少,但是增删多的情况下,ArrayList则相反。

List的遍历

1)Iterator:迭代输出,是使用最多的输出方式。

Iterator it = arr.iterator();
while(it.hasNext()){ object o =it.next(); ...}

2)ListIterator:是Iterator的子接口,专门用于输出List中的内容。可以在迭代时对里面的元素操作,如果没有使用这个接口去遍历,对元素进行操作,会出现并发修改异常ConcurrentModificationException。
详细讲解

3)foreach输出:JDK1.5之后提供的新功能,可以输出数组或集合。

4)for循环

Set

HashSet底层是哈希表,即是一个hashMap的实例,在HashSet中,元素都存到HashMap键值对的Key上面,而Value时有一个统一的值private static final Object PRESENT = new Object();,
按照哈希算法来存取集合中的对象 存取速度比较快
当程序向HashSet中 add()的一个对象的时候, 先用hashCode方法计算出该对象的哈希码 哈希码不一致 添加 哈希码一致 不添加 相同对象不添加 然后用equals判断对象的属性是否一致 比较结果为false就添加 true就不添加

对于基本数据类型包装类/String 已经重写了hashCode 和 equals 会自动比较
自定义实现类要重写其hashCode和equals方法,规定自定义类的比较规则来排重.

LinkedHashSet 特点: 是set中唯一一个能保证存取一致的集合对象。底层是双向链表,LinkedHashSet是继承自HashSet,底层实现是LinkedHashMap。
TreeSet 二叉树 实现了SortedSet接口 能够对集合中对象进行排序,自然排序 根据ASCII表大小排序,默认是升序。只能存储同一种类型的才能进行排序,不然会出现转换异常。 TreeSet的底层实现是TreeMap
对于自定义类的排序,实现 Comparable 接口 重写 comparaTo方法。或者使用 Comparator比较器。

Set子集合的三者区别

①.需要速度快的集合,使用HashSet

②.需要集合有排序功能,使用TreeSet

③.需要按照插入的顺序存储集合,使用LinkedHashSet

Set不可重复String和其他对象的对比

详细介绍

Map

Map集合的数据结构是针对键有效的 跟值无关
map的键如果是自定义类,也需要重写hashCode和equals方法。

1.HashTable 底层是哈希表 不可以存入null键null值 线程同步的 效率低
2.HashMap 底层是哈希表 可以存入null键null值(但也是只有一条key为null的记录) 线程不同步的 效率高
3.TreeMap 底层是二叉树 线程不同步的 可以用于给Map集合中的键进行排序 和Set很像 其实 Set底层就是用了Map集合
4.LinkedHashMap保存了记录的插入顺序,在用Iteraor遍历LinkedHashMap时,先得到的记录肯定是先插入的,在遍历的时候会比HashMap慢,有HashMap的全部特性。

Map的遍历:4种方式

public static void main(String[] args) {
        Map<String,String> map = new HashMap<String,String>();
        map.put("林俊杰", "不为谁而作的歌");
        map.put("胡夏", "知足");
        map.put("田馥甄", "你就不要想起我");

        //第一种方法KeySet集合迭代
        Set<String> keySet = map.keySet();
        Iterator<String> it = keySet.iterator();
        while(it.hasNext()){
            String key = it.next();
            String value =map.get(key);
            System.out.println(key+"--"+value);
        }
        //第二种方法EntrySet集合迭代
        Set<Map.Entry<String,String>> entrySet = map.entrySet();
        Iterator<Map.Entry<String,String>> en = entrySet.iterator();
        while(en.hasNext()){
            Entry<String, String> map1 = en.next();
            String key1 = map1.getKey();
            String value1 = map1.getValue();
            System.out.println(key1+"--"+value1);
        }
        //第三种方法,KeySet集合增强for循环
        Set<String> keySet1 = map.keySet();
        for(String key2 :keySet1){
            System.out.println(key2+"--"+map.get(key2));
        }
        //第四种方法,EntrySet集合增强for循环
        Set<Map.Entry<String, String>> entrySet2 = map.entrySet();
        for(Entry<String, String> key3 :entrySet2){
            System.out.println(key3.getKey()+"--"+key3.getValue());
        }

    }

集合中使用泛型的优点:

Java1.5引入了泛型,所有的集合接口和实现都大量地使用它。
泛型允许我们为集合提供一个可以容纳的对象类型,因此,如果你添加其它类型的任何元素,它会在编译时报错。这避免了在运行时出现ClassCastException。泛型也使得代码整洁,我们不需要使用显式转换和instanceOf操作符。
它也给运行时带来好处,因为不会产生类型检查的字节码指令。

①数组转list,可以使用Arrays.asList(数组)

②List转数组,使用list.toArray()

猜你喜欢

转载自blog.csdn.net/ilikejj0/article/details/82691666