06_Set & Stream

本文详细介绍了JavaSet接口及其子类(如HashSet、LinkedHashSet和TreeSet)的特点,以及StreamAPI的创建、中间操作(如filter、distinct、limit、skip、sorted和map)和终止操作(如anyMatch、allMatch、noneMatch、findAny、findFirst、forEach、count、reduce和collect)。
摘要由CSDN通过智能技术生成

Set

特点

  1. Set是Collection的子接口
  2. Set数据结构是: 集合
  3. 有些子实现无序(HashSet), 有些子实现是有序的(LinkedHashSet, TreeSet大小有序)
  4. 所有子实现都不允许存储重复元素(重复的定义是否一致)
  5. 有些子实现允许存储null(HashSet LinkedHashSet), 有些子实现不允许存储null(TreeSet)

Set的API

-------------------------set接口, 没有在Collection的基础上额外定义什么api---------

---------------------------------增删改查方法---------------------------------

boolean add(E e): 
// 添加一个元素进入Collection

boolean addAll(Collection<? extends E> c): 
// 添加一个Collection进指定的Collection

boolean remove(Object o)// 删除元素, 只删除第一个出现的(如果存在多个)

boolean removeAll(Collection<?> c)// 删除Collection中的所有存在的元素,会全部删除,如果存在多个

boolean contains(Object o)// 判断是否存在指定元素

boolean containsAll(Collection<?> c)// 判断给定的collection中是否全部存在于目标Collection

boolean retainAll(Collection<?> c)// 将原有collection只保留传入的collection。

---------------------------------特殊方法---------------------------------

void clear()// 清空collection

boolean equals(Object o)// 判断是否相等

int hashCode()// 计算hashCode

boolean isEmpty(): 
// 是否为空

int size()// collection里面的元素个数

---------------------------------方便遍历方法---------------------------------

Object[] toArray(): 
// 将collection转成一个数组,方便遍历,

<T> T[] toArray(T[] a)// 类似,只是传入了一个数组

Iterator<E> iterator()// 返回一个迭代器

Set中的HashSet、LinkedHashSet、TreeSet操作跟Map中的差不多


Stream

  • 流是用来帮助我们简化集合操作的。
  • 写法简单
  • 代码极度的简化,但是可读性变差了

创建流

  • 调用集合类的Stream方法,生成一个流(最常用/常见
Collection collection = new ArrayList();
Stream stream = collection.stream();
  • 由值创建
Stream<String> test = Stream.of("zs", "ls", "wu", "zl");
  • 通过数组创建
String [] strs = {"zs", "ls", "wu"};
Stream<String> stream = Arrays.stream(strs);

中间操作

filter(过滤操作)

用于通过设置的条件过滤出元素

使用场景

  • 对元素进行过滤

eg:

public class Demo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("hello");
        list.add("hi");
        list.add("good");

        Stream<String> stream = list.stream();
        stream.filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                if(s.equals("hello")){
                    return true;
                }
                return false;
            }
        }).collect(Collectors.toList());
    }
}

-----> 转换为lambda表达式
/**
* 这里可以直接new这个接口,然后idea提示你怎么写
* 可以跟着idea一起走,它提示你就可以简化
* 需要注意: 一定要认识代码,如果不认识,退回去
*/


Stream<String> stream = list.stream();
stream.filter(s -> s.equals("hello")).collect(Collectors.toList());

注意: 每次中间操作会返回一个 Stream (可以有多次中间操作),这就允许对其操作可以像链条一样排列,变成一个管道。

  • filter中的方法:
Stream<T> filter(Predicate<? super T> predicate); 
public interface Predicate{}

// filter方法参数  ---->  需要传入的是一个 Predicate类型的实例。
// Predicate 里面只有一个方法。输入参数根据流里的数据确定,输出参数是个boolean

distinct(去重操作)

用于筛选元素(相当于去除重复元素)

使用场景

  • 对元素进行去重处理。底层是LinkedHashSet
  • 如果使用自定义的类,调用distinct,需要重写hashCode和equals方法

limit(截取操作)

用于获取指定数量(最大)的流

使用场景

StudentList.stream().filter(student -> student.getHeight > 180)
.limit(5)
.collect(Collectors.toList());

其中:
Stream<T> limit(long maxSize);

// limit(n)方法, 返回前n个元素.
// 如果流中有10个元素,limit(3) 则只返回3个元素。
// 如果流中有1个元素,limit(3) 则只返回1个元素。

skip(跳过操作)

skip(n)方法,表示跳过前n个元素

Stream<T> skip(long n);

// skip(n)方法, 跳过前n个元素, 返回之后的元素.  (如果整体不够n个, 返回空流)

sorted(排序操作)

用于对流进行排序

Stream<T> sorted(); 
				// 自然顺序排序
				
Stream<T> sorted(Comparator<? super T> comparator);
				// 提供一个比较器

eg:

List<Student> studentList = new StudentList().studentList;

studentList.stream().
filter(s -> s.getHeight() > 180)
.sorted((s1, s2) -> s1.getHeight() - s2.getHeight())
.collect(Collectors.toList());

map(转换操作)

用于映射每个元素到对应的结果

<R> Stream<R> map(Function<? super T, ? extends R> mapper);

// TODO: map映射返回新的数据,  map的参数是一个方法
// map主要是把一种类型转换成另外一种类型
// map在工作过程中,常用

eg:

 List<Student> studentList = new StudentList().studentList;

List<String> collect = studentList.stream()
    .map(student -> student.getName())
    .collect(Collectors.toList());
System.out.println(collect);

终止操作

anyMatch(是否有任意一个匹配)

检查流到最后的数据, 是否有一个/多个数据匹配某种情况

boolean anyMatch(Predicate<? super T> predicate);

