集合相关

集合架构

集合的架构图

Collection(接口):

所有单例集合的父类Collection集合的功能所有单例集合都可以直接使用;

API:

  • public boolean add(E e): 把给定的对象添加到当前集合中 。
  • public void clear() :清空集合中所有的元素。
  • public boolean remove(E e): 把给定的对象在当前集合中删除。
  • public boolean contains(Object obj): 判断当前集合中是否包含给定的对象。
  • public boolean isEmpty(): 判断当前集合是否为空。
  • public int size(): 返回集合中元素的个数。
  • public Object[] toArray(): 把集合中的元素,存储到数组中

遍历方式:

1.迭代器

  • public Iterator iterator(): 获取集合对应的迭代器,用来遍历集合中的元素
  • E next():获取下一个元素值!
  • boolean hasNext():判断是否有下一个元素,有返回true ,反之false。
        Iterator<String> it = lists.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }

2.foreach:for(被遍历集合或者数组中元素的类型 变量名称 : 被遍历集合或者数组){}

        for(String s: lists){
            System.out.println(s);
        }

3.lambda表达式: lambda表达式是JKD1.8的新特性,主要是为了简化代码,简化代码如下:

 Collection<String> lists = new ArrayList<>();
    lists.add("五六七");
    lists.add("梅花十三");
    lists.add("鸡大宝");
    lists.add("小飞");
    lists.forEach(s -> {
        System.out.println(s);
    });

Set(接口):

特点:添加的元素是无序,不重复,无索引的。

HashSet:
  1. null值:可以存放null值
  2. 线程:线程不安全
  3. 底层:哈希表
    • 其他特定:无序,不重复,无索引
  4. HashSet的层使用的是HashMap
  5. JDK1.8以前,哈希表是由数组+链表构成,JDK1.8以后是由数组+链表+红黑树构成
  6. 当链表的大于8个以后,链表结构就会转成红黑树结构进行存储
  7. 哈希算法:
  8. 获取元素对象的哈希值
  9. 让当前对象的哈希值对都城数组长度取余(数组长度默认是16)
  10. 取余的结构作为该对线下元素在地城数组的索引位置
  11. 吧对象元素存入到该索引位置
    哈希算法底层代码
HashSet研究的两个问题:

1)Set集合添加的元素是不重复的,是如何去重复的?
对于基本数据类型和字符串,Set集合可以直接判断去重
对于引用数据类型,Set集合会按照如下顺序进行判断:

  1. 调用自己的hashCode方法获取哈希值进行比较,如果返回false直接认为两个对象不重复
  2. 如果哈希值相同,再调用equals方法比较,返回false表示不重复,true表示重复
    所以我们比较两个对象的内容是否相同需要重写hashCode方法和equals方法
    2)Set集合元素无序的原因是什么
    Set无序的根本原因就是底层使用了哈希表,通过哈希算法觉得存放的位置,所以是无需的。
LinkedHashSet:
  • null值:允许 null 元素 但最多只能加一个
  • 线程:不安全
  • 底层:哈希表,每个元素都带上一个链
  • 其他特点:有序,不重复,无索引
TreeSet:
  • null值:默认不允许null值,可以通过设置Comparator接口的实例,来实现元素允许为null值
  • 线程:不安全
  • 底层:红黑树
  • 其他特点:无序,不重复,无索引,但是可以自动排序
TreeSet的排序:
  • 对于有值特性的元素直接可以升序排序。(浮点型,整型)
  • 字符串类型的元素会按照首字符的编号排序。
  • 但是对于自定义的引用数据类型,TreeSet默认无法排序,执行的时候直接报错
  • 要对引用数据类型进行排序有如下两种方案
  1. 为对象实现比较器规则接口:Comparable,重写比较方法
public class Student implements Comparable<Student>{
    private String name;
    private int age;
    private String sex;

    /**
     * 如果程序员认为比较者大于被比较者 返回正数!
     * 如果程序员认为比较者小于被比较者 返回负数!
     * 如果程序员认为比较者等于被比较者 返回0!
     */
    @Override
    public int compareTo(Student o) {
        return this.age - o.age;
    }
    //构造方法和getter,setter,tostring方法省略
}    
  1. 直接为集合设置比较器Comparator对象,重写比较方法
    public static void main(String[] args) {
        TreeSet<Student> students = new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return o1.getAge() - o2.getAge();
            }
        });
        Collections.addAll(students,new Student("五六七",18,"男"),
                                                new Student("梅花十三",17,"女"),
                                                new Student("鸡大宝",20,"公"));
        System.out.println(students);
    }

List(接口):

特点:添加的元素是有序,可重复,有索引。

ArrayList:
  • null值:允许为null值
  • 线程:不安全
  • 底层:数组
  • 查询:快
  • 增删:慢
遍历方式
  • for循环:因为有索引所以多了个根据索引遍历的方式:
for(int i = 0 ; i < lists.size() ; i++ ) {
    String ele = lists.get(i);
    System.out.println(ele);
}
  • 迭代器:略
  • foreach:略
  • lambda表达式:略
LinkedList:
  • null值:允许为null值
  • 线程:不安全
  • 底层:链表
  • 查询:慢
  • 增删:快
遍历方式:同ArrayList(略)
LinkedList和ArrayList的区别

