Skip to content

十、集合

一、介绍

1、特点

  • 数组的大小是固定的,集合的大小则是可变的
  • 数组只能存放基本类型数据,也可以存放对象的引用,而集合存放的只能是对象的引用
  • 集合类框架提供2个接口——CollectionMap,它们都继承java.lang.Object
  • Collection类有ListSet两种继承接口
  • Map是一种键值对的存储形式

二、Collection

Collection是单列集合的祖宗接口,它的功能是全部单列集合都可以继承使用的

方法名称说明
public boolean add(E e)把给定的对象添加到当前集合中
public void clear()清空集合中所有的元素
public boolean remove(E e)把给定的对象在当前集合中删除
public boolean contains(Object obj)判断当前集合是否包含给定的对象
public boolean isEmpty(E e)判断当前集合是否为空
public size()返回集合中元素的个数/集合的长度

1、遍历方式

(1)增强for

格式

java
for(元素的数据类型 变量名:数组或者集合){
	
}

(2)迭代器

迭代器在Java中的类是Iterator,迭代器是集合专用的遍历方式

  • Collection集合获取迭代器
    方法名称说明
    Iterator<E> iterator返回迭代器对象,默认指向当前集合的0索引
    java
    Collection<String> coll = new ArrayList<>();
    Iterator<String> it = coll.iterator();
    
    while(it.hasNext()){
        String str = it.next();
    }
  • Iterator的常用方法
    方法名称说明
    boolean hasNext()判断当前位置是否有元素,有元素返回true,没用元素返回false
    E next()获取当前位置的元素,并将迭代器对象移向下一个位置

(3)lambda表达式

java
// Lambda 表达式没有参数
() -> System.out.println("Hello, Lambda!");

// Lambda 表达式有一个参数
(x) -> System.out.println("The number is: " + x);

// Lambda 表达式有多个参数
(x, y) -> {
    int sum = x + y;
    System.out.println("The sum is: " + sum);
};

1、List集合

  • 添加的元素是有序、可重复、有索引

  • 遍历方式

    1. 迭代器
    2. 列表迭代器
    3. 增强for循环
    4. lambda表达式
    5. 普通for循环

(1)ArrayList集合

方法名说明
boolean add(E e)添加元素,返回值表示是否添加成功
boolean remove(E e)删除指定元素,返回值表示是否删除成功
E remove(int index)删除指定索引的元素,返回被删除元素
E set(int index,E e)修改指定索引下的元素,返回原来的元素
E get(int index)获取指定索引的元素
int size()集合的长度,也就是集合中元素的个数

在 Java 中,你可以使用多种方式来初始化一个 ArrayList 集合

  1. 使用无参构造函数初始化:

    java
    ArrayList<String> list = new ArrayList<>();
  2. 使用包含初始容量的构造函数初始化:

    java
    ArrayList<String> list = new ArrayList<>(10); // 指定初始容量为10
  3. 使用 Arrays.asList() 初始化:

    java
    ArrayList<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));
  4. 使用集合的 add() 方法逐个添加元素初始化:

    java
    ArrayList<String> list = new ArrayList<>();
    list.add("a");
    list.add("b");
    list.add("c");
  5. 使用集合的 addAll() 方法添加另一个集合的元素初始化:

    java
    ArrayList<String> list1 = new ArrayList<>(Arrays.asList("a", "b", "c"));
    ArrayList<String> list2 = new ArrayList<>();
    list2.addAll(list1);
  6. Java 9 之后,使用 List.of() 初始化:

    java
    ArrayList<String> list = new ArrayList<>(List.of("a", "b", "c"));

(2)LinkedList集合未看完

https://blog.csdn.net/qq_39939541/article/details/131367198

2、Set集合

  • 添加的元素是无序、不重复、无索引

(1)实现类

  • HashSet:无序、不重复、无索引
  • LinkedHashSet:、不重复、无索引
  • TreeSet:、不重复、无索引

(2)创建Set对象

java
Set<String> s =new HashSet<>();

(3)遍历

  • 增强for
    java
    for(String s : s){
    	//处理
    }
  • Lambda表达式
    java
    s.forEach(str->System.out.println(str));

(4)HashSet

  • HashSet底层原理
    • 集合底层采取哈希表存储数据

    • 哈希表是一种对于增删改查数据性能比较好的结构

  • 哈希值
    • 哈希值:对象的整数表现形式
    • 根据hashCode方法算出来的int类型的整数
    • hashCode定义在Object类中,所有对象都可以调用,默认使用地址值进行计算
    • 一般情况下,会重写hashCode方法,利用对象内部的属性值计算哈希值
  • 对象的哈希值特点
    • 如果没有重写hashcode方法,不同对象计算出的哈希值是不同的
    • 如果已经重写hashcode方法,不同的对象只要属性值相同,计算出的哈希值就是一样的
    • 哈希碰撞:在小部分情况下,不同的属性值或者不同的地址值计算出来的哈希值也可能一样

