java之JDK8的新特性

JDK8新特性

     速度快,代码少(Lambda表达式)强大的Stream API 便于并行 最大化减少空指针异常       

     Nashorm引擎,允许在JVM上运行JS应用

并行流与串行流

Lambda表达式

        概述:就是匿名函数

        基本语法:(参数列表) —>{方法体}

 @Test
    public void test2(){
        Comparator com = new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                return Integer.compare((Integer) o1,(Integer) o2);
            }
        };
        System.out.println(com.compare(12, 24));

        Comparator<Integer> com1 = ((o1, o2) -> Integer.compare(o1,o2));//Lambda表达式
        System.out.println(com1.compare(30, 24));

        System.out.println("----------------");
        Comparator<Integer> com2 = Integer::compare;//方法引用
        System.out.println(com2.compare(22, 22));

    }

 Lambda:

* 举例:(o1,o2) -> Integer.compare(o1,o2);
* 格式:
*    ->:箭头操作符       左边:形参列表(接口中抽象方法得的形参列表)
*                                 右边:Lambda体,其实就是重写的抽象方法的方法体
* 使用情况:以下有六种情况
* 总结:    左边:参数类型可以省略。如果参数只有一个,其中的小括号可以省
*                右边:使用大括号,如果只有一个执行语句,则【{}和return】可以省略不写
* Lambda表达式本质:作为接口的实例【只有一个抽象方法】
*                   接口的要求:函数式接口
 

    //1  无参无返回值
    @Test
    public void test1(){
        Runnable r2 = () -> {
            System.out.println("Lambda");
            System.out.println("无参无返回值");
        };
        r2.run();
    }
    //2  有参无返回值
    @Test
    public void test2(){

        Consumer<String> con = new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println("I like "+s);
            }
        };
        con.accept("basketball");

        Consumer<String> con2 = System.out::println;
        con2.accept("124");
        Consumer<String> con1 = (String s) -> { System.out.println("I like "+s);};
        con1.accept("basketball");

    }
    //3  数据类型可以省略,因为可以由编译器推断出,称为“类型推断”
    @Test
    public void test3(){
        Consumer<String> con1 = (s) -> { System.out.println("I like "+s);};
        con1.accept("basketball");
    }
    //4   只有一个参数,参数的括号可以省略
    @Test
    public void test4(){
        Consumer<String> con1 = s -> { System.out.println("I like "+s);};
        con1.accept("basketball");
    }
    //5   有多个参数,多条执行语句,并且可以有返回值
    @Test
    public void test5(){
        Comparator<Integer> com = (o1, o2) -> {
            System.out.println(o1+" "+o2);
            return Integer.compare(o1,o2);
        };
        System.out.println(com.compare(12, 24));
    }
    //6  只有一条执行语句,return与大括号有,都可以省略
    @Test
    public void test6(){
        Comparator<Integer> com = (o1, o2) ->  Integer.compare(o1,o2);
        System.out.println(com.compare(12, 24));
    }

Lambda表达式类型推断

 函数式接口---》只包含一个抽象方法的接口

使用@FunctionInterface注解判断是否是函数时接口

 函数式接口

 

  Lambda之 方法引用

 

 

 

 Stream

创建Stream

/**
 * StreamAPI的使用
 *    //非关系型数据库就需要在java层面对数据进行删选 Radis MongDB
 *    Stream与Collection的区别:Collection是一种静态的内存数据结构  面向内存
 *                             Stream是有关计算的  面向cpu  1不会存储数据 2不会改对象 3返回一个新对象  4操作是延迟的
 *    1 创建Stream对象
 *    2 中间操作
 *    3 终止操作(只有调用终止操作,前面中间操作的才会顺序执行且不可逆)
 *
 * @author FuQingsong
 * @create 2023-03-04-21:19
 */
public class StreamCreateTest {
    @Test
    public void test1(){
        //1创建Stream对象(可以通过集合、数组)
        List<Person> p = new ArrayList<>();
        p.add(new Person(12,124));
        p.add(new Person(11,14));
        p.add(new Person(52,24));
        p.add(new Person(12,1244));
        p.add(new Person(1142,1244));

        Stream<Person> stream = p.stream();// default Stream<E> stream():返回一个顺序流

        Stream<Person> stream1 = p.parallelStream();//获取一个并行流

        //2通过数组创建
        int[] arr = new int[]{2,3,5,9,1};
        IntStream stream2 = Arrays.stream(arr);//  注意基本数据类型数组的InStream

        //3Stream.of()  它就是和集合打交道的
        Stream<Integer> integerStream = Stream.of(1, 3, 4, 5, 6, 2);



        //4创建无线流
        // public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f)
        //遍历前十个偶数
        Stream.iterate(0,t->t+2).limit(10).forEach(System.out::println);
        // public static<T> Stream<T> generate(Supplier<T> s)
        Stream.generate(Math::random).limit(10).forEach(System.out::println);
    }

}