主要是底层实现不同:
ArrayList底层是数组,在内存中是一组连续的代码块,通过索引*单位长度(根据所传泛型觉得单位长度)来寻找元素,所以查询速度很快,但是增删元素就相对较慢;
LinkedList底层是双向链表,在内存中的位置是随机的,链表每个元素都记录了元素的值和下一个元素的地址,想要找到某个元素,只能通过头或者尾元素的地址值查找下一个元素,直到找到要找的元素。

Vector:(淘汰)
  • null值:允许为null值
  • 线程:安全
  • 底层:数组
  • 查询:快
  • 增删:慢
    Vector因为是线程安全的,性能较差,所以几乎淘汰不用了
遍历方式:同ArrayList(略)
总结:
  • 如果希望元素可以重复,又有索引,查询要快用ArrayList集合。
  • 如果希望元素可以重复,又有索引,增删要快要用LinkedList集合。(适合查询元素比较少,经常要首尾操作元素的情况)
  • 如果希望增删改查都很快,但是元素不重复以及无序无索引,那么用HashSet集合。
  • 如果希望增删改查都很快且有序,但是元素不重复以及无索引,那么用LinkedHashSet集合。

Map(接口):

Map接口是所有键值对集合的父类

Map集合的特点:

  1. Map集合的特点都是由键决定的。
  2. Map集合的键是无序,不重复的,无索引的。
    Map集合后面重复的键对应的元素会覆盖前面的整个元素!
  3. Map集合的值无要求。
  4. Map集合的键值对都可以为null。
  • HashMap、LinkedHashMap和TreeMap底层和HashSet、LinkedHashSet、TreeSet的底层是一样的
    HashSet底层
    TreeSet底层
    LinkedHashSet底层1
    super点进去
    LinkedHashSet底层2

HashMap:

  • null值:允许键值都为null值
  • 线程:不安全
  • 底层:哈希表
  • 其他特点:无序不重复
遍历方式:
  1. “键找值”的方式遍历:先获取Map集合全部的键,再根据遍历键找值。
    public static void main(String[] args) {
        Map<String,Integer> maps = new HashMap<>();
        maps.put("aaa",1);
        maps.put("bbb",2);
        maps.put("ccc",2);
        Set<String> keys = maps.keySet();
        for (String key : keys) {
            Integer value = maps.get(key);
            System.out.println(key + "=" + value);
        }
    }
  1. “键值对”的方式遍历:
    public static void main(String[] args) {
            Map<String,Integer> maps = new HashMap<>();
            maps.put("aaa",1);
            maps.put("bbb",2);
            maps.put("ccc",2);
        Set<Map.Entry<String, Integer>> entries = maps.entrySet();
        for (Map.Entry<String, Integer> entry : entries) {
            System.out.println(entry.getKey());
            System.out.println(entry.getValue());
        }
    }
  1. Lambda表达式。
    public static void main(String[] args) {
            Map<String,Integer> maps = new HashMap<>();
            maps.put("aaa",1);
            maps.put("bbb",2);
            maps.put("ccc",2);
            maps.forEach((k , v) -> System.out.println(k+"="+v));
        }
常用API:
  • public V put(K key, V value)`: 把指定的键与指定的值添加到Map集合中。
  • public V remove(Object key): 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值。
  • public V get(Object key) 根据指定的键,在Map集合中获取对应的值。
  • public Set<K> keySet(): 获取Map集合中所有的键,存储到Set集合中。
  • public Set<Map.Entry<K,V>> entrySet(): 获取到Map集合中所有的键值对对象的集合(Set集合)。
  • public boolean containKey(Object key):判断该集合中是否有此键。

LinkedHashMap:

  • null值:允许键值都为null值
  • 线程:安全
  • 底层:哈希表加上链表结构
  • 其他特点:有序不重复

HashTable:

  • null值:不允许为null值
  • 线程:安全,高并发竞争越激烈性能越差
  • 底层:红黑树
  • 其他特点:无序不重复

TreeMap:

  • null值:都允许
  • 线程:不安全
  • 底层:红黑树
  • 其他特点:无序不重复

IdentityHashMap:

  • null值:都允许
  • 线程:不安全
  • 底层:Hash表来实现Map接口
  • 其他特点:无序不重复

ConcurrentHashMap:

  • null值:不允许为null值
  • 线程:安全,使用分段锁,性能得到优化,高并发下建议使用
  • 底层:数组+链表+红黑树
  • 其他特点:无序不重复
    concurrentHashMap底层对哈希表加锁是只加其中一个桶,所以不影响其他桶进行读写等操作,综合性能高,而HashTable是对一整个哈希表加锁,所以综合性能比较差,已经淘汰了
    HashTable底层加锁

Properties:

  • null值:同Hashtable
  • 线程:安全
  • 底层:同Hashtable
  • 其他特点:无序不重复,集合里只能存字符串类型,是唯一一个与IO流结合的集合
    Properties底层是继承了HashTable,这个集合主要是用于读写属性文件,在各框架底层中大量使用。

集合工具类

Collections工具类:

  • public static boolean addAll(Collection<? super T> c, T… elements)
    给集合对象批量添加元素!
  • public static void shuffle(List<?> list) :打乱集合顺序。
  • public static void sort(List list):将集合中元素按照默认规则排序。
  • public static void sort(List list,Comparator<? super T> ):将集合中元素按照指定规则排序。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值