《JavaSE-第十九章》之Collection

简介: 《JavaSE-第十九章》之Collection

文章目录

1.集合概述

2.Iterable

3.Iterator

3.1for-each的本质

4.Collcetion

5.Collections

1.集合概述

在没有学习集合前,基本都是用数组存储元素,而数组只适用于元素类型确定以及个数确定,不需要大量的增删的场景。集合却可以完美的解决上述问题,集合在未指定泛型参数时,默认的元素类型为Object,可以存储任意类型的数据,而且无需考虑集合的大小,因为集合的大小是可以动态变化的。所以集合非常适用于做增删元素的场景。

集合体系

在Java中集合分为两个大类,一是单列集合,二是双列集合。所谓的单例集合就是元素只能存储一个数组,而双列集合存储的是键值对。

2.Iterable

Iterable是可迭代的意思,作用是为集合类提供for-each循环的支持。

package java.lang;
import java.util.Iterator;
import java.util.Objects;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.Consumer;
public interface Iterable<T> {//表示对象可以被迭代,它有个方法iterator方法,返回Iterator对象,实际通过Iterator接口的方法进行遍历
    //类实现了iterable,就可以使用foreach
    //类没有实现则也可以创建Iterator的对象
    Iterator<T> iterator();
    //为了方便遍历并操作集合内的元素
    default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }
    //提供了一个可以并行遍历元素的迭代器
    default Spliterator<T> spliterator() {
        return Spliterators.spliteratorUnknownSize(iterator(), 0);
    }
}

3.Iterator

Iterator是foreach遍历的主体,它的源码如下:

package java.util;
import java.util.function.Consumer;
public interface Iterator<E> {
  //判断迭代的集合是否还有多个可以访问的元素,如果有则返回true,反之则false
    boolean hasNext();
  //可以逐个访问集合中的每个元素,如果访问到集合末尾,该方法会抛出一个NoSuchElementException
    E next();
  //删除上一次调用next()方法返回的元素
    default void remove() {
        throw new UnsupportedOperationException("remove");
    }
    //访问元素,指定访问的动作,直到再没有更多的元素,或者这个动作会抛出一个异常
    default void forEachRemaining(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        while (hasNext())
            action.accept(next());
    }
}

3.1for-each的本质

for-each循环的实现也依赖于Iterator,只不过我们写的for-each在编译时会被转换成Iterator方式遍历。

代码示例

import java.util.ArrayList;
/**
 * @author 929KC
 * @date 2022/11/8 15:01
 * @description:
 */
public class Demo {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        for (Integer integer : list) {
            System.out.print(integer+" ");
        }
    }
}

为了对上述结论验证,可以反编译(class->java)上述代码

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
import java.util.ArrayList;
import java.util.Iterator;
public class Demo {
    public Demo() {
    }
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        Iterator var2 = list.iterator();
        while(var2.hasNext()) {
            Integer integer = (Integer)var2.next();
            System.out.print(integer + " ");
        }
    }
}

反编译之后,可以看到所谓的for-each,实际上就是使用迭代器迭代。

4.Collcetion

Collection是一个接口,它提供了对集合中元素进行操作的通用接口方法。为各种具体的实现类,提供了最大化的统一操作。也就意味着把握住了该接口中的方法,就几乎拿其具体的实现类的方法。

package java.util;
import java.util.function.Predicate;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
public interface Collection<E> extends Iterable<E> {
    //储存在集合中的元素个数
    int size();
    //判断集合是否为空
    boolean isEmpty();
  //判断集合是否包含某个元素
    boolean contains(Object o);
  //返回一个迭代集合元素的迭代器
    Iterator<E> iterator();
  //将集合转换成Object数组
    Object[] toArray();
  //返回这个集合中对象的数组。如果a足够大,将集合中的元素填入这个数组中。剩余空间填补null;否则分配一个新数组,其成员类型与a的成员类型相同,其长度等于集合的大小,并填充集合元素
    <T> T[] toArray(T[] a);
  //向集合添加元素
    boolean add(E e);
  //删除集合中的某个元素
    boolean remove(Object o);
  //判断该集合是否包含指定集合中的元素
    boolean containsAll(Collection<?> c);
  //将c集合中的所有元素都添加到当前集合中,添加成功返回true,反之则false
    boolean addAll(Collection<? extends E> c);
    //从当前集合中删除c集合中的所有元素,删除成功返回true,反之则false
    boolean removeAll(Collection<?> c);
  //删除满足某个条件的元素
    default boolean removeIf(Predicate<? super E> filter) {
        Objects.requireNonNull(filter);
        boolean removed = false;
        final Iterator<E> each = iterator();
        while (each.hasNext()) {
            if (filter.test(each.next())) {
                each.remove();
                removed = true;
            }
        }
        return removed;
    }
  //从当前集合中删除c集合中没有的元素,删除成功返回true,反之则false
    boolean retainAll(Collection<?> c);
    //清空集合中的元素
    void clear();
    boolean equals(Object o);
    int hashCode();
}

