目录
在Lamda新特性的支持下,JAVA8中可以使用lamda表达式来创建匿名方法。然而,有时候我们仅仅是需要调用一个已存在的方法(如java中已经定义好的方法),在这时候java8新特性“方法引用”将会进一步简化操作(注意:需要有Lamda的支持)。
• 定义一个方法获取供给型接口类型的参数,调用 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;
- }
-
-
- @Override
- public 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<Person> supplier = Person::new;
- Person person = supplier.get();
- System.out.println(person);
-
-
- // 2) 引用静态方法-->类名称::static 方法名称;
- Supplier<Integer> method1 = Person::method1;
- Integer result = method1.get();
- System.out.println("result:"+result);
-
- System.out.println("==================");
- // 调用静态方法时:选定和这个静态方法相匹配的功能性函数(是否匹配:是否有参数 是否有返回值--》使用哪个功能性函数)
- Function<Integer,Integer> function = Person::method2;
- Integer apply = function.apply(66);
- System.out.println("applay:"+apply);
-
- System.out.println("==================");
- // 3)引用某个对象的实例的普通方法-->实例化对象::普通方法;
- Person person1 = new Person("tidy",18);
- Supplier<String> stringSupplier =person1::getName;
- String name = stringSupplier.get();
- System.out.println("name:"+name);
-
-
- // 4)引用特定类型的任意对象的实例方法-->特定类::普通方法;
- // String equals方法 比较两个字符串是否相等 2个字符串
- // BiFunction
- BiFunction<String,String,Boolean> biFunction = String::equals;
- Boolean resultFlg = biFunction.apply("hello", "hello");
- System.out.println("resultFlg:"+resultFlg);
-
- System.out.println("6666666666666666666:");
- List<Integer> list = new ArrayList();
- list.add(10);
- list.add(30);
- list.add(30);
- // 内部类
- /* Consumer<Integer> consumer = new Consumer<Integer>() {
- @Override
- public void accept(Integer integer) {
- System.out.println(integer);
- }
- };
- list.forEach(consumer);*/
- /*list.forEach(new Consumer<Integer>() {
- @Override
- public 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流对象
- */
- @Test
- public void createStream() {
-
- // list1数据源
- List<Integer> list1 = new ArrayList<>();
- list1.add(10);
- list1.add(30);
- list1.add(20);
-
- // 1)集合对象中 stream()
- Stream<Integer> stream = list1.stream();
- stream.forEach(t -> System.out.println(t));
-
- // 2)集合中方式2
- Stream<Integer> stream2 = list1.parallelStream();
- stream2.forEach(t -> System.out.println(t));
-
- // 3)数组数据源--》Stream
- Integer[] arr = {1, 3, 5, 7};
- Stream<Integer> stream3 = Arrays.stream(arr);
-
-
- // 4)Stream中的of方法
- Stream<Integer> 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<Integer> stream5 = Stream.iterate(0, t -> t + 2);
-
-
- // limit(3) 获取前3个数据
- Stream<Integer> 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<Double> generate = Stream.generate(Math::random);
- Stream<Double> stream7 = Stream.generate(Math::random).limit(2);
- stream7.forEach(t -> System.out.println(t));
- // stream7.forEach(System.out::println);
-
-
- }
-
-
- /**
- * 2、流操作:
- * 中间操作
- */
- @Test
- public void operation() {
- Stream<String> stream = Stream.of("Tom", ",", "Hello", " ", "Hello", "World");
-
- // 1)中间操作-->新Stream流
- // filter:过滤流 返回true条件都会添加到这个新流当中
- Stream<String> newStream = stream.filter(str -> {
- if (",".equals(str)) {
- return false;
- } else {
- return true;
- }
- });
-
- newStream.forEach(t -> System.out.println(t));
-
- System.out.println("---------------------------");
-
- Stream<String> stream2 = Stream.of("Tom", ",", "Hello", " ", "Hello", "World");
-
- // 中间操作--limit 获取前X个数据
- Stream<String> newStream2 = stream2.limit(2);
-
- newStream2.forEach(t -> System.out.println(t));
-
-
- System.out.println("------1111111111----------------------------");
- Stream<String> stream3 = Stream.of("Tom", ",", "Hello", " ", "Hello", "World");
-
- // 中间操作---skip跳过前多少个数据
- Stream<String> streamNew = stream3.skip(2);
- streamNew.forEach(t -> System.out.println(t));
-
- System.out.println("----distict:-----------------------------");
- Stream<Integer> streamDistinct = Stream.of(10, 20, 30, 10, 5);
- // 中间操作去重--distinct
- Stream<Integer> 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<Integer> stream1 = Arrays.stream(arr2);
- long count = stream1.distinct().count();
- System.out.println("count:" + count);
-
-
- Stream<String> stream4 = Stream.of("Tom", ",", "Hello", " ", "Hello", "World");
- // Stream<String> 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<Integer> 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<String> 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归为两类----》0
- Stream<Integer> stream66 = Arrays.stream(arr66);
- Stream<Integer> stream661 = stream66.map(t -> t >= 10 ? 999 : 0);
- stream661.forEach(t -> System.out.println(t));
-
- }
-
-
- /**
- * 流操作注意事项:
- * Stream 自己不会存储元素----》:数据源--》转换为流
- * Stream 不会改变源对象。相反,他们会返回一个持有结果的新 Stream
- * Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行
- * Stream 只能被"消费"一次,一旦遍历过就会失效,就像容器的迭代器那样,想要再次遍历必须重新生成。
- */
- @Test
- public void operation2() {
- Integer[] arr = {1, 3, 7, 8, 9, 2, 4, 7, 2};
- Stream<Integer> stream = Arrays.stream(arr);
- /*Stream<Integer> stream = Arrays.stream(arr);
-
- Stream<Integer> 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 closed
- long count = stream.distinct().count();
-
-
- }
-
-
- /**
- * 2、流操作:
- * 终止操作
- */
- @Test
- public void operation3() {
-
- // Integer[] arr = {11, 3, 17};
- // Stream<Integer> 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<Integer> reduce = stream.reduce((num1, num2) -> num1 + num2);
- Integer sum = reduce.get();
- System.out.println("sum:"+sum);*/
-
-
- // 求 数组中所有数据乘积
- /*Optional<Integer> reduce2 = stream.reduce((num1, num2) -> num1 * num2);
- Integer result = reduce2.get();
- System.out.println("result:"+result);
-
- Stream<String> streamNew = Stream.of("a", "b", "c");
-
- Optional<String> reduce3 = streamNew.reduce((str1, str2) -> str1 + str2);
- String str = reduce3.get();
- System.out.println(str);*/
-
- /* Integer[] arr1 = {1, 2, 3, 4, 5};
- Stream<Integer> stream1 = Arrays.stream(arr1);
- // 求 数组中所有奇数和
- Optional<Integer> 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<String> stream2 = Stream.of("e", "d", "c", "a", "f", "b"); //把流中元素收集到
-
-
- List<String> list = stream2.collect(Collectors.toList()); // 调用终止操作的方法后需要重新定义
-
-
- Stream stream = Stream.of("e", "d", "c", "a", "f", "b"); // 把流中元素收集到
-
- Set<String> 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<String> 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<Integer> 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分以下分数---java00
- Integer[] scores = {85, 90, 100, 70, 80,75};
- // java314---》 85 90 100 80
- // java00--->70 75
-
- Stream<Integer> stream = Arrays.stream(scores);
- Map<String, List<Integer>> 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<Integer> 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<Integer> 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<Integer> ji = list1.stream().filter(t -> t % 2 != 0).reduce((x, y) -> x + y);
- System.out.println("ji和:"+ji.get());
- //
- //
- //
- //
- //
- System.out.println("---------------------");
- // 2. 给一个整数集合,将集合分成偶数集合和奇数集合
- ArrayList<Integer> li = new ArrayList<>();
- li.add(1);
- li.add(2);
- li.add(3);
- li.add(4);
- li.add(5);
- li.add(6);
- List<Integer> ou1 = li.stream().filter(t->t%2==0).collect(Collectors.toList());
- System.out.println("ou:"+ou1);
- List<Integer> ji1 = li.stream().filter(t->t%2!=0).collect(Collectors.toList());
- System.out.println("ji:"+ji1);
-
-
-
- /*// List<Integer> list22 = list1.stream().filter(t -> t % 2 == 0).collect(Collectors.toList());
- List<String> 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<Integer> list4 = new ArrayList<>();
- List<Integer> list2 = new ArrayList<>();
- List<Integer> 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<String> 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<Integer> list99 = new ArrayList<>();
- list99.add(1);
- list99.add(2);
- list99.add(3);
-
- List<Integer> list5 = new ArrayList<>();
- list5.add(11);
- list5.add(21);
- list5.add(31);
-
- List<Integer> 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<String> stringStream = Stream.of("e", "d", "c", "a", "f", "b");
- // String st = stringStream.reduce("", (str1, str2) -> str1 = str1 + str2);
- // System.out.println(st);*/
-
-
- }
- }