中间操作

public class StreamMIddleTest {
    /*
      筛选与切片
      filter(Predicate p)  接收lambda,从流中排除某些元素
      distinct()           筛选重复的元素,hashcode与equals【自定义的类需要重写】
      limit(long maxSize)   截断流 使其中元素不超过给定的数量
      skip(long n)         跳过n个元素,返回一个人扔掉了前n个元素的流,如果流中元素不足n个,则返回一个空流,与limit()互补
     */
    @Test
    public void test1(){

        List<Person> p = new ArrayList<>();
        p.add(new Person(12,124));
        p.add(new Person(11,14));
        p.add(new Person(52,24));
        p.add(new Person(12,1244));
        p.add(new Person(1142,1244));
        Stream<Person> stream = p.stream();// default Stream<E> stream():返回一个顺序流

        //filter(Predicate p)  接收lambda,从流中排除某些元素
        //Predicate boolean test(T t):用来对指定数据类型数据进行判断的方法
//        Predicate predicate = new Predicate() {
//            @Override
//            public boolean test(Object o) {
//                if (o instanceof Person){
//                    Person p = (Person)o;
//                    return p.getAge()>30;
//                }
//                return true;
//            }
//        };

        stream.filter(e -> e.getAge() > 30).forEach(System.out::println);
    }

    /*
    映射  //自变量=====函数-===因变量
    map(Function f) 接收一个函数作为参数将参数转换为其他形式或提取信息,孩函数会应用到每一个元素上,并将其映射成一个新的元素,
    flatMap(Function f) 接收一个函数作为参数,将流中的每一个值都换成另一个流,然后把所有的流连接成一个流
    mapToXxx(ToDoubleFunction f)【Double Int Long】 产生一个DoubleStream流
     */
    @Test
    public void test2(){
        //Function              R apply(T t)  放入一个形参返回一个值
        List<String> list = Arrays.asList("aa", "bb", "cc", "dd");
        Stream<String> stream1 = list.stream();
        stream1.map(str->str.toUpperCase()).forEach(System.out::println);


        List<Person> p = new ArrayList<>();
        p.add(new Person(12,124));
        p.add(new Person(11,14));
        p.add(new Person(52,24));
        p.add(new Person(12,1244));
        p.add(new Person(1142,1244));
        Stream<Person> stream = p.stream();// default Stream<E> stream():返回一个顺序流

        //Function              R apply(T t)  放入一个形参返回一个值
        //打印年龄大于30的人
        stream.map(e ->e.getAge()>30? e:null).forEach(System.out::println);
        p.stream().map(e -> e.getAge()).filter(age -> age > 30).forEach(System.out::println);

        System.out.println("=============");


        Stream<Integer> agesStream = p.stream().map(Person::getAge);
        agesStream.filter(age -> age > 30).forEach(System.out::println);


    //    flatMap(Function f) 接收一个函数作为参数,将流中的每一个值都换成另一个流,然后把所有的流连接成一个流//addAll
        list.stream().map(StreamMIddleTest::getStream).forEach(e ->{
            e.forEach(System.out::println);
        });

        list.stream().flatMap(StreamMIddleTest::getStream).forEach(System.out::println);
    }
    @Test
    public void test3(){
        ArrayList arr1 = new ArrayList();
        arr1.add(1);
        arr1.add(2);
        arr1.add(3);

        ArrayList arr2 = new ArrayList();
        arr2.add(4);
        arr2.add(5);
        arr2.add(6);

        arr1.add(arr2);
        System.out.println(arr1);
    }

    public static Stream<Character> getStream(String str){
        ArrayList<Character> characters = new ArrayList<>();
        for(Character c : str.toCharArray()){
            characters.add(c);
        }
        return characters.stream();
    }


    //排序
    /*
    sorted() 产生一个新流 按自然排序
    sorted(Comparator com) 产生一个新流 按比较器顺序排序
     */
    @Test
    public void test4(){
        List<Integer> list = Arrays.asList(3, 1, 33, 12);
        list.stream().sorted().forEach(System.out::println);
        Comparator<Integer> com = new Comparator<Integer>(){
            @Override
            public int compare(Integer o1, Integer o2) {
                return -o1.compareTo(o2);
            }
        };
        list.stream().sorted(com).forEach(System.out::println);
        System.out.println("-----------------");
        list.stream().sorted((o1, o2) -> -o1.compareTo(o2)).forEach(System.out::println);
    }
}

终止操作

public class StreamFinalTest {


