标签:适合 reg layer ali html toc let 初始化 特性
java8新特性:函数式编程,stream流,Optional 类!
参考文献:
java8 stream流操作的flatMap(流的扁平化)
标准写法
Arrays.sort(arr, (String m, String n) -> Integer.compare(m.length(), n.length()));
lambda表达式的标准写法由下面几点构成:
(Dog m, Dog n)
->
Integer.compare(m.getWeight(), n.getWeight())
参数类型可以推断
如果参数的类型可以根据上下文推断出来,则可以省略掉类型
存在多行代码
需要{} 括起来,且代码应该有明确的返回语句
Arrays.sort(arr, (String m, String n) -> {
if (m.length() > n.length())
return -1;
else
return 0;
});
单个参数并可推断类型
可以省略参数 “x” 的括号
方法引用
写成::形式,并省略参数。
stream.forEach(System.out::println);
没有参数
() -> {for(int i=0; i<10; i++) doSomthing();}
包含有可选值的包装类,既可以含有对象也可以为空。
ofNullable()
创建Optional对象:传入的对象即可能是 null 也可能是非 null,不会抛出异常NullPointerException
ifPresent()
选择性执行语句:该方法除了执行检查,还接受一个Consumer(消费者) 参数,如果对象不是空的,就对执行传入的 Lambda 表达式:
opt.ifPresent( u -> assertEquals(user.getEmail(), u.getEmail()));
这个例子中,只有 user 用户不为 null 的时候才会执行断言。
orElseGet()
返回默认值:这个方法会在有值的时候返回值,如果没有值,它会执行作为参数传入的 Supplier(供应者) 函数式接口,并将返回其执行结果:
User result = Optional.ofNullable(user).orElseGet( () -> user2);
orElse() 和 orElseGet() 的不同之处: Optional 对象返回非空值后,orElse() 方法仍然创建了 默认值 对象,而orElseGet() 方法不创建 默认值 对象。
orElseThrow()
在对象为空的时候抛出异常,而不是返回备选的值:
@Test(expected = IllegalArgumentException.class)
public void whenThrowException_thenOk() {
User result = Optional.ofNullable(user)
.orElseThrow( () -> new IllegalArgumentException());
}
这个方法让我们有更丰富的语义,可以决定抛出什么样的异常,而不总是抛出 NullPointerException。
map()
filter()
Optional 类的链式方法
String result = Optional.ofNullable(user)
.flatMap(User::getAddress)
.flatMap(Address::getCountry)
.map(Country::getIsocode)
.orElse("default");
概念
Java 8 中的 Stream 是对集合(Collection)对象功能的增强
"终端操作"&"中间操作"
终端操作: 会消费流,这种操作会产生一个结果的
iterator()、 spliterator()、min()、max()、forEach()
中间操作:会产生另一个流,类似管道
缩减操作
缩减操作的三个约束条件
reduce()-通用的方法,而min()和max(),count()这些操作称为特例缩减。
T reduce(T identity, BinaryOperator<T> accumulator);//1
Optional<T> reduce(BinaryOperator<T> accumulator);//2
第一个版本的identity为初始化值(兼容单个值的情况),求和的时候为0,求积的时候它的值为1。
其中的accumulator是一个BinaryOperator
@FunctionalInterface
public interface BinaryOperator<T> extends BiFunction<T,T,T> {
}
@FunctionalInterface
public interface BiFunction<T, U, R> {
R apply(T t, U u);//notice
}
apply()对他的两个操作数(t,u)应用到同一个函数上,并返回结果
# 直接函数式编程
reduce((a, b) -> a + b)
并行流
对流调用一下parallel(),或者Collection.parallelStream()
在reduce()的第三版本比较适合并行流,accumulator被称为累加器, combiner被称为合成器, combiner定义的函数将accumulator提到的两个值合并起来
public interface Stream<T> extends BaseStream<T, Stream<T>> {
//、、、忽略其他无关紧要的元素
<U> U reduce(U identity,
BiFunction<U, ? super T, U> accumulator,
BinaryOperator<U> combiner);
}
顺序流&并行流&无序流之间的切换操作
在使用并行流时,有时候流是无序的就能获得性能上的提升,可以通过BaseStream接口提供的unordered()方法把流转换成一个无序流之后,再进行各种操作
forEach()方法不一定会保留并行流的顺序,如果在对并行流的每个元素执行操作时,也希望保留顺序,那么可以使用forEachOrdered()方法,它的用法和forEach()是一样的。
forEach底层采用的是迭代器的方式。如果数据结构是ArrayList这种数据结构,那你可以采用for,但是你的数据结构如果是LinkList那你千万别再用for,应该果断采用forEach,因为数据一多起来的,for此时的效率低得可怜
映射
filter方法
filter方法的参数是一个Predicate
map方法
对一个流中的值进行某种形式的转换,返回的是对应类型的Stream对象。
flatMap方法
flat -- 摊平,流的扁平化
flatMap()操作能把原始流中的元素进行一对多的转换,并且将新生成的元素全都合并到它返回的流里面,即重新整合为一个流。
将多个Stream连接成一个Stream,这时候不是用新值取代Stream的值,与map有所区别,这是重新生成一个Stream对象取而代之。
String[] words = new String[]{"Hello","World"};
List<String> a = Arrays.stream(words)
.map(word -> word.split(""))
.flatMap(Arrays::stream)
.distinct()
.collect(toList());
a.forEach(System.out::print);
// 输出 ["H","e","l","o","W","r","d"]
收集功能
Collectors
类
public static <T> Collector<T, ?, List<T>> toList()
public static <T> Collector<T, ?, Set<T>> toSet()
用法:steam.collect(Collectors.toList)
collect方法
<R> R collect(Supplier<R> supplier,
BiConsumer<R, ? super T> accumulator,
BiConsumer<R, R> combiner);
类似上面的缩减操作。其中supplier指定如何创建用于保存结果的对象,比如,要使用ArrayList作为结果的集合,需要指定它的构造函数,accumulator函数是将一个元素添加到结果中,而combiner函数合并两个部分的结果
private static void learnCollect() {
List<HeroPlayerGold> lists = new ArrayList<>();
lists.add(new HeroPlayerGold("盖伦", "RNG-Letme", 100));
lists.add(new HeroPlayerGold("诸葛亮", "RNG-Xiaohu", 300));
lists.add(new HeroPlayerGold("露娜", "RNG-MLXG", 300));
lists.add(new HeroPlayerGold("狄仁杰", "RNG-UZI", 500));
lists.add(new HeroPlayerGold("牛头", "RNG-Ming", 500));
lists.stream().collect(HashSet::new,
HashSet::add,
HashSet::addAll
).forEach(System.out::println);
}
Spliterator是Java8新增的一种迭代器,Spliterator支持并行迭代。
参考:JDK 8 通过Stream 对List,Map操作和互转
list 转 map
List<Student> list = Arrays.asList(new Student(1, 18, "阿龙", GenderColumn.BOY.getCode()),
new Student(2, 17, "小花", GenderColumn.GIRL.getCode()),
new Student(3, 17, "阿浪", GenderColumn.LADYBOY.getCode()));
// value 为对象 student -> student jdk1.8返回当前对象
Map<Integer, Student> map = list.stream().collect(Collectors.toMap(Student::getId, student -> student));
map 转 map
Map<String, Map<String, Object>> map1 = aggregationMap.entrySet().stream().collect(Collectors.toMap(
e -> e.getKey(),
e -> {
List<String> options = ((StringTerms) e.getValue()).getBuckets().stream().map(StringTerms.Bucket::getKeyAsString).collect(Collectors.toList());
Map<String, Object> map = new HashMap<>();
map.put("options", options);
return map;
}
));
map 转 list
// stream map 转 list
List<Map<String, Object>> paramMapList = aggregationMap.entrySet().stream().map((e) -> {
List<String> options = ((StringTerms) e.getValue()).getBuckets().stream().map(StringTerms.Bucket::getKeyAsString).collect(Collectors.toList());
Map<String, Object> map = new HashMap<>();
map.put("k", e.getKey());
map.put("options", options);
return map;
}).collect(Collectors.toList());
标签:适合 reg layer ali html toc let 初始化 特性
原文地址:https://www.cnblogs.com/jarvankuo/p/11955011.html