java8 新特性

java8 主要新特性

一、lambda表达式

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

格式:

  • lambda操作符(箭头操作符): ->
  • 操作符左边:lambda形参列表,即:接口中的抽象方法的形参列表
  • 操作符右边:方法体,即:接口抽象方法的方法体

特殊情况:

  1. lambda表达式的参数列表的参数类型可以省略(类型推断);如果只有一个参数,小括号可以省略
  2. lambda体应用大括号包起来;如果只有一条语句,大括号可以胜率(此时,如果有返回值,return必须省略)
  3. 实现的接口必须时函数式接口(接口中只有一个抽象方法)

函数式接口:

1.消费型(Consumer):传入参数无返回值

public static void main(String[] args) {
        ConsunerTest("this is ConsumerTest", new Consumer<String>() {     //原始是实现
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });

        System.out.println("-----------lambda--------------");

        ConsunerTest("this is lambda of ConsumerTest",s -> System.out.println(s));
    }

    public static void ConsunerTest(String s, Consumer<String> consumer){     //方法中使用Consumer函数式接口
        consumer.accept(s);            //函数式接口中抽象方法传入参数,无返回值
    }

2.供给型(Supplier):无传入参数,有返回值

public static void main(String[] args) {
        SupplierTest("this is ", new Supplier<String>() {     //原始是实现
            @Override
            public String get() {
                return "supplierTest";
            }
        });

        System.out.println("----------------lambda---------------");

        SupplierTest("this is lambda of", () -> "supplierTest");

    }

    public static void SupplierTest(String s, Supplier<String> supplier){    //方法中使用Supplier函数式借楼
        String s1 = supplier.get();     //获取函数式接口的方法返回值
        System.out.println(s + " " + s1);
    }

3.函数型(Function):传入T,返回R

4.断言型(Predicate):传入T,返回Boolean

public static void main(String[] args) {
        List list = new ArrayList();     
        list.add(123);
        list.add(false);
        list.add("this is PredicateTest");
        list.add(56.23);
        List<String> stringList1 = PredicateTest(list, new Predicate() {       //原始是实现
            @Override
            public boolean test(Object o) {
                if (o instanceof String) {                  //如果式字符串则返回true,否则返回false
                    return true;
                } else {
                    return false;
                }
            }
        });
        System.out.println(stringList1);

        System.out.println("---------------lambda---------------");

        List<String> stringList2 = PredicateTest(list, s -> {
            if (s instanceof String) {
                return true;
            } else {
                return false;
            }
        });
        System.out.println(stringList2);

    }

    //传入一个集合,将集合中的字符串过滤出来,并返回
    public static List<String> PredicateTest(List list, Predicate predicate){
        List<String> filter = new ArrayList<>();
        for (Object s : list) {
            if(predicate.test(s)){
                filter.add((String)s);
            }
        }
        return filter;
    }

二、方法引用

本质上式lambda表达式

使用前提:抽象方法已有lambda实现,则可以使用方法引用代替lambda;·接口中的抽象方法的形参列表和返回值类型与方法引用中的形参列表和返回值类型一致

**格式:**类或对象 ::方法名

三种情况:

  1. 对象::非静态方法

            System.out.println("----------lambda-------------");
            Consumer<String> con = s -> System.out.println(s);     //lambda中的方法实现打印
            con.accept("this is test");
            System.out.println("----------方法引用-------------");
            PrintStream ps = System.out;
            Consumer<String> con2 = ps::println;     //方法引用,前面为对象,后面为具体方法
            con2.accept("this is test2");
    
  2. 类::静态方法

      	   System.out.println("---------------lambda表达式---------------");
           Comparator<Integer> com1 = (n1,n2)->Integer.compare(n1, n2);
           System.out.println(com1.compare(15, 65));
           System.out.println("---------------方法引用--------------------");
           Comparator<Integer> com2 = Integer::compare;             //类::方法名
           System.out.println(com2.compare(66, 55));
    
  3. 类::非静态方法

    	   System.out.println("------------lambda--------------------");
            Function<Class,String> fun1 = c -> c.getName();    //传入一个参数Class类型,返回字符串类型
            System.out.println(fun1.apply("aaa".getClass()));
            System.out.println("------------方法引用--------------------");
            Function<Class,String> fun2 = Class::getName;   //传入的参数类型与lambda中的参数列表类型一致,参数作为调用方法者
            System.out.println(fun2.apply("test".getClass()));
    
    	   System.out.println("-----------------lambda-------------------------");   
            Comparator<String> com1 = (s1,s2) -> s1.compareTo(s2);           //传入两个String类型,返回int
            System.out.println(com1.compare("abc", "bcd"));
            System.out.println("-----------------方法引用-------------------------");    
            Comparator<String> com2 = String::compareTo;         //第一个参数调用方法,传入第二个参数(两个参数类型与lambda中参数列表类型一致)
            System.out.println(com2.compare("abc", "bcd"));
    

