【Java笔记-集合】

在这里插入图片描述

单列集合Collection

Collection是单列集合的顶层接口,所有方法被List和Set系列集合共享
List:添加元素是有序的、可重复、有索引
Set:添加元素是无序的、不重复、无索引

  • 常见成员方法:
    add clear remove contains isEmpty size
  • 三种通用的遍历方式
    • 迭代器:在遍历的过程中需要删除元素时使用
    • 增强for
    • Lambda: 仅仅想遍历,使用后两种
  • Collection迭代器遍历:
    1. 迭代器在遍历集合的时候不依赖索引

    2. 迭代器需要掌握三个方法
      在这里插入图片描述

    3. 迭代器的四个细节:

      • 如果当前位置没有元素,还要强行获取,会报NoSuchElementException
      • 迭代器遍历完毕,指针不会复位
      • 循环中只能用一次next方法
      • 迭代器遍历时,不能用结合的方法进行增加或删除

List

  • List对象创建
    List是一个接口,需要通过实现子类创建对象。List中存放的类型只能是Object及其子类,所以不能存放int, 应该为Integer
List<Integer> list1 = new ArrayList<>();//然后通过add()添加元素
List<Integer> list2 = new LinkedList<>();
  • List方法
//增删改查
add(Object data);//末尾增加data
add(Object data, pos);//在位置pos增加data
remove(int pos);//删除指定位置的元素
remove(Object);//删除指定元素
set(Object, pos);//修改指定位置的元素
forEach();//for循环遍历
iterator();//迭代器遍历

Set

  • 无序、不重复、无索引
  • Set集合的方法基本上与Collection的API一致
  • Hash Set:无序、不重复、无索引
  • LinkedHashSet:有序、不重复、无索引
  • TreeSet:可排序、不重复、无索引

双列集合Map

Map是一个接口

  • 特点

    • 双列集合一次需要存一对数据,分别为键和值(例如商品和价格)
    • 键不能重复,值可以重复
    • 键和值是意义对应的,每个键只能找到自己对应的值
    • 键+值这个整体称为”键值对“或”键值对对象“,Java中叫做”Entry对象“
  • 方法

    1. 基本方法

      Map<K, V> m = new HashMap();//K、V为键值的类型
      //添加数据,若键已存在,会把原有的键值对覆盖,并返回被覆盖的值
      //若键不存在,返回null
      m.put(K key,V value);
      //删除指定键值对并返回该值
      m.remove(Object key);
      //清空
      void clear();
      //
      boolean containsKey(Object key);
      //
      boolean containsValue(Object Value);
      //
      boolean isEmpty();
      //
      int size();
      //输出
      System.out.println(m);
      
    2. entrySet();
      返回的是键值对对象

  • 遍历

    1. 用keySet()方法获取所有键,返回的是Set集合,再通过get(key)方法获得key对应的值。(键找值)

      //增强for遍历
      	Set<K> keys = map.keySet();
      	for(K key : keys){
      		V value = map.get(key);
      	}
      	//Lambda表达式遍历
      	keys.forEach(key -> System.out.println(key));
      	//迭代器遍历
      	Iterator<K> it = keys.iterator();
      	while(it.hasNext()){
           	System.out.println(it.next());
       	}
      
    2. entry对遍历

      Set<Map.Entry<K,V>> entries = map.entrySet();
      for(Map.Entry<K, V> entry : entries){
            K key = entry.getKey();
            V value = entry.getValue();
      }
      //
      entries.forEach(entry -> System.out.println(entry));
      //
      Iterator<Map.Entry<K, V>> it2 = entries.iterator();
      while(it2.hasNext()){
          System.out.println(it2.next());
      }
      
    3. map遍历(Lambda)
      方法:default void forEach(Biconsumer<? super K,? super V> action)

      System.out.println("Map遍历:");
      map.forEach(new BiConsumer<K, V>() {
          @Override
          public void accept(K key, V value) {
              System.out.println(key + "=" + value);
          }
      });
      System.out.println("Map遍历(+lambda表达式):");
      map.forEach(( key,  value) -> System.out.println(key + "=" + value));
      
      

