目录
方法引用
示例
接口
类
测试类
Stream
编辑 Stream 的操作三个步骤
创建 Stream 的 4 种方法
常见Stream接口的继承关系
Stream的中间操作
中间操作常用方法
Stream的终止操作
Stream的终止操作-collect()
示例代码演示
作业
在Lamda新特性的支持下,JAVA8中可以使用lamda表达式来创建匿名方法。然而,有时候我们仅仅是需要调用一个已存在的方法(如java中已经定义好的方法),在这时候java8新特性“方法引用”将会进一步简化操作(注意:需要有Lamda的支持)。
•方法引用的四种形式: •引用静态方法-->类名称::static 方法名称; •引用某个对象的实例的普通方法-->实例化对象::普通方法; •引用特定类型的任意对象的实例方法-->特定类::普通方法; •引用构造方法-->类名称::new•定义一个方法获取供给型接口类型的参数,调用get方法获取返回对象,并执行普通方法
package part4;/*** @date : 2022/11/23 9:36*/
@FunctionalInterface
public interface PersonInterface {public static final String name = "tidy";public static final Integer age =18;public void methodA();}
package part4;/*** @date : 2022/11/23 9:31*/
public class Person {String name;Integer age;public static int method1() {System.out.println("static静态方法...");return 0;}public static int method2(int a) {System.out.println("static静态方法..."+a);return 0;}public Person() {}public Person(String name, Integer age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}
}
package part4;import java.util.ArrayList;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;/*** @date : 2022/11/23 9:29*/
public class MethodReferenceDemo {public static void main(String[] args) {/* 方法引用的四种形式:引用静态方法-->类名称::static 方法名称;引用某个对象的实例的普通方法-->实例化对象::普通方法;引用特定类型的任意对象的实例方法-->特定类::普通方法;引用构造方法-->类名称::new
*/// 1)引用构造方法-->类名称::new/*Person person = new Person();System.out.println(person);*/
// 注意事项1:方法引用 前提要使用lambda表达式--》功能性函数
// Person person = Person::new;// 注意事项2:接口中没有构造方法 调用不成
// PersonInterface personInterface = PersonInterface::new;// 借助于供给型接口 实例化对象Supplier supplier = Person::new;Person person = supplier.get();System.out.println(person);// 2) 引用静态方法-->类名称::static 方法名称;Supplier method1 = Person::method1;Integer result = method1.get();System.out.println("result:"+result);System.out.println("==================");
// 调用静态方法时:选定和这个静态方法相匹配的功能性函数(是否匹配:是否有参数 是否有返回值--》使用哪个功能性函数)Function function = Person::method2;Integer apply = function.apply(66);System.out.println("applay:"+apply);System.out.println("==================");
// 3)引用某个对象的实例的普通方法-->实例化对象::普通方法;Person person1 = new Person("tidy",18);Supplier stringSupplier =person1::getName;String name = stringSupplier.get();System.out.println("name:"+name);// 4)引用特定类型的任意对象的实例方法-->特定类::普通方法;
// String equals方法 比较两个字符串是否相等 2个字符串
// BiFunctionBiFunction biFunction = String::equals;Boolean resultFlg = biFunction.apply("hello", "hello");System.out.println("resultFlg:"+resultFlg);System.out.println("6666666666666666666:");List list = new ArrayList();list.add(10);list.add(30);list.add(30);
// 内部类/* Consumer consumer = new Consumer() {@Overridepublic void accept(Integer integer) {System.out.println(integer);}};list.forEach(consumer);*//*list.forEach(new Consumer() {@Overridepublic void accept(Integer integer) {System.out.println(integer);}});*/// list.forEach(t-> System.out.println(t));
// println(..):有参数没有返回值/*Consumer consumer = System.out::println;
// 方法引用list.forEach(consumer);*/list.forEach(System.out::println);}
}
创建 Stream :一个数据源(如:集合、数组),获取一个流
中间操作 :一个中间操作链,对数据源的数据进行处理
终止操作(终端操作) :一个终止操作,执行中间操作链,并产生结果
•通过Collection中的steam()方法创建流 •通过Collection中的parallelSteam()方法创建流 •通过Arrays中的steam()方法创建流 •通过Stream中的of()静态方法创建流 •通过Stream中的iterate()方法创建流 •通过Steam中的generate()方法创建流
多个中间操作可以连接起来形成一个流水线,除非流水线上触发终止操作,否则中间操作不会执行任何的处理而在终止操作时一次性全部处理,称为“惰性求值”。
上面这个例子主要是对一组String数据进行操作,主要涉及到的中间操作方法有filter(),limit(),skip(),distinct()终止操作方法有forEach(),下面我们对这些常用方法进行简单介绍
分类 | 方法 | 描述 |
筛选和切片 | filter(Predicate p) | 接收Lambda,从流中排除某些元素 |
limit(long maxSize) | 截断流,使其元素不超过给定数量 | |
skip(long n) | 跳过元素,返回一个跳过前n个元素的流。若流中元素不足n个,则返回一个空流。与limit(n)互补 | |
distinct() | 筛选,通过流所生成元素的hashCode()和equals()去除重复元素 | |
映射 | map(Function f) | 接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素 |
mapToDouble(ToDoubleFunction f) | 接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的DoubleStream | |
mapTolnt(ToIntFunction f) | 同上 | |
mapToLong(ToLongFunction f) | 同上 | |
flatMap(Function f) | 接收一个函数作为参数,将流中的每一个值都换成另一个流,然后把所有流连接成一个流 | |
排序 | sorted() | 产生一个新流,其中按自然顺序排序 |
sorted(Comparator c) | 产生一个新流,其中按比较器顺序排序 |
分类 | 方法 | 描述 |
查找与匹配 | allMatch(Predicate p) | 检查是否匹配所有元素 |
anyMatch(Predicate p) | 检查是否至少匹配一个元素 | |
findFirst() | 检查是否没有匹配所有元素返回第一个元素 | |
findAny() | 返回当前流中的任意元素 | |
count() | 返回流中元素总数 | |
max(Comparator c) | 返回流中最大值 | |
min(Comparator c) | 返回流中最小值 | |
forEach() | 内部迭代 | |
归约 | reduce(T iden, BinaryOperator b) | 可以将流中元素反复结合起来,得到一个值。返回T |
reduce(BinaryOperator b) | 可以将流中元素反复结合起来,得到一个值。返回 Optional | |
收集 | collect(Collector c) | 将流转换为其他形式。接收一个 Collector 接口的实现,用于给 Stream 中元素做汇总的方法 |
演示
Collector 接口中方法的实现决定了如何对流执行收集操作(如收集到 List、Set/Map)。但是 Collectors 实用类提供了很多静态方法,可以方便地创建常见收集器实例,具体方法与实例如下表:
方法 | 返回类型 | 作用 |
toList | List | 把流中元素收集到 List |
toSet | Set | 把流中元素收集到 Set |
toCollection | Collection | 把流中元素收集到 Collection |
counting | Long | 计算流中元素的个数 |
summingInt | Integer | 对流中元素的整数属性求和 |
averagingInt | Double | 计算流中元素Integer属性的平均值 |
summarizingInt | IntSummaryStatistics | 收集流中Integer属性的统计值,如:平均值 |
joining | String | 连接流中每个字符串 |
maxBy | Optional | 根据比较器选择最大值 |
minBy | Optional | 根据比较器选择最小值 |
reducing | 归约产生的类型 | 收集流中Integer属性的统计值,如:平均值 |
collectingAndThen | 转换函数返回的类型 | 包裹另一个收集器,对其结果转换函数 |
groupingBy | Map | 根据某属性值对流分组,属性为K,结果为V |
partitioningBy | Map | 根据true或false进行分区 |
package part5;import org.junit.Test;import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;/*** @date : 2022/11/23 14:30*/
public class JunitStream {/*** 数据源(集合、数组、变量、字符串。。。)---》Stream流对象* 1、创建Stream流对象*/@Testpublic void createStream() {// list1数据源List list1 = new ArrayList<>();list1.add(10);list1.add(30);list1.add(20);// 1)集合对象中 stream()Stream stream = list1.stream();stream.forEach(t -> System.out.println(t));// 2)集合中方式2Stream stream2 = list1.parallelStream();stream2.forEach(t -> System.out.println(t));// 3)数组数据源--》StreamInteger[] arr = {1, 3, 5, 7};Stream stream3 = Arrays.stream(arr);// 4)Stream中的of方法Stream stream4 = Stream.of(1, 2, 3, 4, 5);stream4.forEach(t-> System.out.println(t));// 5)Stream中iterate
// 数据进行计算:从0开始 让他每次+2 :0 2 4 6 8 10.....
// iterate无限流
// Stream stream5 = Stream.iterate(0, t -> t + 2);// limit(3) 获取前3个数据Stream stream6 = Stream.iterate(0, t -> t + 2).limit(3);stream6.forEach(t -> System.out.println(t));System.out.println("===================");
// 6)Stream.generate
// Math.random()--double
// Stream.generate(()->{return Math.random();});
// Stream.generate(()-> Math.random());
// Stream generate = Stream.generate(Math::random);Stream stream7 = Stream.generate(Math::random).limit(2);stream7.forEach(t -> System.out.println(t));
// stream7.forEach(System.out::println);}/*** 2、流操作:* 中间操作*/@Testpublic void operation() {Stream stream = Stream.of("Tom", ",", "Hello", " ", "Hello", "World");// 1)中间操作-->新Stream流
// filter:过滤流 返回true条件都会添加到这个新流当中Stream newStream = stream.filter(str -> {if (",".equals(str)) {return false;} else {return true;}});newStream.forEach(t -> System.out.println(t));System.out.println("---------------------------");Stream stream2 = Stream.of("Tom", ",", "Hello", " ", "Hello", "World");// 中间操作--limit 获取前X个数据Stream newStream2 = stream2.limit(2);newStream2.forEach(t -> System.out.println(t));System.out.println("------1111111111----------------------------");Stream stream3 = Stream.of("Tom", ",", "Hello", " ", "Hello", "World");// 中间操作---skip跳过前多少个数据Stream streamNew = stream3.skip(2);streamNew.forEach(t -> System.out.println(t));System.out.println("----distict:-----------------------------");Stream streamDistinct = Stream.of(10, 20, 30, 10, 5);
// 中间操作去重--distinctStream newDistinctStream = streamDistinct.distinct();newDistinctStream.forEach(t -> System.out.println(t));// 数组 1,3,7,8,9,2,4,7,2----去重后求其数据个数Integer[] arr2 = {1, 3, 7, 8, 9, 2, 4, 7, 2};Stream stream1 = Arrays.stream(arr2);long count = stream1.distinct().count();System.out.println("count:" + count);Stream stream4 = Stream.of("Tom", ",", "Hello", " ", "Hello", "World");
// Stream count1 = stream.filter(str -> !",".equals(str) ? true : false).limit(3).skip(1).distinct();
// 中间流 可以使用连续操作---链式编程long count1 = stream4.filter(str -> !",".equals(str) ? true : false).limit(3).skip(1).distinct().count();System.out.println("count1:" + count1);System.out.println("=========sorted=============");Integer[] arr = {1, 3, 7, 8, 9, 2, 4, 7, 2};
// 使用流的操作:数组去重 按照升序进行输出Stream stream5 = Arrays.stream(arr);
// 按照升序进行输出
// stream5.distinct().sorted().forEach(t-> System.out.println(t));
// 降序进行输出stream5.distinct().sorted((a1, a2) -> a2.compareTo(a1)).forEach(t -> System.out.println(t));System.out.println("flatMap:===================");
// 需求:"e", "d", "c", "a", "f", "b"--->"edcafb"Stream stream6 = Stream.of("e", "d", "c", "a", "f", "b");stream6.flatMap(t -> Stream.of(t)).forEach(t -> System.out.print(t));System.out.println("=============================");Integer[] arr66 = {1, 3, 7, 8, 9, 2, 4, 7, 2, 60, 70};
// 分类:>=10归为一类数据 ----》999 <10归为两类----》0Stream stream66 = Arrays.stream(arr66);Stream stream661 = stream66.map(t -> t >= 10 ? 999 : 0);stream661.forEach(t -> System.out.println(t));}/*** 流操作注意事项:* Stream 自己不会存储元素----》:数据源--》转换为流* Stream 不会改变源对象。相反,他们会返回一个持有结果的新 Stream* Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行* Stream 只能被"消费"一次,一旦遍历过就会失效,就像容器的迭代器那样,想要再次遍历必须重新生成。*/@Testpublic void operation2() {Integer[] arr = {1, 3, 7, 8, 9, 2, 4, 7, 2};Stream stream = Arrays.stream(arr);/*Stream stream = Arrays.stream(arr);Stream newStream = stream.skip(2).distinct();long count = newStream.count();*/
// Stream 只能被"消费"一次,一旦遍历过就会失效stream.forEach(t -> System.out.println(t));// java.lang.IllegalStateException: stream has already been operated upon or closedlong count = stream.distinct().count();}/*** 2、流操作:* 终止操作*/@Testpublic void operation3() {// Integer[] arr = {11, 3, 17};
// Stream stream = Arrays.stream(arr);// 判断数组中至少含有一个大于10数据
// anyMatch:至少含有一个/* boolean result1 = stream.anyMatch(t -> t > 10);System.out.println("result1:"+result1);*/// 判断数组中所有的数据都大于5 true/* boolean resultALl = stream.allMatch(t -> t >5);System.out.println("resultALl:"+resultALl);*/// 求 数组中所有元素之和/* Optional reduce = stream.reduce((num1, num2) -> num1 + num2);Integer sum = reduce.get();System.out.println("sum:"+sum);*/// 求 数组中所有数据乘积/*Optional reduce2 = stream.reduce((num1, num2) -> num1 * num2);Integer result = reduce2.get();System.out.println("result:"+result);Stream streamNew = Stream.of("a", "b", "c");Optional reduce3 = streamNew.reduce((str1, str2) -> str1 + str2);String str = reduce3.get();System.out.println(str);*//* Integer[] arr1 = {1, 2, 3, 4, 5};Stream stream1 = Arrays.stream(arr1);
// 求 数组中所有奇数和Optional reduce7 = stream1.filter(t -> t % 2 != 0).reduce((a, b) -> a + b);Integer result77 = reduce7.get();System.out.println(result77);*/// System.out.println("=======collect:=流--》集合对象转换===============");/*Stream stream2 = Stream.of("e", "d", "c", "a", "f", "b"); //把流中元素收集到List list = stream2.collect(Collectors.toList()); // 调用终止操作的方法后需要重新定义Stream stream = Stream.of("e", "d", "c", "a", "f", "b"); // 把流中元素收集到Set set = stream2.collect(Collectors.toSet());stream = Stream.of("e", "d", "c", "a", "f", "b");
// 把流中元素收集到 Collection(ArrayList)
// ArrayList::new 等同于()->new ArrayList()
// ArrayList::new 可以是list,set接口下的任意实现类ArrayList alist = stream2.collect(Collectors.toCollection(ArrayList::new));System.out.println(list); // [e, d, c, a, f, b]System.out.println(set); // [a, b, c, d, e, f]System.out.println(alist); // [e, d, c, a, f, b]
*/System.out.println("====collect===Collectors:功能===============");Integer[] arr2 = {1, 2, 3, 4, 5};Stream stream1 = Arrays.stream(arr2);
// 计数/*Long count = stream1.collect(Collectors.counting());System.out.println("count:"+count);*/// 求和Integer sum = stream1.collect(Collectors.summingInt(t -> t));System.out.println("sum:"+sum);System.out.println("========================");// groupingBy: 分班 java314 精英班 成绩要求都是80分(含)以上 80分以下分数---java00Integer[] scores = {85, 90, 100, 70, 80,75};
// java314---》 85 90 100 80
// java00--->70 75Stream stream = Arrays.stream(scores);Map> map = stream.collect(Collectors.groupingBy(t -> t >= 80 ? "java314" : "java00"));map.forEach((k,v)-> System.out.println(k+"----"+v));}}
package part5;import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;/*** @author : cqq* @date : 2022/11/23 13:13*/
public class Task {public static void main(String[] args) {// 1. 给一个整数集合,分别求集合中偶数和与奇数和List list1 = new ArrayList<>();list1.add(1);list1.add(2);list1.add(3);list1.add(4);list1.add(5);list1.add(6);list1.add(7);list1.add(8);list1.add(9);list1.add(10);// list1.stream().filter(t->t%2==0).forEach(a-> System.out.println(a));Optional reduce = list1.stream().filter(t -> t % 2 == 0).reduce((x, y) -> x + y);Integer ou = reduce.get();System.out.println("ou和:"+ou);
// list1.stream().filter(t->t%2!=0).forEach(a-> System.out.println(a));Optional ji = list1.stream().filter(t -> t % 2 != 0).reduce((x, y) -> x + y);System.out.println("ji和:"+ji.get());
//
//
//
//
//System.out.println("---------------------");
// 2. 给一个整数集合,将集合分成偶数集合和奇数集合ArrayList li = new ArrayList<>();li.add(1);li.add(2);li.add(3);li.add(4);li.add(5);li.add(6);List ou1 = li.stream().filter(t->t%2==0).collect(Collectors.toList());System.out.println("ou:"+ou1);List ji1 = li.stream().filter(t->t%2!=0).collect(Collectors.toList());System.out.println("ji:"+ji1);/*// List list22 = list1.stream().filter(t -> t % 2 == 0).collect(Collectors.toList());List list66 = list1.stream().map(t -> t + "").collect(Collectors.toList());System.out.println(list66);System.out.println("---------888888888888------------");List list7 = new ArrayList<>();list7.add("hello");list7.add(2);System.out.println(list7);System.out.println("===========999999999:=============");
//
//*/
//
// 3. 集合转换:[[1, 2, 3, 4, 5], [2, 1, 9, 3, 6, 7], [3, 1, 6]] -> ["1", "2", "4", "5", "2", …… "3", "1","6"]List list4 = new ArrayList<>();List list2 = new ArrayList<>();List list3 = new ArrayList<>();Collections.addAll(list4,1,2,3,4,5);Collections.addAll(list2,3,1,6);Collections.addAll(list3,2,1,9,3,6,7);List list = new ArrayList<>();list1.stream().map(t -> list.add("“"+t+"”")).collect(Collectors.toList());list2.stream().map(t -> list.add("“"+t+"”")).collect(Collectors.toList());list3.stream().map(t -> list.add("“"+t+"”")).collect(Collectors.toList());System.out.println(list);/* List list99 = new ArrayList<>();list99.add(1);list99.add(2);list99.add(3);List list5 = new ArrayList<>();list5.add(11);list5.add(21);list5.add(31);List list88 = new ArrayList<>();list88.add(88);list88.add(99);list5.stream().map(t -> list99.add(t)).collect(Collectors.toList());System.out.println(list99);System.out.println("list................");list88.stream().map(t -> list99.add(t)).collect(Collectors.toList());System.out.println(list99);// Stream stringStream = Stream.of("e", "d", "c", "a", "f", "b");
// String st = stringStream.reduce("", (str1, str2) -> str1 = str1 + str2);
// System.out.println(st);*/}
}