Earyant的技术博客

欢迎来到Earyant的技术博客,在这里我将与你分享新技术。

java8新特性

java8新特性

lambda表达式

java8接受一个函数作为另一个函数的参数传入进去

Arrays.asList( “a”, “b”, “d” ).forEach( e -> System.out.println( e ) ); 参数的类型是编译器推断出来的

Lambda可以引用类的成员变量与局部变量(如果这些变量不是final的话,它们会被隐含的转为final,这样效率更高)。

默认方法和静态方法

在JVM中,默认方法的实现是非常高效的,并且通过字节码指令为方法调用提供了支持。默认方法允许继续使用现有的Java接口,而同时能够保障正常的编译过程。这方面好的例子是大量的方法被添加到java.util.Collection接口中去:stream(),parallelStream(),forEach(),removeIf(),……

重复注解

Java编译器的新特性

1
2
3
4
5
6
7
8
public class ParameterNames {
public static void main(String[] args) throws Exception {
Method method = ParameterNames.class.getMethod( "main", String[].class );
for( final Parameter parameter: method.getParameters() ) {
System.out.println( "Parameter: " + parameter.getName() );
}
}
}

Parameter: args

对于有经验的Maven用户,通过maven-compiler-plugin的配置可以将-parameters参数添加到编译器中去。

1
2
3
4
5
6
7
8
9
10
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<compilerArgument>-parameters</compilerArgument>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>

Java 类库的新特性

Optional

平时用的判空:

1
2
3
4
5
6
7
public void get(String name){
if (name == null){
return "";
}else{
return name;
}
}

改成Optional:

1
2
3
4
5
6
7
8
public void get(String name){
Optional<String > names = Opntional.of(name);
if (names.isPresent()){
return names.get();
}else{
return "";
}
}

如果单纯改成这样,还不如直接写成 ==null,看起来更加繁琐。 应该改成这样:

1
2
3
4
public void get(String name){
return Opntional.of(name).get().orElse("");

}

Stream

1
2
3
4
5
final long totalPointsOfOpenTasks = tasks
.stream()
.filter( task -> task.getStatus() == Status.OPEN )
.mapToInt( Task::getPoints )
.sum();

filter

对于Stream中包含的元素使用给定的过滤函数进行过滤操作,新生成的Stream只包含符合条件的元素;

map

映射转换

mapTo*

映射转换成 的类型, 包括Integer、Double、Long

flatMap

合并集合,和map类似,不同的是其每个元素转换得到的是Stream对象,会把子Stream中的元素压缩到父集合中;

1
2
3
{{1,2},{3,4},{5,6}} - > flatMap - > {1,2,3,4,5,6}

