认识集合

  • 集合是一种容器,用来装数据的,类似于数组,但集合的大小可变,开发中常用
  • Collection代表单列集合,每个元素(数据)只包含一个值。
  • Map代表双列集合,每个元素包含两个值(键值对)。

集合体系结构

Collection集合特点

  • List系列集合:添加的元素是有序的、可重复、有索引。
    • ArrayList、LinkedList:有序的、可重复、有索引
  • Set系列集合:添加的元素是无序、不重复、无索引。
    • HashSet:无序、不重复、无索引
    • LinkedHashSet:有序、不重复、无索引
    • TreeSet:按照大小默认升序排序、不重复、无索引

Collection集合

常用功能

Collection是单列集合的祖宗,它规定的方法(功能)是全部单列集合会继承的,所以先学Collection的常用方法。

方法名 说明
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() 把集合中的元素存储到数组中

遍历方法

方法一:迭代器遍历
  • 迭代器是用来遍历集合的专用方式(数组没有迭代器),Java中迭代器的的代表是Iterator
Collection集合获取迭代器的方法
方法名称 说明
Iterator iterator() 返回集合中的迭代器对象,该迭代器对象默认指向当前集合的第一个元素
Iterator迭代器中的常用方法
方法名称 说明
boolean hasNext( ) 询问当前位置是否有元素存在,存在返回true
E next( ) 获取当前位置的元素,并同时将迭代器对象指向下一个元素处
Collection<String> names=new ArrayList<>();
//1、得到这个集合的迭代器对象
Iterator<String> it=names.iterator();
//2、使用一个while循环来遍历
while(it.hasNext()){
    String name=it.next();
    System.out.println(name);
}
方法二:增强for循环
  • 记住格式:

    for(元素的数据类型 变量名:数组或者集合){
        
    }
    
  • 增强for可以用来遍历集合或者数组。

  • 增强for遍历集合,本质就是迭代器遍历集合的简化写法

  • 缺点:只能访问里面的元素,不能对其中的元素进行修改

Collection<String> c=new ArrayList<>();
...
for(String s:c){
    System.out.println(s);
}
方法三:Lambda表达式
  • 得益于JDK8开始的新技术Lambda表达式,提供了一种更简单、更直接的方式来遍历集合。

需要使用Collection的如下方法来完成:

方法名称 说明
default void forEach(Consumer<? super T> action) 结合lambda遍历集合

并发修改异常问题

认识问题
  • 遍历集合的同时又存在增删集合元素的行为时,可能出现业务异常,这种现象被称之为并发修改异常问题。
解决问题
  • 1、如果集合支持索引,可以使用for循环遍历,每删除数据后做i--;或者可以倒着遍历
  • 2、可以使用迭代器遍历,并用迭代器提供的方法删除数据
  • 注意:增强for循环/Lambda遍历均不能解决并发修改异常问题,因此它们只适合做数据的遍历,不适合同时做增删操作。

List集合

List集合的特有方法

  • List集合因为支持索引,所以多了很多与索引相关的方法,当然,Collection的功能List也继承了
方法名称 说明
void add(int index,E element) 在此集合中的指定位置插入指定元素
E remove(int index) 删除指定索引处的元素,返回被删除的元素
E set(int index,E element) 修改指定索引处的元素,返回被修改的元素
E get(int index) 返回指定索引处的元素

List集合支持的遍历方式

  • 1、for循环(因为List集合有索引)
  • 2、迭代器
  • 3、增强for循环
  • 4、Lambda表达式

ArrayList的底层原理

  • ArrayList底层是基于数组存储数据的

  • LinkedList底层是基于双链表存储数据的(先增后删)

    • LinkedList新增了很多首尾操作的特有方法
    方法名称 说明
    public void addFirst(E e) 在该列表开头插入指定的元素
    public void addLast(E e) 将指定的元素追加到此列表的末尾
    public E getFirst() 返回此列表中的第一个元素
    public E getLast 返回此列表中的最后一个元素
    public E removeFirst() 从此列表删除并返回第一个元素
    public E removeLast() 从此列表中删除并返回最后一个元素
    • 应用场景:1、用来设计队列;2、用来设计栈