Collection部分方法演示

package com.kc.collection;
import org.junit.Test;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class CollectionTest {
    @Test
    public void ColletcionApl(){
        Collection<String> list = new ArrayList();
        list.add("叶秋涵");
        list.add("叶子秋");
        list.add("林黛玉");
        list.add("贾宝玉");
        ArrayList<String> list2 = new ArrayList<String>();
        list2.add("史湘云");
        list2.add("妙玉");
        list2.add("秦可卿");
        list.addAll(list2);
        Object[] objects = list.toArray();
        System.out.println(Arrays.toString(objects));
        System.out.println(list.contains("林黛玉"));
        System.out.println(list.size());
        System.out.println(list.isEmpty());
        System.out.println(list.containsAll(list2));
        String [] s = new String [20];
        String[] strings = list.toArray(s);
        System.out.println(Arrays.toString(strings));
        String [] s2 = new String [7];
        String[] strings2 = list.toArray(s2);
        System.out.println(Arrays.toString(strings2));
        Predicate<String> predicate = new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.equals("史湘云");
            }
        };
        System.out.println(list.removeIf(predicate));
        System.out.println(list);
        list.forEach(e-> System.out.print(e));
    }
}
//结果
//[叶秋涵, 叶子秋, 林黛玉, 贾宝玉, 史湘云, 妙玉, 秦可卿]
//true
//7
//false
//true
//[叶秋涵, 叶子秋, 林黛玉, 贾宝玉, 史湘云, 妙玉, 秦可卿, null, null, null, null, null, null, null, null, null, null, null, null, null]
//[叶秋涵, 叶子秋, 林黛玉, 贾宝玉, 史湘云, 妙玉, 秦可卿]
//true
//[叶秋涵, 叶子秋, 林黛玉, 贾宝玉, 妙玉, 秦可卿]
//叶秋涵叶子秋林黛玉贾宝玉妙玉秦可卿

5.Collections

Collections是操作集合的一个工具类,提供了大量的静态方法看以实现对集合元素的排序,添加一些元素,随机排序,替换等操作。

代码示例

package com.kc.collection;
import org.junit.Test;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class CollectionTest {
    @Test
    public void testCollections(){
        ArrayList<String> list = new ArrayList<>();
        //一次性向集合添加多个元素
        Collections.addAll(list,"林黛玉","妙玉","史湘云","张飞","贾宝玉","薛宝钗");
        System.out.println("未排序前:"+list);
        //使用默认的随机源随机排列指定的列表。
        System.out.println("随机排列指定前:"+list);
        Collections.shuffle(list);
        System.out.println("随机排列指定后:"+list);
        //将集合中元素按照默认规则排序。
        System.out.println("自然排序前:"+list);
        Collections.sort(list);
        System.out.println("自然排序后:"+list);
    }
}
//运行结果
//未排序前:[林黛玉, 妙玉, 史湘云, 张飞, 贾宝玉, 薛宝钗]
//随机排列指定前:[林黛玉, 妙玉, 史湘云, 张飞, 贾宝玉, 薛宝钗]
//随机排列指定后:[林黛玉, 妙玉, 张飞, 薛宝钗, 史湘云, 贾宝玉]
//自然排序前:[林黛玉, 妙玉, 张飞, 薛宝钗, 史湘云, 贾宝玉]
//自然排序后:[史湘云, 妙玉, 张飞, 林黛玉, 薛宝钗, 贾宝玉]