//  anyMatch: 判断该stream中的所有元素, 是否存在某个/某些元素,可以根据某个条件处理之后, 满足true

eg:

boolean b = studentList.stream()
        .filter(s -> s.getHeight() > 190)
        .anyMatch(a -> {
          return a.getAddress() == Student.Address.BJ;
        });
System.out.println(b);

allMatch(是否所有的全匹配)

检查是否所有元素都匹配

boolean allMatch(Predicate<? super T> predicate);

// allMatch: 判断该stream中的所有元素, 是否所有元素 可以根据某个条件处理之后, 满足true

eg:

boolean b = studentList.stream().filter(s -> s.getHeight() >= 200)
        .allMatch(s -> s.getAddress() == Student.Address.SH);
System.out.println(b);

noneMatch(没有匹配)

检查是否没有匹配元素

boolean noneMatch(Predicate<? super T> predicate);

// noneMatch: 判断该stream中的所有元素, 是否所有元素 可以根据某个条件处理之后, 满足false

eg:

boolean b1 = studentList.stream()
.noneMatch(s -> Student.Address.SZ.equals(s.getAddress()));

System.out.println(b1);

findAny(找到任意一个)

返回流中任意元素:默认第一个

Optional<T> findAny();

// findAny: 返回任意元素(默认第一个)

eg:

List<Student> studentList = new StudentList().studentList;

Optional<Student> any = studentList.stream()
        .findAny();

//TODO: 注意, Optional作为一个容器代表一个值存在或者不存在
//TODO: Optional中存在几个方法, 可以让使用者显式的检查值存在或者不存在
    // <1>: isPresent()方法:  如果 Optional包含值返回true, 否则返回false
    // <2>: ifPresent(代码块)方法: 会将Optional包含的值, 传给指定的代码块
    // <3>: get()方法: 如果Optional包含值, 返回包含的值, 如果没有数据则抛出异常
    // <4>: orElse(默认值):  如果Optional包含值, 返回包含的值, 否则返回默认值


    any.isPresent();
    any.ifPresent(a -> System.out.println(a));
    any.get();

使用流程

  1. 需要判断一下这个optional里面有没有元素
  2. 如果有,直接拿数据

findFirst(找到第一个)

返回第一个元素

Optional<T> findFirst();

//  findFirst: 返回第一个元素

eg:

Optional<Student> any = studentList.parallelStream()
        .sorted((o1, o2) -> o1.getAge() - o2.getAge()).findFirst();
        
if (any.isPresent()) {
        Student student = any.get();
        System.out.println(student);
    }

forEach(遍历流)

void forEach(Consumer<? super T> action);

//  forEach: 遍历元素(void方法)

eg:

studentList.stream()
.filter(student -> student.getHeight() > 180)
.forEach(student -> System.out,println(student));

count(返回元素中数量)

long count();

//  count: 计算元素个数

eg:

long count = studentList.stream()
        .filter(a -> a.getAddress() == Student.Address.BJ)
        .count();
System.out.println(count);

reduce(按照一定规则减少数据)

将参加计算的元素按照某种方式减少。

比如:两两比较,返回较大的 —> 会拿到里面的最大值;
或者两两比较,返回较小的 —> 最终会拿到最小值

TODO: 规约 reduce

<1>一参情况: Optional<T> reduce(BinaryOperator<T> accumulator)

<2>二参情况: T reduce(T identity, BinaryOperator<T> accumulator);

<1>参数:
//  返回值类型为Optional, 是应对如果流中没有任何元素情况(这种情况没有初始值就无法返回结果)
//  所以1参是把结果包裹在一个Optional对象里(可以通过get方法获取),用以表明/处理结果可能不存在情况

<2>参数:
//  BinaryOperator: 将两个元素合起来产生一个新值
//  identity: 计算的初始值/起始值(用来和第一个元素计算结果)

eg:

// 计算年龄的总和
Optional<Integer> optional = studentList.stream()
        .map(a -> a.getAge())
        .reduce((a, b) -> a + b);

Integer sum = optional.get();
System.out.println(sum);


List<Student> studentList = new StudentList().studentList;

// 年龄最大的学生
Optional<Integer> reduce2 = studentList.stream().map(a -> a.getAge()).reduce((a, b) -> {
      if (a > b) {
        return a;
      }
      return b;
    });

Optional<Integer> reduce3 = studentList.stream().map(a -> a.getAge()).reduce(Integer::max);

// 年龄最小的学生
Optional<Integer> reduce4 = studentList.stream().map(a -> a.getAge()).reduce((a, b) -> {
      if (a > b) {
        return b;
      } else {
        return a;
      }
    });
Optional<Integer> reduce5 = studentList.stream().map(a -> a.getAge()).reduce(Integer::min);

collect(收集器)

用于收集数据经过流计算的结果

Collectors:收集,作用是将元素分别归纳进可变容器 ListMapSetCollection 或者ConcurrentMap

Collectors.toList()

Collectors.toCollection()

Collectors.toSet()

Collectors.toMap()

注意

// Collection 没有直接实现的子类

LinkedList<Student> collect = studentList.stream()
.filter(a -> a.getAddress() == Student.Address.WH)
.collect(Collectors.toCollection(() -> new LinkedList<>()));


// toMap
Map<String, Integer> collect1 = studentList.stream()
.filter(a -> a.getAddress() == Student.Address.WH)
.collect(Collectors.toMap(Student::getName, student -> student.getAge()));
// toMap中的去重
Map<String, Student> collect = studentList.stream()
.filter(student -> Student.getAddress().equals("beijing"))
.collect(Collection.toMap(student -> student.getAge(), student -> student
, (student, student2) -> student));
// 第三个参数代表,当我的key重复的时候,需要告诉我合并value的规则
  • 13
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

coo1heisenberg

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值