Set集合

特点:

  • 无序:添加数据的顺序和获取出的数据顺序不一致;
  • 不重复
  • 无索引
    • HashSet:无序、不重复、无索引
    • LinkedHashSet:有序、不重复、无索引
    • TreeSet:按照大小默认升序排序、不重复、无索引

Set要用到的常用方法,基本上就是Collection提供的!!!

自己几乎没有额外新增一些常用功能!

HashSet集合去重复的机制

  • 如果希望Set集合认为两个内容一样的对象是重复的,必须重写对象的hashCode()和equals()方法

  • @Data会自动重写这两个方法

HashSet、LinkedHashSet 底层原理

  • 基于哈希表(数组、链表、红黑树)实现的

TreeSet集合

  • 特点:不重复、无索引、可排序(默认升序排序,按照元素的大小,由小到大排序)
  • 底层是基于红黑树实现的排序

注意:

  • 对于数值类型:Integer,Double,默认按照数值本身的大小进行升序排序。
  • 对于字符串类型:默认按照首字符的编号升序排序。
  • 对于自定义类型如Student对象,TreeSet默认是无法直接排序的。

Map集合

认识Map集合

  • Map集合也被叫做“键值对集合”,格式:{Key1=value1,key2=value2…}
  • Map集合的所有键是不允许重复的,但值可以重复,键和值是一一对应的,每一个键只能找到自己对应的值

Map集合体系的特点

注意:Map系列集合的特点都是有键决定的,值只是一个附属品,值是不做要求的

  • HashMap(由键决定特点):无序、不重复、无索引;(用的最多)
  • LinkedHashMap(由键决定特点):有序、不重复、无索引。
  • TreeMap(由键决定特点):按照大小默认升序排序(只对键排序)、不重复、无索引

Map集合的常用方法

方法名称 说明
public V put(K key,V value) 添加元素
public int size() 获取集合的大小
public void clear() 清空集合
public boolean isEmpty() 判断集合是否为空,为空返回true,反之
public V get(Object key) 跟据键获取对应值
public V remove(Object key) 跟据键删除整个元素
public boolean containsKey(Object key) 判断是否包含某个键
public boolean containsValue(Object value) 判断是否包含某个值
public Set keySet() 获取全部键的集合
public Collection values() 获取Map集合的全部值

Map集合的遍历方式

1、键找值
  • 先获取Map集合全部的键,再通过遍历键来找值
//1、提起Map集合的全部键到一个Set集合中去
Set<String> keys=map.keySet();
//2、遍历Set集合,得到每一个键
for(String key : keys){
    //3、跟据键去找值
    Integer value = map.get(key);
    System.out.println(key+"="+value);
}
2、键值对
  • 把“键值对”看成一个整体进行遍历(难度较大)
Map提供的方法 说明
Set<Map.Entry<K,V>>entrySet() 获取所有“键值对”的集合
//1、把Map集合转换成Set集合,里面的元素类型都是键值对类型
Set<Map.Entry<String,Double>> entries=map.entrySet(); //.var快捷键
//2、遍历Set集合,得到每一个键值对类型元素
for(Map.Entry<String,Double> entry:entrys){
    String key=entry.getKey();
    double value=entry.getValue();
    System.out.println(key+"===>"+value);
}
3、Lambda表达式
  • 需要用到Map的如下方法
方法名称 说明
default void forEach(BiConsumer<? super k, ? super V> action) 结合Lambda遍历Map集合
map.forEach((k,v)->{
    System.out.println(k+"--->"+v);
});

Stream流

认识Stream流

  • 可以用于操作集合或者数组

  • 优势:Stream流大量的结合了Lambda的语法风格来编程,功能性能强大,代码简洁,可读性好。