{'a','b'},{'c','d'},{'e','f'}} - > flatMap - > {'a','b','c' D", 'E', 'F'}

flatMapTo*

distinct

对于Stream中包含的元素进行去重操作(去重逻辑依赖元素的equals方法),新生成的Stream中没有重复的元素;

sorted

peek

监控器

提供一个Consumer消费函数,返回一个新的Stream,如果只写 Stream.of(“1”,”2”,”3”).peek(e-> System.out.Println(e)) 是不会打印结果的 新Stream每个元素被消费的时候都会执行给定的消费函数; Stream.of(“1”,”2”,”3”).peek(e-> System.out.Println(e)).collect(Collectors.toList());

limit

对一个Stream进行截断操作,获取其前N个元素,如果原Stream中包含的元素个数小于N,那就获取其所有的元素;

skip

返回一个丢弃原Stream的前N个元素后剩下元素组成的新Stream,如果原Stream中包含的元素个数小于N,那么返回空Stream;

forEach

遍历

forEachOrdered

与forEach一样,只不过每次遍历结果都是相同的,forEach不是固定的序列

generate

给定一个生成函数,生成一个无限的队列 Stream.generate(Math::random);

iterate

也是生成无限长度的Stream,和generator不同的是,其元素的生成是重复对给定的种子值(seed)调用用户指定函数来生成的。其中包含的元素可以认为是:seed,f(seed),f(f(seed))无限循环

Stream.iterate(1, item -> item + 1).limit(10).forEach(System.out::println);

collect

汇聚函数

方法参数 返回类型 作用 示例
toList List<T > 把流中的参数汇聚成List集合 示例:List<Menu> menus=Menu.getMenus.stream().collect(Collectors.toList())
toSet Set<T> 把流中所有元素收集到Set中,删除重复项 Set<Menu> menus=Menu.getMenus.stream().collect(Collectors.toSet())
toCollection Collection<T> 把流中所有元素收集到给定的供应源创建的集合中 ArrayList<Menu> menus=Menu.getMenus.stream().collect(Collectors.toCollection(ArrayList::new))
Counting Long 计算流中元素个数 Long count=Menu.getMenus.stream().collect(Collectors.counting());
SummingInt Integer 对流中元素的一个整数属性求和 Integer count=Menu.getMenus.stream().collect(Collectors.summingInt(Menu::getCalories))
averagingInt Double 计算流中元素integer属性的平均值 Double averaging=Menu.getMenus.stream().collect((Collectors.averagingInt(Menu::getCalories))
Joining String 连接流中每个元素的toString方法生成的字符串 String name=Menu.getMenus.stream().map(Menu::getName).collect(Collectors.joining(“, “))
maxBy Optional<T> 一个包裹了流中按照给定比较器选出的最大元素的optional 如果为空返回的是Optional.empty() Optional<Menu> fattest=Menu.getMenus.stream().collectCollectors.maxBy(Menu::getCalories))
minBy Optional<T> 一个包裹了流中按照给定比较器选出的最大元素的optional如果为空返回的是Optional.empty() Optional<Menu> lessest=Menu.getMenus.stream().collect(minBy(Menu::getCalories))
Reducing 归约操作产生的类型 从一个作为累加器的初始值开始,利用binaryOperator与流中的元素逐个结合,从而将流归约为单个值 int count=Menu.getMenus.stream().collect(reducing(0,Menu::getCalories,Integer::sum));
collectingAndThen 转换函数返回的类型 包裹另一个转换器,对其结果应用转换函数 Int count=Menu.getMenus.stream().collect(collectingAndThen(toList(),List::size))
groupingBy Map<K,List<T>> 根据流中元素的某个值对流中的元素进行分组,并将属性值做为结果map的键 Map<Type,List<Menu>> menuType=Menu.getMenus.stream().collect(groupingby(Menu::getType))
partitioningBy Map<Boolean,List<T>> 根据流中每个元素应用谓语的结果来对项目进行分区 Map<Boolean,List<Menu>> menuType=Menu.getMenus.stream().collect(partitioningBy(Menu::isType));

reduce

  • Optional<t> reduce(BinaryOperator<t> accumulator);

List <integer> ints = Lists.newArrayList(1,2,3,4,5,6,7,8,9,10); System.out.println(“ints sum is:” + ints.stream().reduce((sum, item) -> sum + item).get());

可以看到reduce方法接受一个函数,这个函数有两个参数,第一个参数是上次函数执行的返回值(也称为中间结果),第二个参数是stream中的元素,这个函数把这两个值相加,得到的和会被赋值给下次执行这个函数的第一个参数。要注意的是:第一次执行的时候第一个参数的值是Stream的第一个元素,第二个参数是Stream的第二个元素。这个方法返回值类型是Optional,这是Java8防止出现NPE的一种可行方法,后面的文章会详细介绍,这里就简单的认为是一个容器,其中可能会包含0个或者1个对象。

  • T reduce(T identity, BinaryOperator<t> accumulator);
    这个定义上上面已经介绍过的基本一致,不同的是:它允许用户提供一个循环计算的初始值,如果Stream为空,就直接返回该值。而且这个方法不会返回Optional,因为其不会出现null值。

count

个数

allMatch

是不是所有都满足给定的条件

anyMatch

是不是存在某一个元素满足给定的条件

findFirst

返回第一个,返回的是Optional值

noneMatch

是否没有一个元素满足给定的条件

max和min

给定的比较条件,返回最大最小值

参考
好文收藏

欢迎关注我的其它发布渠道