java8新特性之方法引用与构造器引用+Stream
程序员文章站
2022-03-10 16:22:13
...
方法引用与构造器引用
* 若Lambda体中的内容有方法已经实现了,则可以使用"方法引用"
* 是Lambda另一种表现形式
* 三种语法格式:
* 对象::实例方法名
* 类::静态方法名
* 类::实例方法名
*
* 前提,接口中的抽象方法参数列表和返回值类型必须和方法引用的参数列表返回值类型保持一致
* 若Lambda参数列表中的第一个参数是实例方法的调用者,而第二个参数是实例方法的参数时可以使用ClassName::method
*/
@Test
public void test1(){
// 对象::实例方法名
PrintStream ps = System.out;
Consumer<String> con = (x) -> ps.println(x);
PrintStream ps1 = System.out;
Consumer<String> con1 = ps1::println;
Consumer<String> con2 = System.out::println;
con2.accept("java8 so tm easy");
}
@Test
public void test2(){
TMsAj aj = new TMsAj("1111","民再12号",2,65);
//原写法
Supplier<String> sup = ()->aj.getCah();
System.out.println(sup.get());
System.out.println("========================");
//改写
Supplier<Integer> sup2 = aj::getNdsrsl;
System.out.println(sup2.get());
}
//类::静态方法名
@Test
public void test3(){
Comparator<Integer> comparator1 = (x, y) -> Integer.compare(x,y);
Comparator<Integer> comparator2 = Integer::compare;
}
//类::实例方法名
@Test
public void test4(){
BiPredicate<String,String> biPredicate1 = (x,y) -> x.equals(y);
BiPredicate<String,String> biPredicate2 = String::equals;
}
/**
* 构造器引用
*/
@Test
public void test5(){
Supplier<TMsAj> aj = ()->new TMsAj();
//构造器引用
Supplier<TMsAj> aj2 = TMsAj::new;
//由于参数列表和返回值的限制,得到的一定是无参构造器
System.out.println(aj2.get());
}
@Test
public void test6(){
Function<String,TMsAj> function1 = (x)->new TMsAj(x);
//构造器引用
Function<String,TMsAj> function2 = TMsAj::new;
System.out.println(function2.apply("108754"));
}
/**
* 数组引用
* Type[]::new;
*/
@Test
public void test7(){
Function<Integer,String[]> function = (x)->new String[x];
String[] strs = function.apply(10);
System.out.println(strs.length);
System.out.println("=============================");
Function<Integer,String[]> function2 = String[]::new;
String[] strs2 = function2.apply(20);
System.out.println(strs2.length);
}
强大的StreamAPI
Java8有两个最重要的改变,第一个是Lambda表达式,另一个就是Stream API。
Stream是java8中处理集合的关键抽象概念,它可以指定你希望的对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作,使用StreamAPI 对几何数据进行操作,酒类始于使用SQL执行的数据库查询,也可以使用StreamAPI来并行执行操作,简而言之,StreamAPI提供了一种高效且易于使用的处理数据的方式。
到底Stream流是什么呢?
是数据的渠道,用于操作数据源(集合、数组等)所生成的元素序列。
“集合讲的是数据,流讲的是计算”
注意:
1.Stream自己不会存储数据
2.不会改变源对象,而是返回一个持有结果的新Stream
3.操作是延迟执行的,意味着他们会等到需要结果的时候才执行(懒加载、惰性求值)
Stream操作只有三步!
- 把冰箱门打开:创建Stream
- 把大象放冰箱里:中间操作,对源数据进行处理
- 把冰箱门关上:终止操作,执行中间操作链,产生结果
语法
创建流Stream
@Test
public void test1(){
/**
* 创建流
*/
//1.可以通过Collection系列集合提供的stream()或 parallelStream() (串行流和并行流)
List<String> list = new ArrayList<>();
Stream<String> stream1 = list.stream();
//2.通过Arrays中静态方法stream()获取数据流
TMsAj[] ajs = new TMsAj[10];
Stream<TMsAj> stream2 = Arrays.stream(ajs);
//3.通过Stream类中的静态方法of()
Stream<String> stream3 = Stream.of("aa","bb","cc");
//4.创建无限流
//迭代
Stream<Integer> stream4 = Stream.iterate(0,(x) -> x+2);
stream4.forEach(System.out::println);
stream4.limit(10).forEach(System.out::println);
//生成
Stream.generate(()->Math.random()).limit(5).forEach(System.out::println);
中间操作--筛选与切片
/**
* filter——接收Lambda,从流中排除某些元素
* limit——截断
* skip(n)——跳过,扔掉前n个,若不足n个会返回空流
* distinct——筛选,通过流所产生的元素的hashCode()和equals()去重(实体类中重写hashcode和equals)
*
* 内部迭代:由Stream API完成迭代操作
* 外部迭代:Iterator迭代器,自行迭代
*/
List<TMsAj> ajs = Arrays.asList(
new TMsAj("1001","民初1号", 1,11.11),
new TMsAj("1002","民初2号", 2,22.22),
new TMsAj("1003","民初3号", 3,33.33),
new TMsAj("1004","民初4号", 4,44.44),
new TMsAj("1005","民初5号", 5,55.55),
new TMsAj("1006","民初6号", 6,66.66)
);
@Test
public void test1(){
Stream<TMsAj> stream = ajs.stream().filter((e)-> {
System.out.println("中间操作");
return e.getNdsrsl()>4;
});
stream.forEach(System.out::println);
ajs.stream().filter((e)-> e.getNdsrsl()>4).forEach(System.out::println);
//中间操作不会执行任何操作,中只操作一次性执行全部内容
}
中间操作——映射
/**
* 映射
* map——接收Lambda,将元素转换成其他形式或提取新信息。接收一个函数作为参数,
* 该函数会被应用到每个元素上,并将其映射成一个新的元素
*
* flatMap——接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有的流连接成一个流
*/
List<TMsAj> ajs = Arrays.asList(
new TMsAj("1001","民初1号", 1,11.11),
new TMsAj("1002","民初2号", 2,22.22),
new TMsAj("1003","民初3号", 3,33.33),
new TMsAj("1004","民初4号", 4,44.44),
new TMsAj("1005","民初5号", 5,55.55),
new TMsAj("1006","民初6号", 6,66.66)
);
/**
* map
*/
@Test
public void test1(){
List<String> list = Arrays.asList("aaa","bbb","ccc","ddd","eee");
list.stream().map((str)->str.toUpperCase())
.forEach(System.out::println);
System.out.println("=====================================");
ajs.stream().map(e->e.getNdsrsl()).forEach(System.out::println);
// Stream<Stream<Character>> stream = list.stream().map(TestStreamAPI3::filterCharacher);
// stream.forEach((sm)->sm.forEach(System.out::println));
/**
* flatMap(压平)
* 和map的关系可以类比一下集合的add(ele)和addAll(List<ele>)方法
*/
Stream<Character> sm = list.stream().flatMap(e->TestStreamAPI3.filterCharacher(e));
sm.distinct().forEach(System.out::println);
}
public static Stream<Character> filterCharacher(String str){
List<Character> list = new ArrayList<>();
for(Character ch:str.toCharArray()){
list.add(ch);
}
return list.stream();
}
/**
* 排序 sorted
*/
public void test2() {
List<String> list = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee");
list.stream().sorted().forEach(System.out::println);
System.out.println("-------------------------------------------");
ajs.stream().sorted((x, y) -> {
if (x.getCbhaj().equals(y.getCbhaj())) {
return x.getCah().compareTo(y.getCah());
} else {
return x.getCbhaj().compareTo(y.getCbhaj());
}
}).forEach(System.out::println);
}
中止操作
package com.com.thunisoft.java8.TestStream;
import com.com.thunisoft.java8.TestLambda2.TMsAj;
import org.junit.Test;
import java.util.*;
import java.util.stream.Collectors;
/**
* 终止操作
*/
public class TestStreamAPI4 {
/**
* 查找与匹配
* allMatch--检查是否匹配所有元素
* anyMatch--检查是否至少匹配一个元素
* noneMatch--检查是否没有匹配所有元素
* findAny--返回当前流中的任意元素
* count--返回流中元素的总个数
* max--返回流中的最大元素
* min--返回流中的是最小元素
*/
List<TMsAj> ajs = Arrays.asList(
new TMsAj("1001","民初1号", 1,11.11),
new TMsAj("1002","民初2号", 2,22.22),
new TMsAj("1003","民初3号", 3,33.33),
new TMsAj("1004","民初4号", 4,44.44),
new TMsAj("1005","民初5号", 5,55.55),
new TMsAj("1006","民初6号", 6,66.66)
);
@Test
public void test1(){
boolean b1 = ajs.stream().allMatch(e->e.getNdsrsl()==1);
System.out.println(b1);
boolean b2 = ajs.stream().anyMatch(e->e.getNdsrsl()==1);
System.out.println(b2);
//一旦有可能为空,把返回值封装到了optional中
Optional<TMsAj> op = ajs.stream().sorted((x, y) -> Double.compare(x.getScore(), y.getScore())).findFirst();
System.out.println(op.get());
//串行流
Optional<TMsAj> any = ajs.stream().filter(e->e.getScore() > 40).findAny();
System.out.println(any.get());
//并行流
Optional<TMsAj> any2 = ajs.parallelStream().filter(e->e.getScore() > 20).findAny();
System.out.println(any2.get());
}
@Test
public void test2(){
Long count = ajs.stream().count();
System.out.println(count);
Optional<TMsAj> op1 = ajs.stream().max((x, y) -> Double.compare(x.getScore(), y.getScore()));
System.out.println(op1.get());
//提取最高评分是多少
Optional<Double> op2 = ajs.stream().map(x -> x.getScore()).max((x, y) -> Double.compare(x, y));
System.out.println(op2.get());
}
/**
* 归约
* reduce(T indentity,BinaryOperator) / reduce(BinaryOpterator)
* 将流中元素反复结合,得到一个值
*/
@Test
public void test3(){
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
Integer res = list.stream().reduce(0, (x, y) -> x + y);
System.out.println(res);
//算一下总共有多少个当事人
Optional<Integer> reduce = ajs.stream().map(TMsAj::getNdsrsl).reduce(Integer::sum);
System.out.println(reduce.get());
}
/**
* 收集
* collect
*/
@Test
public void test4(){
List<String> list = ajs.stream().map(a -> a.getCah()).collect(Collectors.toList());
list.forEach(System.out::println);
System.out.println("---------------------------------");
Set<String> set = ajs.stream().map(a -> a.getCah()).collect(Collectors.toSet());
set.forEach(System.out::println);
System.out.println("----------------------------------");
//特殊集合
HashSet<Double> hashSet = ajs.stream().map(TMsAj::getScore).collect(Collectors.toCollection(HashSet::new));
hashSet.forEach(System.out::println);
System.out.println("----------------------------------");
//求总数
Long count = ajs.stream().collect(Collectors.counting());
System.out.println(count);
System.out.println("----------------------------------");
//求平均值
Double avg = ajs.stream().collect(Collectors.averagingDouble(e->e.getScore()));
System.out.println(avg);
System.out.println("----------------------------------");
//求总和
Double sum = ajs.stream().collect(Collectors.summingDouble(TMsAj::getScore));
System.out.println(sum);
//最大值,最小值(minBy)
Optional<TMsAj> max = ajs.stream().collect(Collectors.maxBy((x, y) -> Double.compare(x.getScore(), y.getScore())));
System.out.println(max.get());
}
//分组
@Test
public void test6(){
Map<Boolean, List<TMsAj>> group1 = ajs.stream().collect(Collectors.groupingBy(e -> e.getScore() > 30));
//map不能forearch
System.out.println(group1);
}
//多级分组
@Test
public void test7(){
Map<Integer, Map<String, List<TMsAj>>> collect = ajs.stream().collect(Collectors.groupingBy(TMsAj::getNdsrsl, Collectors.groupingBy(e -> {
if (e.getScore() > 30) {
return "繁案";
} else {
return "简案";
}
})));
System.out.println(collect);
}
//分区
@Test
public void test8(){
Map<Boolean, List<TMsAj>> map = ajs.stream().collect(Collectors.partitioningBy(e -> e.getScore() > 30));
System.out.println(map);
}
@Test
public void test9(){
DoubleSummaryStatistics collect = ajs.stream().collect(Collectors.summarizingDouble(TMsAj::getScore));
System.out.println(collect.getMax());
System.out.println(collect.getAverage());
System.out.println(collect.getCount());
System.out.println(collect.getSum());
}
@Test//连接字符串
public void test10(){
String str = ajs.stream().map(TMsAj::getCah).collect(Collectors.joining(",","--","=="));
System.out.println(str);
}
}
上一篇: mplayer解码库的移植
推荐阅读
-
【java新特性】之方法引用与Lambda表达式
-
java8新特性之方法引用示例代码
-
Java8新特性:Lambda表达式之方法引用详解
-
java8新特性(方法引用和构造器引用)
-
【java新特性】之方法引用与Lambda表达式
-
Java8新特性整理之方法引用(二)
-
Java8新特性-004-方法、构造器、数组引用
-
Java8新特性——————Lambda表达式,函数式(Functional)接口,方法引用与构造器引用
-
【Java 20】Java8的其他新特性 - Lambda表达式、函数式接口、方法引用、构造器引用、数组引用、Stream API、Optional类
-
快速学习Java8新特性第四讲——方法引用与构造器引用