三、构造器应用

persion类

public class Persion {
    private int id;
    private String name;
    private char sex;

    public Persion() {
    }

    public Persion(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public Persion(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public char getSex() {
        return sex;
    }

    public void setSex(char sex) {
        this.sex = sex;
    }
    @Override
    public String toString() {
        return "persion{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", sex=" + sex +
                '}';
    }
}

1.无参构造器引用

	    System.out.println("-----------lambda---------");
        Supplier<Persion> s1 = () -> new Persion();      //Supplier函数式接口方法没有传入参数,有返回值;可使用无参构造器直接返回
        System.out.println(s1.get());
        System.out.println("-----------构造器引用---------");
        Supplier<Persion> s2 = Persion::new;            //构造器引用:返回类型::构造器(函数式接口中方法的传入参数列表对应构造器的参数列表)
        System.out.println(s2.get());

2.一个参数构造器引用

        System.out.println("-----------lambda---------");
        Function<String,Persion> s1 = (s) ->new Persion(s);   //Function函数式接口中方法有一个传入参数,一个返回值;可使用一个参数的构造方法
        System.out.println(s1.apply("zhangsan"));
        System.out.println("-----------构造器引用---------");
        Function<String,Persion> s2 = Persion::new;
        System.out.println(s2.apply("lisi"));

2.两个参数的构造器引用

        System.out.println("-----------lambda---------");
        BiFunction<Integer,String,Persion> s1 = (id,name) -> new Persion(id,name);
        System.out.println(s1.apply(1, "zhangsan"));
        System.out.println("-----------构造器引用---------");
        BiFunction<Integer,String,Persion> s2 = Persion::new;
        System.out.println(s2.apply(2, "lisi"));

四、Stream API

Stream关注的式对数据的运算

Stream的操作步骤:

  1. 创建Stream:(集合或数组)获取一个流
  2. 中间操作:一个中间操作,对数据源进行操作
  3. 终止操作:一旦执行终止操作,就执行中间操作链,并产生结果

创建Stream方式

    @Test
    public void test1(){
        //通过集合
        List<Persion> list = new ArrayList<>();
        Stream<Persion> stream = list.stream();    //返回一个顺序流
        Stream<Persion> persionStream = list.parallelStream();   //返回一个并行流
    }

    @Test
    public void test2(){
        //通过数组
        int [] arr = {1,2,3,4,5,6,8};
        IntStream stream = Arrays.stream(arr);     //直接使用Arrays的stream()方法,返回流
    }

    @Test
    public void test3(){
        //通过Stream的of
        Stream<Integer> integerStream = Stream.of(1, 2, 2, 3, 14);
    }

    @Test
    public void test4(){
        //创建无限流
        //使用iterate;实现从0开始,遍历偶数
        Stream.iterate(0,(t)->t+2).limit(5).forEach(System.out::println);   //参数:起始值,操作;limit为中间操作;foreach为终止操作
        //使用generate
        Stream.generate(()->Math.random()).limit(5).forEach(System.out::println);
    }

中间操作

筛选与切片

//筛选与切片
    @Test
    public void test1(){
        List<Integer> list = Arrays.asList(54, 24, 68, 87, 35, 94, 27, 54, 27);
        //1.filter过滤
        list.stream().filter((num)-> num>=50).forEach(System.out::println);   //使用filter(参数为predicate函数式接口);实现过滤数组中>=50de数
        System.out.println("************************");
        //2.limit截断
        list.stream().limit(3).forEach(System.out::println);   //通过limit截断,只显示前面的3个元素
        System.out.println("************************");
        //skip跳过,
        list.stream().skip(3).forEach(System.out::println);   //跳过前面的几个数据
        System.out.println("************************");
        //distinct筛选,根据hashcode和equals取出重复元素
        list.stream().distinct().forEach(System.out::println);
    }

映射

    //映射:通过方法将stream中的每一个元素映射到其中完成实现
    @Test
    public void test2(){
        //map
        List<Integer> list1 = Arrays.asList(1,2,3,4,5);
        list1.stream().map(num -> num+1).forEach(System.out::println);
        System.out.println("********************");
        //flatMap
    }

排序

    //排序
    @Test
    public void test1(){
        List<Integer> list = Arrays.asList(2, 5, 4, 3, 9, 7);
        List<Persion> list2 = Arrays.asList(new Persion(1, "a"), new Persion(4, "b"), new Persion(2, "c"), new Persion(3, "d"));
        //sorted()自然排序
        list.stream().sorted().forEach(System.out::println);   //将list从小到大自然排序
        list2.stream().sorted().forEach(System.out::println);     //list2根据Persion类中实现Comparable接口的方法进行排序
        System.out.println("*******************");
        //sorted(comparator com)定制排序
        list.stream().sorted((n1,n2) -> -(n1-n2)).forEach(System.out::println);   //list根据自定义方法排序
        list2.stream().sorted((p1,p2) ->-(p1.getId()-p2.getId())).forEach(System.out::println);  //根据Comparator对象实现自定义排序

    }

终止操作

匹配与查找

 		//allMatch检查是否匹配所有元素
        List<Integer> list = Arrays.asList(7, 6, 2, 3, 4, 5, 7, 9);
        boolean b = list.stream().allMatch(num -> num > 0);    //检查是否所有元素都大于0
        System.out.println(b);     //true
        //anyMatch检查是否匹配至少一个
        boolean b1 = list.stream().anyMatch(num -> num >= 9);
        System.out.println(b1);     //true
        //noneMatch检查是否没有匹配的
        boolean b2 = list.stream().noneMatch(num -> num > 10);
        System.out.println(b2);   //true
        //findFirst查找第一个元素
        Optional<Integer> first = list.stream().findFirst();
        System.out.println(first);
        //findAny查找任意元素
        Optional<Integer> any = list.parallelStream().findAny();
        System.out.println(any);
        //count查找元素个数
        long count = list.stream().filter(num -> num>5).count();   //查找大于5的元素个数
        System.out.println(count);
        //max获得最大值
        Optional<Integer> max = list.stream().max(Integer::compare);  //Comparator接口的方法引用
        System.out.println(max);
        //min获得最小值
        Optional<Integer> min = list.stream().min(Integer::compareTo);
        System.out.println(min);
        //foreach内部迭代
        list.stream().forEach(System.out::println);

归约

        //归约
        //reduce(T identity, BinaryOperator)
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        //实现计算1-10的和;identity为初始值;BinaryOperator为传入两个参数,返回一个值的函数式接口;Integer中的sum方法也是传入两个数,返回二者之和
        Integer reduce = list.stream().reduce(0, Integer::sum);
        System.out.println(reduce);

        //reduce(BinaryOperator)
        Optional<Integer> reduce1 = list.stream().reduce(Integer::sum);
        System.out.println(reduce1);

收集

        List<Integer> list = Arrays.asList(6, 5, 6, 1, 3, 7, 4, 9, 5, 2);
        List<Integer> collect = list.stream().filter(num -> num > 5).collect(Collectors.toList());  //list
        System.out.println(collect);
        Set<Integer> collect1 = list.stream().filter(num -> num > 3).collect(Collectors.toSet());    //set
        System.out.println(collect1);

五、Optional类

避免出现空指针

Optional.of(T t) optional.orElse(E e)

Optional.ofNullable(T t) optional.orElseGet(E e)

其他

Date Time API 改进

可重复注解

HashMap底层实现添加红黑树

接口添加默认方法和静态方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值