(5)LinkedHashSet

  • 特点
    1. 有序、不重复、无索引
    2. 底层基于哈希表,使用双链表记录添加顺序

(6)TreeSet

  • 默认规则
    • 对于数值类型:Integer,Double,默认按照从小到大的顺序进行排序
    • 对于字符、字符串类型:按照字符ASCLL码表中的数字升序进行排序
  • 遍历
    • 迭代器
    • 增强for
    • lamdba表达式
  • 比较方式
    • 方式一

      • 默认排序/自然排序:javabean类实现Comparable接口指定比较规则
    • 方式二

      • 比较排序:创建TreeSet对象时候,传递比较器Comparator指定规则

        java
        TreeSet<String> ts = new TreeSet<>((o1,o2)->{
            int =o1.length() - o2.length();
            i = i==0 ? o1.compareTo(o2) :i;
            return i;
        })

三、Map

1、特点

  1. 双列集合一次需要存一对数据,分别为键和值
  2. 键不可以重复,值可以重复
  3. 键和值是一一对应的,每一个键只能找到自己对应的值
  4. 键+值这个整体称为“键值对”或者“键值对对象”,在Java中叫做“Entry对象”

2、常见API

方法名称说明
V put(K key,V value)添加元素
V remove(Object key)根据键删除键值对元素
void clear()移除所有的键值对元素
boolean containsKey(Object key)判断集合是否包含指定的键
boolean containsValue(Object value)判断集合是否包含指定的值
boolean isEmpty()判断集合是否为空
int size()集合的长度/集合中键值对个数

3、遍历方式

获取所有的键

java
Set<String> keys = map.keySet();

(1)增强for

遍历键,获取值

java
for(String key : keys){
	System.out.println(map.get(key));
}

(2)迭代器

java
Iterator<String> k = keys.iterator();

while(k.hasNext()){
    String key = k.next();
    System.out.println(map.get(key));
}

(3)lambda表达式

java
keys.forEach(key->{
	System.out.println(map.get(key));
})

(4)EntrySet

java
Set<Map.Entry<String,String>> entries = map.entrySet();

for(Map.Entry<String,String> entry : entries){
	String key = entry,getKey();
    String value = entry.getValue();
}

4、HashMap

(1)特点

  • HashMap是Map里面的一个实现类
  • 没有额外需要学习的特有方法,直接使用Map里面的方法就可以了
  • 特点都是由键决定的:无序、不重复、无索引
  • HashMap跟HashSet底层原理是一模一样的,都是哈希表结构

5、LinkedHashMap

(1)特点

  • 有序、不重复、无索引
  • 保证存储和取出的顺序一致
  • 底层数据结构依然是哈希表,只是每个键值对元素又额外的多了一个双链表的机制记录存储的顺序

6、TreeMap

  • TreeMap跟TreeSet底层原理一样,都是红黑树结构的
  • 由键决定特性:不重复、无索引、可排序
  • 可排序:对键进行排序
  • 注意:默认按照键的从小到大进行排序,也可以自己规定键的排序规则

(1)排序规则

  • 实现Comparable接口,指定比较规则
  • 创建集合时传递Comparator比较器对象,指定比较规则

(2)Comparator

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

(3)Comparable

实现接口

java
public class Student implements Comparable<Student>{
    @Override
    public int compareTo(Student o){
        int i = this.age - o.age;
        i==0 ? this.getName().compareTo(o.getName()) : i;
        return i;
    }
}

四、Collections工具

方法说明
sort(List<T> list)对列表进行升序排序。
sort(List<T> list, Comparator<T> c)使用自定义的比较器对列表进行排序。
reverse(List<?> list)反转列表中元素的顺序。
shuffle(List<?> list)随机打乱列表中元素的顺序。
binarySearch(List<? extends T> list, T key)在有序列表中使用二分查找算法查找指定元素的索引。
binarySearch(List<? extends T> list, T key, Comparator<? super T> c)使用自定义的比较器进行二分查找。
max(Collection<? extends T> coll)返回集合中的最大元素。
min(Collection<? extends T> coll)返回集合中的最小元素。
copy(List<? super T> dest, List<? extends T> src)将源列表中的元素复制到目标列表中。
fill(List<? super T> list, T obj)用指定元素填充列表。
replaceAll(List<T> list, T oldVal, T newVal)将列表中所有指定的旧元素替换为新元素。

五、不可变集合

只能进行查询操作

1、List

java
List<String> list = List.of("张三","李四","王五");

2、Set

java
Set<String> set = Set.of("张三","李四","王五");

3、Map

java
Map<String> map = Map.of("张三","李四","王五");

六、泛型

  • 统一数据类型
  • 把运行时期的问题提前到了编译期间,避免了强制类型转换可能出现的异常,因为在编译阶段类型就能确定下来

注意

  • 泛型中不能写基本数据类型
  • 指定泛型的具体类型后,传递数据时,可以传该类型或者其子类类型
  • 如果不写泛型,类型默认Object