    /*
    //1 匹配与查找

       allMatch(Predicate p)   检查是否匹配所有的元素
       anyMatch(Predicate p)   检查是否至少匹配一个元素
       noneMatch(Predicate p)  检查是否没有匹配元素
       findFirst  返回第一个元素
       findAny    获取任意一个元素
       count     返回流中元素的个数
       max(Comparator com) 返回流中最大的值
       min(Comparator com) 返回流中最小的值
       forEach(Consumer c) 内部迭代
     */
    @Test
    public void test1(){
        ArrayList<Person> p = new ArrayList<>();
        p.add(new Person(12,14));
        p.add(new Person(11,14));
        p.add(new Person(52,24));
        p.add(new Person(12,1244));
        p.add(new Person(1142,1244));
        p.forEach(System.out::println);//集合迭代0
        //是否所有的年龄大于18岁
        System.out.println(p.stream().allMatch(e -> e.getAge() > 18));// allMatch(Predicate p)   检查是否匹配所有的元素
        //是否存在年龄大于30岁
        System.out.println(p.stream().anyMatch(e -> e.getAge() > 18));//anyMatch(Predicate p)   检查是否至少匹配一个元素
        //是否存在id=14的人(false 表示存在 true 表示没有这个人)
        System.out.println(p.stream().noneMatch(e -> e.getId() == 14));//noneMatch(Predicate p)  检查是否没有匹配元素
        //返回第一个员工
        System.out.println(p.stream().findFirst()); //findFirst  返回第一个元素
        //所有的年龄大于18岁的个数
        System.out.println(p.stream().map(Person::getAge).filter(age -> age > 18).count());//count   返回流中元素的个数
        //返回年龄最大
        System.out.println(p.stream().max((o1, o2) -> o1.getAge() - o2.getAge()));//  max(Comparator com) 返回流中最大的值

    }

    //2 规约

    /*         初始值
     reduce(T identity, BinaryOperator b) 可以将流中元素结合起来,得到一个值,返回T
     reduce(BinaryOperator b) 可以将流中元素反复结合起来,得到一个值,返回Optional<T>
     */
    @Test
    public void test2(){
       //1-10自然数的和
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        Integer reduce = list.stream().reduce(0, Integer::sum);
        System.out.println(reduce);
        System.out.println(list.stream().reduce(Integer::sum));//Optional[55]
    }

    //3 收集
    /*
    collect(Collect c)  将流转换为其他方式,接收一个Collector接口的实现,用于给Stream中的元素做汇总的方法
     */
    @Test
    public void test3(){
        ArrayList<Person> p = new ArrayList<>();
        p.add(new Person(12,14));
        p.add(new Person(11,14));
        p.add(new Person(52,24));
        p.add(new Person(12,1244));
        p.add(new Person(1142,1244));
        List<Person> collect = p.stream().filter(e -> e.getAge() > 18).collect(Collectors.toList());//toSet()
        System.out.println(collect);

    }
}

Optional类

 

 

/**
 * Optional<T>  避免空指针 也是一种容器,所承下的数有限
 *    常用的方法:ofNullable orElse 两个方法
 *              从Optional拿数据使用  get 注意是否为空(null) isPresent()是否为空
 * @author FuQingsong
 * @create 2023-03-06-18:46
 */
public class OptionalTest {

    @Test
    public void test1(){
        //创建
        Girl girl = new Girl();
        Optional<Girl> o1 = Optional.of(new Girl());//创建实例 参数不能为空
        girl = null;
        Optional<Girl> o2 = Optional.ofNullable(girl);//参数可以是null
        //orElse(T t1)如果单前的Optional的内部封装的t是非空的,则返回内部的t,如果内部t是空的,返回orElse方法中的参数t1
        Optional<Object> empty = Optional.empty();//创建一个空的Optional实例
    }

//    @Test
//    public void test2(){
//        //错误的示范;---->空指针异常
//        Boy boy = new Boy();
//        String name = getName(boy);
//        System.out.println(name);
//    }

    public String getName(Boy boy){
        //会出现空指针
        return boy.getGirl().getName();
    }

    //优化getName() 需要一层一层的进行的判断
    public String getGirlName(Boy boy){
        if (boy != null){
            Girl girl = boy.getGirl();
            if (girl != null)  return girl.getName();
        }
        return null;
    }

    //使用Optional类优化的getgirlName的方法
    public String getMMName(Boy boy){
        Optional<Boy> boy1 = Optional.ofNullable(boy);
        Boy boy2 = boy1.orElse(new Boy(new Girl("qw", 12)));
        Girl girl = boy2.getGirl();
        Optional<Girl> girl1 = Optional.ofNullable(girl);
        Girl girl2 = girl1.orElse(new Girl("qr", 2));
        return girl2.getName();
    }

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值