自定义排序

代码示例

package com.kc.collection;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class Apple implements Comparable<Apple>{
    private String name;
    private String color;
    private double price;
    private int weight;
   /** 
    * 自定义比较规则
    * @author 929KC
    * @date 2022/11/8 2022/11/8
    * @param o 
    * @return int 
    */
    @Override
    public int compareTo(Apple o) {
        // 按照重量进行比较的
        return this.weight - o.weight ; // List集存储相同大小的元素会保留
    }
}

对苹果类型按照自定义规则排序

package com.kc.collection;
import org.junit.Test;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class CollectionTest {
    @Test
    public void testCollections2(){
        List<Apple> apples = new ArrayList<>(); // 可以重复!
        apples.add(new Apple("毒苹果", "黑色", 9.9, 500));
        apples.add(new Apple("青苹果", "绿色", 15.9, 300));
        apples.add(new Apple("红苹果", "功色", 29.9, 400));
        apples.add(new Apple("黄苹果", "黄色", 9.8, 500));
       // 方法一:Apple类已经重写了比较规则,可以使用
        Collections.sort(apples); 
        System.out.println(apples);
         //方式二:sort方法自带比较器对象
        Collections.sort(apples, new Comparator<Apple>() {
            @Override
            public int compare(Apple o1, Apple o2) {
                return Double.compare(o1.getPrice() , o2.getPrice()); // 按照价格排序!!
            }
        });
        System.out.println(apples);
    }
}
//运行结果
//[Apple(name=青苹果, color=绿色, price=15.9, weight=300), Apple(name=红苹果, color=功色, price=29.9, weight=400), Apple(name=毒苹果, color=黑色, price=9.9, weight=500), Apple(name=黄苹果, color=黄色, price=9.8, weight=500)]
//[Apple(name=黄苹果, color=黄色, price=9.8, weight=500), Apple(name=毒苹果, color=黑色, price=9.9, weight=500), Apple(name=青苹果, color=绿色, price=15.9, weight=300), Apple(name=红苹果, color=功色, price=29.9, weight=400)]

相关文章
|
6天前
|
存储 Java BI
JavaSE&Collection集合
JavaSE&Collection集合
21 6
|
6天前
|
存储 Java 索引
从零开始学习 Java:简单易懂的入门指南之Collection集合及list集合(二十一)
从零开始学习 Java:简单易懂的入门指南之Collection集合及list集合(二十一)
|
10月前
|
存储 Java 索引
【JavaSE】Java基础语法(二十八):HashSet集合
1. HashSet集合概述和特点 底层数据结构是哈希表 存取无序 不可以存储重复元素 没有索引,不能使用普通for循环遍历
|
5月前
|
Java
【零基础学Java】—Collection集合(三十八)
【零基础学Java】—Collection集合(三十八)
|
9月前
|
存储 容器
《JavaSE-第十七章》之LinkedList
《JavaSE-第十七章》之LinkedList
20489 34
|
9月前
|
存储 Java Linux
《JavaSE-第十四章》之文件(一)
《JavaSE-第十四章》之文件(一)
|
10月前
|
算法 安全 Java
【JavaSE专栏47】Java常用类Collections解析,你了解JAVA集合类的通用用法吗?
【JavaSE专栏47】Java常用类Collections解析,你了解JAVA集合类的通用用法吗?
125 2
|
10月前
|
存储 算法 Java
【JavaSE专栏46】Java常用类Arrays解析,原生数组和List集合有何区别?
【JavaSE专栏46】Java常用类Arrays解析,原生数组和List集合有何区别?
107 0
|
10月前
|
存储 Java 索引
【JavaSE】Java基础语法(二十六):Collection集合
1. 数组和集合的区别 相同点 都是容器,可以存储多个数据 不同点 数组的长度是不可变的,集合的长度是可变的 数组可以存基本数据类型和引用数据类型 集合只能存引用数据类型,如果要存基本数据类型,需要存对应的包装类
|
10月前
|
存储 Java 索引
【JavaSE】Java基础语法(二十七):Set集合和 TreeSet
1. Set集合 1.1Set集合概述和特点【应用】 不可以存储重复元素 没有索引,不能使用普通for循环遍历