HashMap

  • 特点

    1. HashMap是Map的一个实现类,没有额外需要学习的特有方法,直接用Map里的方法。
    2. 特点都是由键决定的:无序、不重复、无索引
    3. 和HashSet的底层原理一模一样,都是哈希表结构(数组加链表)
  • 底层原理
    添加元素时,根据元素的哈希值确定存入位置,
    若数组位置为null(该位置没有元素),则直接存入;
    若数组位置不为null,且键不重复,则挂在下面形成链表或红黑树(链表长度大于64时形成红黑树),如果链表的元素和添加元素的哈希值和键重复了(两个都判断是为了防止哈希碰撞),则修改最后链表已有元素的值,进行元素覆盖(而不是直接用添加元素直接替换已有元素)
    若存入的元素为基础类型(String也算),则直接拷贝;若不是基础类型,则存入地址,一律占8字节。

    若创建红黑树,不需要实现Compareable接口或传递比较器对象,因为默认用哈希值的大小来创建红黑树。

LinkedHashMap

  • 特点:
    1. 由键决定:有序、不重复、无索引,有序指的是保证存储和取出的元素顺序一致。
    2. 原理:底层数据结构是哈希表,只是每个键值对元素又额外多了一个双链表的机制记录存储的顺序。

Hashtable

Properties

TreeMap

  • 特点
    1. 底层原理:红黑树(和TreeSet一样),所以增删改查性能较好
    2. 由键决定:可排序、不重复、无索引
    3. 默认按照键的顺序,从小到大排序,也可以按自己规定的规则排序
      代码书写两种排序规则:1. 实现Comparable接口,指定比较规则(当key是自定义对象时,需要让类继承该接口,并重写compareTo方法,以此来指定比较规则);2. 创建集合时传递Comparator比较器对象,指定比较规则。若两种规则都写了,以第二种为准。
    4. HashMap不排序,效率比TreeMap更高。

以key从大到小的顺序排列:

TreeMap<Integer, String> tm = new TreeMap<>(new Comparator<Integer>() {
    @Override
    public int compare(Integer o1, Integer o2) {
        return o2- o1;
    }
});

Compareable接口,以学生的年龄递增为顺序,年龄相等则按照名字的顺序
(继承接口后有红色波浪线,选中并按alt+回车,选则implements methods,可以选择要重写的方法)

public class Student implements Comparable<Student>{
    private int age;
    private String name;
    //JavaBean省略
    @Override
    public int compareTo(Student o) {
        //o: 已经在红黑树中存在的元素
        //this: 新添加的元素
        int i = this.getAge() - o.getAge();
        i = i == 0 ? this.getName().compareTo(o.getName()) : i;
        //这一行的compareTo()是String的方法
        return i;
    }
}
  • 底层原理
    三种双链集合如何选择:
    默认:HashMap(效率最高,仅管最坏情况(所有元素都在一个数组位置形成了链表)时效率低,但这样的情况极少),操作复杂度O(1)
    保证存取有序:LinkedHashMap
    需要排序:TreeMap,操作复杂度O(logN)
  • API
    在这里插入图片描述

集合工具类Collections

常用API
在这里插入图片描述
调用方法时可以直接用类名调用:Collections.addAll();

其他

  • JDK5以后,方法的形参可以是可变参数,即形参的个数可以发生变化,格式:
    方法名(属性类型…形参名)
    注意:
    • 但可变参数在一个方法的形参中最多只能有一个
    • 可变参数要写在其他参数的后面,写在最后
    • 可变参数本质是一个数组
      例子:求和方法
public static int getSum(int...a){
        int sum = 0;
        for (int i = 0; i < a.length; i++) {
            sum += a[i];
        }
        return sum;
    }

不可变集合

集合一旦生成,无法删改,只能查询

  • 创建
    //List
    List<String> list = List.of("aa","bb","cc","dd");
    //Set: 元素不能重复
    Set<String> set = Set.of("aaa","bbb","ccc");
    //Map 最多只能添加10个键值对
    Map<String,String> map1 = Map.of("aaa","111","bbb","222","ccc","333");
    //Map.copyOf():直接传入Map集合,
    // 若已经是不可变集合则直接返回输入,若是可变集合则转换为不可变集合
    Map<String,String> hm = new HashMap<>();
    hm.put("aaa","111");
    hm.put("bbb","222");
    hm.put("ccc","333");
    Map<String,String> map2 = Map.copyOf(hm);
    

Map.of()最多只能传递10个键值对,因为它的输入形参不是可变参数,是10个键值对。因为形参最多只能有一个可变参数。如果要传递大于10个键值对,要用Map.ofEntries(),它的形参是可变参数,所以传递的是数组,要把entries转换为数组(使用entries.toArray()方法)。JDK10开始,可以直接使用Map.copyOf()将可变Map集合转换为不可变集合。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值