上一篇文章说了Stream流的基础,Lambda表达式,今天我们就来看一下java8中强大的Stream流!
Stream流是Java8中引入的一个强大的功能,它允许我们以一种更加高效和简洁的方式处理集合、数组等数据结构中的元素。
Stream流的几个特点:
- 中间操作和终端操作:Stream 流的操作分为中间操作和终端操作。中间操作可以连接起来形成一个流水线,而终端操作会对流水线中的元素进行最终处理,并产生一个新的集合或值。
- 延迟执行:Stream 流的操作不会立即执行,而是等到需要结果的时候才执行。这种特性称为“惰性求值”,也就是当我们执行终端操作的时候整个流才会执行。
- 不存储数据源:Stream 流在操作过程中不会保存数据源中的元素,而是按照特定的规则对数据进行计算。
- 不改变数据源:Stream 流在操作过程中不会改变数据源,而是会产生一个新的集合或值,所以我们在执行完终端操作后需要返回新的数据源。
Stream流的操作步骤为:创建Stream、中间操作、终止操作(终端操作)并产生结果,接下来我们将分为这三部分章节进行讲解。
Stream串行流的创建- 使用集合或数组调用 Collection.stream()或 Arrays.stream(T[] array) 方法。
//集合
ArrayList<String> list = new ArrayList<>();
list.stream().forEach(System.out::println);
String[] array = new String[10];
//数组
array[0]="a";
Arrays.stream(array).forEach(System.out::println);
- 使用 Stream.of() 静态方法,通过显示值创建一个流。
Stream.of("aa","bb").forEach(System.out::println);
- 使用 Stream.iterate() 和 Stream.generate() 静态方法创建无限流。
//如果不限制的话将会一直生成并输出
Stream.generate(Math::random).limit(4).forEach(System.out::println);
//从0开始,每次加2,不限制将会一直输出
Stream.iterate(0, (integer)->integer 2).limit(4).forEach(System.out::println);
Stream并行流的创建
ArrayList<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");
//并行流
list.parallelStream().forEach(System.out::println);
//串行流
list.stream().forEach(System.out::println);
//串行流改并行流
list.stream().parallel().forEach(System.out::println);
//判断是否是并行流
System.out.println(list.stream().parallel().isParallel());
执行结果
并行流与串行流的区别
- 串行流就是将源数据转换为一个流对象,然后单线程下执行聚合操作的流(也就是单一管道流)
- 并行流(Parallel Stream)就是将数据分为多个子流对象进行多线程操作(也就是多个管道流)
需要注意的是并行流并不总是比顺序流快。所以正确的姿势使用并行流是尤为重要的,不然适得其反(请注意线程安全问题)
中间操作区分中间操作和终端操作的简单方法就是看是否返回的是Stream,如果是则是中间操作,否则是终端操作
- filter过滤操作
//要求传入一个Predicate函数式接口并返回boolean作为筛选条件
Stream<T> filter(Predicate<? super T> predicate);
ArrayList<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("13");
list.add("12");
list.add("11");
//过滤集合中以1开头的字符串
list.stream().filter(x->x.startsWith("1")).forEach(System.out::println);
- map转换操作
//要求传入一个Function函数式接口,传入集合参数,返回要转化的结果
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
//与上面的区别是当前流仅能转换为int类型,如果是其他数值类型,也会强转为int
IntStream mapToInt(ToIntFunction<? super T> mapper);
//与上面的区别是当前流仅能转换为long类型,如果是其他数值类型,也会强转为long
LongStream mapToLong(ToLongFunction<? super T> mapper);
//与上面的区别是当前流仅能转换为double类型,如果是其他数值类型,也会强转为double
DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper);
ArrayList<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("13");
list.add("12");
list.add("11");
//将集合中的字符串参数转化为数字类型
list.stream().map(Integer::parseInt).forEach(System.out::println);
list.stream().mapToInt(Integer::parseInt).forEach(System.out::println);
list.stream().mapToDouble(Double::parseDouble).forEach(System.out::println);
list.stream().mapToLong(Long::parseLong).forEach(System.out::println);
- flatMap扁平转换操作
比map多了一个flat,flat的意思是平的、扁平的含义,操作的效果是对流的元素应用一对多转换,然后将生成的元素展平为新的流。话不多说我们直接上案例
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper);
LongStream flatMapToLong(Function<? super T, ? extends LongStream> mapper);
DoubleStream flatMapToDouble(Function<? super T, ? extends DoubleStream> mapper);
ArrayList<Company> companies = new ArrayList<>();
Staff wp = new Staff("王朋", "001");
Staff lm = new Staff("李明", "002");
Staff ly = new Staff("李艳", "003");
Staff wh = new Staff("王昊", "004");
Staff wm = new Staff("王明", "005");
Staff wz = new Staff("王中", "006");
Company company1 = new Company("字节跳动", Arrays.asList(wp,lm));
Company company2 = new Company("阿里巴巴", Arrays.asList(ly,wh));
Company company3 = new Company("华为", Arrays.asList(wm,wz));
companies.add(company1);
companies.add(company2);
companies.add(company3);
companies.stream().map(Company::getStaffs).forEach(System.out::println);
companies.stream().flatMap(x->x.getStaffs().stream()).forEach(System.out::println);
操作结果
看出来区别了吗,map的话只是把每个staff集合进行了输出;而flatmap的话是将每个staff集合中的数据再次拿出来遍历并输出。
- distinct去重操作
去重依然是根据hashcode和queals方法进行,所以对于类我们需要重写这两个方法哦
Staff wp = new Staff("王朋", "001");
Staff lm = new Staff("李明", "002");
Staff ly = new Staff("李艳", "003");
ArrayList<Staff> staff = new ArrayList<>();
staff.add(wp);
staff.add(lm);
staff.add(ly);
staff.add(new Staff("王朋","001"));
staff.stream().distinct().forEach(System.out::println);
- sorted排序操作
//类实现了Comparable接口的话可以直接调用
Stream<T> sorted();
//提供排序算法
Stream<T> sorted(Comparator<? super T> comparator);
ArrayList<Company> companies = new ArrayList<>();
Staff wp = new Staff("王朋", 1);
Staff lm = new Staff("李明", 2);
Staff ly = new Staff("李艳", 3);
Staff wh = new Staff("王昊", 4);
Staff wm = new Staff("王明", 5);
Staff wz = new Staff("王中", 6);
Company company = new Company("", Arrays.asList(wp, lm, ly, wh, wm, wz));
//从小按大排序
company.getStaffs().stream().sorted((o1,o2)->o1.getStaffNumber()-o2.getStaffNumber()).forEach(System.out::println);
//也可以使用Comparator的静态方法
company.getStaffs().stream().sorted(Comparator.comparingInt(Staff::getStaffNumber)).forEach(System.out::println);
//如果类实现类Comparable接口重写了排序方法的话,可以直接调用无参方法
company.getStaffs().stream().sorted().forEach(System.out::println);
- limit限制条数操作
Stream<T> limit(long maxSize);
ArrayList<Company> companies = new ArrayList<>();
Staff wp = new Staff("王朋", 1);
Staff lm = new Staff("李明", 2);
Staff ly = new Staff("李艳", 3);
Staff wh = new Staff("王昊", 4);
Staff wm = new Staff("王明", 5);
Staff wz = new Staff("王中", 6);
Company company = new Company("", Arrays.asList(wp, lm, ly, wh, wm, wz));
//限制数量为前三个
company.getStaffs().stream().limit(3).forEach(System.out::println);
- peek操作
peek的意思为偷看,他与我们后面讲的终端操作forEach很像,内部都是一个Consumer接口,唯一的区别是peek是中间操作而foreach是终端操作。peek可以debug的时候查看流中的数据是否有问题。
Stream<T> peek(Consumer<? super T> action);
ArrayList<Company> companies = new ArrayList<>();
Staff wp = new Staff("王朋", 1);
Staff lm = new Staff("李明", 2);
Staff ly = new Staff("李艳", 3);
Staff wh = new Staff("王昊", 4);
Staff wm = new Staff("王明", 5);
Staff wz = new Staff("王中", 6);
Company company = new Company("", Arrays.asList(wp, lm, ly, wh, wm, wz));
company.getStaffs().stream().peek(x->x.setStaffNumber(1)).forEach(System.out::println);
- skip跳过操作
//很简单,指定跳过前几个就可以
Stream<T> skip(long n);
ArrayList<Company> companies = new ArrayList<>();
Staff wp = new Staff("王朋", 1);
Staff lm = new Staff("李明", 2);
Staff ly = new Staff("李艳", 3);
Staff wh = new Staff("王昊", 4);
Staff wm = new Staff("王明", 5);
Staff wz = new Staff("王中", 6);
Company company = new Company("", Arrays.asList(wp, lm, ly, wh, wm, wz));
//跳过前两个
company.getStaffs().stream().skip(2).forEach(System.out::println);
- concat连接流
这是一个静态方法,意在将两个相同类型的流做连接并产生一个新的流
public static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b) {
Objects.requireNonNull(a);
Objects.requireNonNull(b);
@SuppressWarnings("unchecked")
Spliterator<T> split = new Streams.ConcatSpliterator.OfRef<>(
(Spliterator<T>) a.spliterator(), (Spliterator<T>) b.spliterator());
Stream<T> stream = StreamSupport.stream(split, a.isParallel() || b.isParallel());
return stream.onClose(Streams.composedClose(a, b));
}
Staff wp = new Staff("王朋", 1);
Staff lm = new Staff("李明", 2);
Staff ly = new Staff("李艳", 3);
Staff wh = new Staff("王昊", 4);
Staff wm = new Staff("王明", 5);
Staff wz = new Staff("王中", 6);
Company company = new Company("", Arrays.asList(wp, lm, ly, wh, wm, wz));
Company company1 = new Company("", Arrays.asList(wp, lm, ly, wh, wm, wz));
Stream<Staff> concat = Stream.concat(company.getStaffs().stream(), company1.getStaffs().stream());
concat.forEach(System.out::println);
- foreach循环遍历
这个我们在上面一直在用,forEach并不会返回任何东西,它方法内部是一个消费型接口
//串行流的时候不能保证遍历的顺序
void forEach(Consumer<? super T> action);
Staff wp = new Staff("王朋", 1);
Staff lm = new Staff("李明", 2);
Staff ly = new Staff("李艳", 3);
Staff wh = new Staff("王昊", 4);
Staff wm = new Staff("王明", 5);
Staff wz = new Staff("王中", 6);
Company company = new Company("", Arrays.asList(wp, lm, ly, wh, wm, wz));
company.getStaffs().stream().forEach(x->x.setStaffNumber(1));
System.out.println(company.getStaffs());
- forEachOrdered排序循环遍历
//串行流的时候确保与原顺序一致,尤其是并行流的时候
void forEachOrdered(Consumer<? super T> action);
Staff wp = new Staff("王朋", 1);
Staff lm = new Staff("李明", 2);
Staff ly = new Staff("李艳", 3);
Staff wh = new Staff("王昊", 4);
Staff wm = new Staff("王明", 5);
Staff wz = new Staff("王中", 6);
Company company = new Company("", Arrays.asList(wp, lm, ly, wh, wm, wz));
company.getStaffs().stream().parallel().forEachOrdered(System.out::println);
company.getStaffs().stream().parallel().forEach(System.out::println);
- toArray转数组
//将流转成Object数组
Object[] toArray();
//转成执行类型数组
<A> A[] toArray(IntFunction<A[]> generator);
Staff wp = new Staff("王朋", 1);
Staff lm = new Staff("李明", 2);
Staff ly = new Staff("李艳", 3);
Staff wh = new Staff("王昊", 4);
Staff wm = new Staff("王明", 5);
Staff wz = new Staff("王中", 6);
Company company = new Company("", Arrays.asList(wp, lm, ly, wh, wm, wz));
//默认返回的是一个Object数组
Object[] objects = company.getStaffs().stream().toArray();
//返回指定的类型
Staff[] staff = company.getStaffs().stream().toArray(new IntFunction<Staff[]>() {
@Override
public Staff[] apply(int value) {
return new Staff[value];
}
});
//使用方法引用
Staff[] staffArray = company.getStaffs().stream().toArray(Staff[]::new);
- reduce计算操作
用于对流中的内容做计算操作,其中有三个重载方法
//给一个初始值,给一个计算过程
T reduce(T identity, BinaryOperator<T> accumulator);
//不给初始值,默认是集合元素的第一个值,给一个计算过程
Optional<T> reduce(BinaryOperator<T> accumulator);
//多一个参数,用于并行流计算
<U> U reduce(U identity,
BiFunction<U, ? super T, U> accumulator,
BinaryOperator<U> combiner);
//T reduce(T identity, BinaryOperator<T> accumulator)实例:
List<Integer> numbers = Arrays.asList(1, 3, 4, 5, 6, 7, 10);
//求集合中的数值总和
//初始值为4
Integer sum = numbers.stream().reduce(4, new BinaryOperator<Integer>() {
@Override
public Integer apply(Integer integer, Integer integer2) {
//第一个integer为每次计算的结果,首次为初始值
//第二个为流中的每个元素
//最终返回的值在下次便利时会赋值给integer
System.out.println(Thread.currentThread().getName() ">>>integer>>>" integer ",integer2>>>>" integer2);
return integer integer2;
}
});
System.out.println(sum);
//最终结果40
//BinaryOperator接口提供了几个静态方法minBy、maxBy
//其中maxBy为求最大值,将集合中的值于我们提供的默认值进行比较,返回最大值
Integer sum1 = numbers.stream().reduce(4, BinaryOperator.maxBy((o1,o2)->o1-o2));
//minBy为求最小值,将集合中的值于我们提供的默认值进行比较,返回最小值
Integer sum1 = numbers.stream().reduce(4, BinaryOperator.minBy((o1,o2)->o1-o2));
//
Integer sum1 = numbers.stream().reduce(4, BinaryOperator.andThen((o1,o2)->o1-o2));
//需要注意的是当使用并行流时,每个线程的reduce的默认值都会是指定的默认值,怎么个意思,看例子
Integer parallelSum = numbers.stream().parallel().reduce(4, new BinaryOperator<Integer>() {
@Override
public Integer apply(Integer integer, Integer integer2) {
System.out.println(Thread.currentThread().getName() ">>>integer>>>" integer ",integer2>>>>" integer2);
return integer integer2;
}
});
System.out.println(parallelSum);
//最终结果64
串行流时,我们发现正常在初始值的基础上进行累加;但是当是并行流时,每启动一个线程,我们的integer初始值都是4然后最终将每个线程的结果进行累加。
//Optional<T> reduce(BinaryOperator<T> accumulator)实例:
List<Integer> numbers = Arrays.asList(1, 3, 4, 5, 6, 7, 10);
//求集合中的数值总和
List<Integer> numbers = Arrays.asList(1, 3, 4, 5, 6, 7, 10);
//在当前方法中,会将集合中的第一个值作为默认值,参考下图
Optional<Integer> reduce = numbers.stream().reduce(new BinaryOperator<Integer>() {
@Override
public Integer apply(Integer integer, Integer integer2) {
System.out.println("integer:" integer);
System.out.println("integer2:" integer2);
return integer integer2;
}
});
System.out.println(reduce.get());
单参数实例
//<U> U reduce(U identity,BiFunction<U, ? super T, U> accumulator,BinaryOperator<U> combiner);
List<Integer> numbers = Arrays.asList(1, 3, 4, 5, 6, 7, 10);
Integer reduce = numbers.stream().reduce(0, new BinaryOperator<Integer>() {
@Override
public Integer apply(Integer integer, Integer integer2) {
return integer integer2;
}
}, new BinaryOperator<Integer>() {
@Override
public Integer apply(Integer integer, Integer integer2) {
return integer integer2;
}
});
- collect收集操作
将流转换为指定的集合
<R, A> R collect(Collector<? super T, A, R> collector);
//第一个参数是提供一个基础容器,第二个是将集合参数转化为指定类型,第三个参数是将转化后的参数存入到指定容器中
<R> R collect(Supplier<R> supplier,BiConsumer<R, ? super T> accumulator,BiConsumer<R, R> combiner);
Staff wp = new Staff("王朋", 1);
Staff lm = new Staff("李明", 2);
Staff ly = new Staff("李艳", 3);
Staff wh = new Staff("王昊", 4);
Staff wm = new Staff("王明", 5);
Staff wz = new Staff("王中", 6);
Company company = new Company("字节跳动", Arrays.asList(wp, lm, ly, wh, wm, wz));
//将集合中的某些参数转化为map
HashMap<String, Integer> hashMap = company.getStaffs().stream().collect(new Supplier<HashMap<String, Integer>>() {
@Override
public HashMap<String, Integer> get() {
return new HashMap<String, Integer>();
}
}, new BiConsumer<HashMap<String, Integer>, Staff>() {
@Override
public void accept(HashMap<String, Integer> hashMap, Staff staff) {
hashMap.put(staff.getStaffName(), staff.getStaffNumber());
}
}, new BiConsumer<HashMap<String, Integer>, HashMap<String, Integer>>() {
@Override
public void accept(HashMap<String, Integer> hashMap, HashMap<String, Integer> hashMap1) {
hashMap.putAll(hashMap1);
}
});
System.out.println(hashMap);
//<R, A> R collect(Collector<? super T, A, R> collector);
//对于这种,真要是写匿名内部类是非常麻烦的,但是java提供了Collectors工具类
Staff wp = new Staff("王朋", 1);
Staff lm = new Staff("李明", 2);
Staff ly = new Staff("李艳", 3);
Staff wh = new Staff("王昊", 4);
Staff wm = new Staff("王明", 5);
Staff wz = new Staff("王中", 6);
List<Staff> staffs = Arrays.asList(wp, lm, ly, wh, wm, wz);
//转list
List<Staff> list = staffs.stream().collect(Collectors.toList());
//转set
Set<Staff> set = staffs.stream().collect(Collectors.toSet());
//转成任意你想要的集合
ArrayList<Staff> arrayList = staffs.stream().collect(Collectors.toCollection(new Supplier<ArrayList<Staff>>() {
@Override
public ArrayList<Staff> get() {
return new ArrayList<Staff>();
}
}));
//按指定字段进行分组
Map<Integer, List<Staff>> collect = staffs.stream().collect(Collectors.groupingBy(new Function<Staff, Integer>() {
@Override
public Integer apply(Staff staff) {
return staff.getStaffNumber();
}
}));
//先分组再求每组的数量
Map<Integer, Long> map = staffs.stream().collect(Collectors.groupingBy(Staff::getStaffNumber, Collectors.counting()));
System.out.println(map);
//先分组再求每组的数量,这里默认返回了1,实际上最终会将返回值相加
Map<Integer, Long> map1 = staffs.stream().collect(Collectors.groupingBy(Staff::getStaffNumber, Collectors.summingLong(new ToLongFunction<Staff>() {
@Override
public long applyAsLong(Staff value) {
return 1;
}
})));
System.out.println(map1);
//集合转map,key是StaffNumber,value是StaffName
Map<Integer, String> map2 = staffs.stream().collect(Collectors.toMap(new Function<Staff, Integer>() {
@Override
public Integer apply(Staff staff) {
return staff.getStaffNumber();
}
}, new Function<Staff, String>() {
@Override
public String apply(Staff staff) {
return staff.getStaffName();
}
}));
System.out.println(map2);
//分组后对map的value字段进行再次处理,将List<Staff>转化为map,key为StaffNumber、value为StaffName
Map<String, Map<Integer, String>> map3 = staffs.stream().collect(Collectors.groupingBy(Staff::getStaffName, Collectors.toMap(Staff::getStaffNumber, Staff::getStaffName)));
System.out.println(map3);
//多级分组,先按工号分,然后再在每组里按名字长短分
Map<Integer, Map<Integer, List<Staff>>> map4 = staffs.stream().collect(Collectors.groupingBy(Staff::getStaffNumber, Collectors.groupingBy(x -> x.getStaffName().length())));
System.out.println(map4);
//集合转字符串拼接
List<String> list1 = Arrays.asList("a", "b", "c");
//abc
System.out.println(list1.stream().collect(Collectors.joining()));
//a,b,c
System.out.println(list1.stream().collect(Collectors.joining(",")));
//aa,b,cc
System.out.println(list1.stream().collect(Collectors.joining(",","a","b")));
//求指定字段的数值运算
IntSummaryStatistics summaryStatistics = staffs.stream().collect(Collectors.summarizingInt(Staff::getStaffNumber));
//求和
long sum = summaryStatistics.getSum();
//平均值
double average = summaryStatistics.getAverage();
//最小值
int min = summaryStatistics.getMin();
//最大值
int max = summaryStatistics.getMax();
//总数量
long count = summaryStatistics.getCount();
System.out.println("sum:" sum ",average:" average ",min:" min ",max:" max ",count:" count);
- min获取最小值元素
获取当前集合中元素最小的一个
Optional<T> min(Comparator<? super T> comparator);
//获取工号最小的一个
Staff wp = new Staff("王朋", 1);
Staff lm = new Staff("李明", 2);
Staff ly = new Staff("李艳", 3);
Staff wh = new Staff("王昊", 4);
Staff wm = new Staff("王明", 5);
Staff wz = new Staff("王中", 6);
Company company = new Company("", Arrays.asList(wp, lm, ly, wh, wm, wz));
Optional<Staff> optionalStaff = company.getStaffs().stream().min(new Comparator<Staff>() {
@Override
public int compare(Staff o1, Staff o2) {
return o1.getStaffNumber() - o2.getStaffNumber();
}
});
if (optionalStaff.isPresent()) {
Staff staff = optionalStaff.get();
System.out.println(staff);
}
Optional不会的可以看之前的一篇文章:
- max获取最大值元素
获取当前集合中元素最大的一个
Optional<T> max(Comparator<? super T> comparator);
Staff wp = new Staff("王朋", 1);
Staff lm = new Staff("李明", 2);
Staff ly = new Staff("李艳", 3);
Staff wh = new Staff("王昊", 4);
Staff wm = new Staff("王明", 5);
Staff wz = new Staff("王中", 6);
Company company = new Company("", Arrays.asList(wp, lm, ly, wh, wm, wz));
Optional<Staff> optionalStaff = company.getStaffs().stream().max(new Comparator<Staff>() {
@Override
public int compare(Staff o1, Staff o2) {
return o1.getStaffNumber() - o2.getStaffNumber();
}
});
if (optionalStaff.isPresent()) {
Staff staff = optionalStaff.get();
System.out.println(staff);
}
- count获取元素数量
求集合中的元素数量
long count();
Staff wp = new Staff("王朋", 1);
Staff lm = new Staff("李明", 2);
Staff ly = new Staff("李艳", 3);
Staff wh = new Staff("王昊", 4);
Staff wm = new Staff("王明", 5);
Staff wz = new Staff("王中", 6);
Company company = new Company("", Arrays.asList(wp, lm, ly, wh, wm, wz));
System.out.println(company.getStaffs().stream().count());
- anyMatch任意匹配指定条件
集合中是否有任意一个匹配指定条件的数据
boolean anyMatch(Predicate<? super T> predicate);
Staff wp = new Staff("王朋", 1);
Staff lm = new Staff("李明", 2);
Staff ly = new Staff("李艳", 3);
Staff wh = new Staff("王昊", 4);
Staff wm = new Staff("王明", 5);
Staff wz = new Staff("王中", 6);
Company company = new Company("", Arrays.asList(wp, lm, ly, wh, wm, wz));
System.out.println(company.getStaffs().stream().anyMatch(x -> "王朋".equals(x.getStaffName())));
//true
- allMatch所有元素匹配指定条件
集合中是否所有元素都匹配指定条件的数据
boolean allMatch(Predicate<? super T> predicate);
Staff wp = new Staff("王朋", 1);
Staff lm = new Staff("李明", 2);
Staff ly = new Staff("李艳", 3);
Staff wh = new Staff("王昊", 4);
Staff wm = new Staff("王明", 5);
Staff wz = new Staff("王中", 6);
Company company = new Company("字节跳动", Arrays.asList(wp, lm, ly, wh, wm, wz));
System.out.println(company.getStaffs().stream().allMatch(x -> "王朋".equals(x.getStaffName())));
//false
- noneMatch无元素匹配指定条件
集合中是否所有元素都不匹配指定条件的数据
boolean noneMatch(Predicate<? super T> predicate);
Staff wp = new Staff("王朋", 1);
Staff lm = new Staff("李明", 2);
Staff ly = new Staff("李艳", 3);
Staff wh = new Staff("王昊", 4);
Staff wm = new Staff("王明", 5);
Staff wz = new Staff("王中", 6);
Company company = new Company("字节跳动", Arrays.asList(wp, lm, ly, wh, wm, wz));
System.out.println(company.getStaffs().stream().noneMatch(x -> "王坤".equals(x.getStaffName())));
//ture
- findFirst获取流中第一个参数
在流中获取第一个
Optional<T> findFirst();
Staff wp = new Staff("王朋", 1);
Staff lm = new Staff("李明", 2);
Staff ly = new Staff("李艳", 3);
Staff wh = new Staff("王昊", 4);
Staff wm = new Staff("王明", 5);
Staff wz = new Staff("王中", 6);
Company company = new Company("字节跳动", Arrays.asList(wp, lm, ly, wh, wm, wz));
Optional<Staff> first = company.getStaffs().stream().findFirst();
if (first.isPresent()) {
System.out.println(first.get());
}
//Staff{staffName='王朋', staffNumber='1'}
//上面的判断也可以替换为:
first.ifPresent(System.out::println);
- findAny获取流中任意一个参数
获取任意一个值
Optional<T> findAny();
Staff wp = new Staff("王朋", 1);
Staff lm = new Staff("李明", 2);
Staff ly = new Staff("李艳", 3);
Staff wh = new Staff("王昊", 4);
Staff wm = new Staff("王明", 5);
Staff wz = new Staff("王中", 6);
Company company = new Company("字节跳动", Arrays.asList(wp, lm, ly, wh, wm, wz));
Optional<Staff> first = company.getStaffs().stream().findAny();
first.ifPresent(System.out::println);
,