函数式接口@FunctionalInterface
该注解只能标记在"有且仅有一个抽象方法"的接口上。
@FunctionalInterface标记在接口上,“函数式接口”是指仅仅只包含一个抽象方法的接口。
该注解不是必须的,如果一个接口符合"函数式接口"定义,那么加不加该注解都没有影响。加上该注解能够更好地让编译器进行检查。如果编写的不是函数式接口,但是加上了@FunctionInterface,那么编译器会报错。根据条件取数组的一个元素
public static UserType findByCode(String code) {
Optional<UserType> first = Arrays.stream(UserType.values())
.filter(item -> item.code.equals(code)).findFirst();
return first.get();
}
filter 方法用于通过设置的条件过滤出元素。根据条件判断list元素是否存在
List<User> list = getUser();
if (!CollectionUtils.isEmpty(list)) {
Optional<User> first = list.stream().filter(item -> item.getName().equals(name))
.findFirst();
return first.isPresent();
}遍历list
Set<Node> set = new HashSet<>();
List<User> list = getUser();
if (!CollectionUtils.isEmpty(list)) {
list.stream().forEach(item -> {
set.add(new Node(item.getId(), item.getName()));
});
}遍历map
map.forEach((k,v)->{
System.out.println(k+" "+v);
});匿名类
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Before Java8");
}
});
lambda:
new Thread( () -> System.out.println("In Java8, Lambda expression") );
用() -> {}代码块替代了整个匿名类。
如果我们的 Lambda 表达式需要多行代码,可以用一对打括号 {} 扩起来:
new Thread( () -> {
System.out.println("In Java8, Lambda expression");
System.out.println("In Java8, Lambda expression");
});
并行流
list.parallelStream().forEach(item -> {
System.out.println("item="+item);
});
parallelStream默认使用了fork-join框架,其默认线程数是CPU核心数减1。
ThreadPool:多见于线程并发,阻塞时延比较长的,这种线程池比较常用,一般设置的线程个数根据业务性能要求会比较多。
ForkJoinPool:特点是少量线程完成大量任务,一般用于非阻塞的,能快速处理的业务,或阻塞时延比较少的。JDK8 双冒号用法
Random random = new Random();
random.ints().limit(10).forEach(System.out::println);
jdk8中使用了::的用法。就是把方法当做参数传到stream内部,使stream的每个元素都传入到该方法里面执行一下,双冒号运算就是Java中的[方法引用],[方法引用]的格式是:
类名::方法名
注意此处没有()。
详细用法参考:
https://www.jianshu.com/p/d5d9c1ced33cmap
map 方法用于映射每个元素到对应的结果filter
filter 方法用于通过设置的条件过滤出元素limit
limit 方法用于获取指定数量的流sorted
sorted 方法用于对流进行排序Collectors
Collectors 类实现了很多归约操作,例如将流转换成集合和聚合元素统计
另外,一些产生统计结果的收集器也非常有用。它们主要用于int、double、long等基本类型上,它们可以用来产生类似如下的统计结果。
List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
IntSummaryStatistics stats = numbers.stream().mapToInt((x) -> x).summaryStatistics();
System.out.println("列表中最大的数 : " + stats.getMax());
System.out.println("列表中最小的数 : " + stats.getMin());
System.out.println("所有数之和 : " + stats.getSum());
System.out.println("平均数 : " + stats.getAverage());
- Optional
Optional仅仅是一个容器:存放T类型的值或者null。它提供了一些有用的接口来避免显式的null检查。
如果Optional实例持有一个非空值,则isPresent()方法返回true,否则返回false;orElseGet()方法,Optional实例持有null,则可以接受一个lambda表达式生成的默认值;map()方法可以将现有的Opetional实例的值转换成新的值;orElse()方法与orElseGet()方法类似,但是在持有null的时候返回传入的默认值。
示例1:
Optional< String > fullName = Optional.ofNullable( null );
System.out.println( "Full Name is set? " + fullName.isPresent() );
System.out.println( "Full Name: " + fullName.orElseGet( () -> "[none]" ) );
System.out.println( fullName.map( s -> "Hey " + s + "!" ).orElse( "Hey Stranger!" ) );
输出:
Full Name is set? false
Full Name: [none]
Hey Stranger!
示例2:
Optional< String > firstName = Optional.of( "Tom" );
System.out.println( "First Name is set? " + firstName.isPresent() );
System.out.println( "First Name: " + firstName.orElseGet( () -> "[none]" ) );
System.out.println( firstName.map( s -> "Hey " + s + "!" ).orElse( "Hey Stranger!" ) );
System.out.println();
输出:
First Name is set? true
First Name: Tom
Hey Tom!
示例3:
public class User {
private Address address;
public Optional<Address> getAddress() {
return Optional.ofNullable(address);
}
// ...
}
public class Address {
private Country country;
public Optional<Country> getCountry() {
return Optional.ofNullable(country);
}
// ...
}
String result = Optional.ofNullable(user)
.flatMap(User::getAddress)
.flatMap(Address::getCountry)
.map(Country::getIsocode)
.orElse("default");
flatMap的参数是Optional<T>,返回的也是Optional<T>;
map的参数是T,返回的是Optional<T>。