Stream流的使用步骤

1、获取Stream流

2、调用流水线的各种方法,进行数据处理

3、获取处理的结果(遍历、统计、收集到一个新集合中返回)

获取Stream流

  • 获取集合的Stream流
//1、获取集合的Stream流:调用集合提供的Stream方法
Collection<String> list= new ArrayList<>();
Stream<String> s1= list.stream();
//2、Map集合
Map<String,Integer> map = new HashMap<>();
//获取键流
Stream<String> s2= map.keySet().stream();
//获取值流
Stream<Integer> s3= map.values().stream();
//获取键值对流
Stream<Map.Entry<String,Integer>> s4 = map.entrySet().stream();
  • 获取数组的Stream流
String[] names;
//1、获取当前数组的Stream流
Stream<String> s5 = Array.stream(names);
//2、获取当前接受数据的Stream流
Stream<String> s6= Stream.of(names);

Stream流提供的方法

  • 中间方法指的是调用完成后会返回新的Stream流,可以继续使用(支持链式编程)
Stream 提供的常用中间方法 说明
Stream<T> filter(Predicate<? super T> predicate) 用于对流中的数据进行过滤。
Stream<I> sorted() 对元素进行升序排序。
Stream<I> sorted(Comparator<? super I> comparator) 按照指定规则排序。
Stream<T> limit(long maxSize) 获取前几个元素。
Stream<T> skip(long n) 跳过前几个元素。
Stream<T> distinct() 去除流中重复的元素。
<R> Stream<R> map(Function<? super T, ? extends R> mapper) 对元素进行加工,并返回对应的新流。
static <T> Stream<T> concat(Stream a, Stream b) 合并 a 和 b 两个流为一个流。

终结方法、收集Stream流

Stream流的终结方法
  • 终结方法指的是调用完成后,不会返回新Stream了,没法继续使用流了
Stream 提供的常用终结方法 说明
void forEach(Consumer action) 对此流运算后的元素执行遍历。
long count() 统计此流运算后的元素个数。
Optional<I> max(Comparator<? super I> comparator) 获取此流运算后的最大值元素。
Optional<I> min(Comparator<? super I> comparator) 获取此流运算后的最小值元素。
收集Stream流
  • 把Stream流操作后的结果转回到集合或数组中去返回
  • 注意:流只能收集一次.
Stream 提供的常用终结方法 说明
R collect(Collector collector) 把流处理后的结果收集到一个指定的集合中去。
Object[] toArray() 把流处理后的结果收集到一个数组中去。
Collectors 工具类提供的具体收集方式 说明
public static <T> Collector<T> toList() 把元素收集到 List 集合中。
public static <T> Collector<T> toSet() 把元素收集到 Set 集合中。
public static Collector toMap(Function keyMapper, Function valueMapper) 把元素收集到 Map 集合中。

方法中可变参数

  • 一种特殊形参,定义在方法、构造器的新参列表中,格式是:数据类型...参数名称
public static void sum(int...num){
}
  • 特点:可以不传数据;可以传一个或者同时传多个数据给它;也可以传一个数组给它。

  • 好处:常常用来灵活的接收数组。

  • 注意事项:

    • 可变参数在方法内部是一个数组。
    • 一个新参列表中可变参数只能有一个
    • 可变参数必须放在新参列表的最后面
    public static void sum(int age,int...nums){
    }
    

collections工具类

  • 是一个用来操作集合的工具类
方法名称 说明
public static <T> boolean addAll(Collection<? super T> c, T... elements) 给集合批量添加元素。
public static void shuffle(List<?> list) 打乱 List 集合中的元素顺序。
public static <T> void sort(List<T> list) 对 List 集合中的元素进行升序排序(默认使用自然顺序)。
public static <T> void sort(List<T> list, Comparator<? super T> c) 对 List 集合中的元素,按照比较器对象指定的规则进行排序。
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