java8新特性

JAVA8 新增了很多特性,因为其简便、易懂,已经广泛用于生产环境中,为了不在工作的时候尴尬强烈建议掌握新特性。
主要有以下几点新特性:
1.Lambda表达式 2.函数式接口 3.方法引用 4.构造器引用 5.Stream API 6.Option类 7.DateTime API
本文主要对前5点进行介绍。

1.Lambda表达式

首先来看我们如果要构建一个Runnable接口的实现类会怎么做?很简单,构建一个匿名对象就可以了,匿名对象重写run方法一气呵成。

Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("hello");
            }
};

那要是想更简单的实现该怎么做呢?这就用到了Lambda表达式,先看示例。

Runnable runnable1=()->{System.out.println("hello");};

是不是有点过于简单了?初次一看,这是啥?为什么跟上面就一样了?下面来介绍一下Lambda表达式的语法:

(parameters) -> expression
或
(parameters) ->{ statements; }

()中填方法的参数,->为Lambda操作符,{}是方法体。

Lambda表达式仅可以作为函数式接口的实现类。

函数式接口:一个接口中仅包含一个方法,这样的接口就被称为函数式接口,比如Runnable接口中只有void run()方法。

现在大概懂了吧,上面的代码由Lambda表达式作为Runnable接口的实现类,所以和上面的代码是等价的。
注意Lambda表达式中的(){}以及参数类型在一定情况都是可以省略的,如参数只有一个时:

public interface Predicate<T> {
    boolean test(T t);
 }
 
Predicate<String>s= str->true; 

使用Lambda表达式时,必须非常明确这个函数式接口中的参数和返回值,这样才能写的出来。

2.方法引用

方法引用利用::操作符来指代方法,一般用于配合Lambda表达式使用。
首先看Compartor接口,仅有一个方法compare,符合函数式接口的定义,所以可以用Lambda表达式来替代接口实现类的实现

public interface Comparator<T> {  
    int compare(T o1, T o2);
}

Lambda实现:

Comparator<Integer>c2=(o1,o2)->o1-o2;

再看看Integer类中compare方法的参数:int compare(int,int),跟Comparator< Interger> 接口中的compare方法参数一样,所以可以用Integer::compare来替换Comparator接口中的compare方法,这就是方法引用。

Comparator<Integer>c=Integer::compare;

特殊情况

方法引用中存在一种特殊情况,接口方法中参数为n个,被引用的方法的类为接口方法的第一个参数,方法仅含有n-1个参数。这种情况也符合方法引用的条件,说起来很抽象,举个例子就懂了。

Compartor< String>中的compare方法: int compare(String o1, String o2);
String的CompareTo方法: public int compareTo(String anotherString);
Lambda表达式:

        Comparator<String>c=String::compareTo;

compare接口方法有2个参数,其中第一个参数为String,而compareTo(String)只有1个参数并且compareTo方法为String类的方法,正好对应接口方法的第一个参数,这样也能实现方法引用。

3.构造器引用

用类名::new来替代返回值为对象的函数式接口。
先看Supplier接口,仅有一个get方法返回对象T。

public interface Supplier<T> {
    T get();
}

如果用Lambda表示式的话:

class Employee{
    int a ;
    Employee(){}
    Employee(int a){this.a =a;}
}
Supplier<Employee>supplier=()->new Employee();
Supplier<Employee>supplier= Employee::new;

构造器引用还会自动匹配有参构造,当接口函数签名: 对象 (构造器参数…)时会自动匹配

public interface Function<T, R> {
    R apply(T t);
}
//Functon<Integer,Employee>中存在方法:Employee apply(Integer)
 Function<Integer,Employee>f =Employee::new;

4.Stream API

Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合数组运算和表达的高阶抽象。

Stream API 可以极大提高 Java 程序员的生产力,让程序员写出高效率、干净、简洁的代码。

特点

stream不存储数据,而是按照特定的规则对数据进行计算,一般会输出结果。
stream不会改变数据源,通常情况下会产生一个新的集合或一个值。
stream具有延迟执行特性,只有调用终端操作时,中间操作才会执行。

多说无益,实例演示:

先将ArrayList中加入了1、2、3共3个元素,再获取ArrayList中的流对象,通过流对象过滤得到集合中>1的元素,并将过滤结果返回成一个新的集合collect。

   ArrayList<Integer> integers = new ArrayList<>();
        integers.add(1);
        integers.add(2);
        integers.add(3);
        Stream<Integer> stream = integers.stream();
        List<Integer> collect = stream.filter(i -> i > 1).collect(Collectors.toList());

获取流的方法:

对于Collection集合:
Collection.stream()
Collection.parallelStream()
对于数组:
Arrays.stream(T array) or Stream.of()

流的操作主要分为中间操作、终止操作,中间操作有map映射、filter过滤、limit限制输出等等,终止操作有foreach遍历、match是否匹配、collect收集等等。只有经过终止操作才会得到流的结果。

中间操作 API

map: Stream map(Function<? super T, ? extends R> mapper);

将流中的元素映射(转换)成另外的元素。比如下面将students集合转换成了String集合

List<Student>students;
List<String> studentNames = students.stream().map(Student::getName)
                                             .collect(Collectors.toList());
Stream filter(Predicate<? super T> predicate);

filter过滤流中的元素,应当传入Predicate接口实现类 方法签名:boolean test(T t)

Stream distinct();

根据对象的hashCode去重

Stream sorted(Comparator<? super T> comparator);

传入Comparator接口实现类排序,也可以不传参数,需要流中的对象实现Comparator接口

ArrayList<Integer> integers = new ArrayList<>();
...
Stream<Integer> stream = integers.stream();
stream.sorted(Integer::compare);
Stream limit(long maxSize);

限制输出多少条结果

students.stream().limit(6).forEach(System.out::println);
Stream skip(long n);

跳过n个元素

终止操作 API

void forEach(Consumer<? super T> action);

遍历流,传入Consumer接口实现类void accept(T t)对流中元素进行操作,一般直接传入System.out::println打印所有元素。

stream.forEach(System.out::println);
A[] toArray(IntFunction<A[]> generator);

可以将流转换成指定的数组,传入对象[]::new

Integer[] array = stream.toArray(Integer[]::new);
max/min

传入Comparator接口实现类返回最大值、最小值,以Optional对象的方式返回,可以通过Option.get()获取。

Optional<T> min(Comparator<? super T> comparator);

Optional<T> max(Comparator<? super T> comparator);
long count()

返回流中元素数量

T reduce(T identity, BinaryOperator accumulator);

凝结、归纳流中所有元素,它需要提供一个起始值,然后按一定规则进行运算,比如相加等,它接收一个二元操作 BinaryOperator函数式接口。
重载方法:T reduce(BinaryOperator accumulator); 初始值为0
计算集合中的所有元素之和:

ArrayList<Integer> integers = new ArrayList<>();
        integers.add(1);
        integers.add(2);
        integers.add(3);
        System.out.println(integers.stream().reduce(0, (v1, v2) -> v1 + v2));
        //等价于
        System.out.println(integers.stream().reduce(Integer::sum));

anyMatch\ allMatch\ noneMatch

boolean anyMatch(Predicate<? super T> predicate);

boolean allMatch(Predicate<? super T> predicate);

boolean noneMatch(Predicate<? super T> predicate)
顾名思义,any只要存在就返回true,all所有都符合条件返回true,none都不满足返回true。

<R, A> R collect(Collector<? super T, A, R> collector);

一般用这个方法,还有个重载不常用。
将流中元素转换成集合

List<Integer> = integers.stream().collect(Collectors.toList());
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值