Java8新特性代码示例(附注释)- 方法引用,Optional, Stream

  /**
     * java8中的函数式接口,java中规定:函数式接口必须只有一个抽象方法,可以有多个非抽象方法,同时,如果继承实现了
     * Object中的方法,那么也是合法的
     * <p>
     * 函数式接口可以使用lambda来创建
     */
    @FunctionalInterface
    interface MyService {
        void sayMessage(String msg);

        @Override
        boolean equals(Object obj);
    }

    /**
     * 入口
     * @param args
     */
    public static void main(String[] args) {
        printSeperator();
        testMehtodRef();
        printSeperator();

        testSupplierConsumer();
        printSeperator();

        testOptional();
        printSeperator();

        testStream();
        printSeperator();
    }

    /**
     * 测试Optional类
     */
    private static void testOptional() {
        Optional<String> optional1 = Optional.ofNullable(null);
        //如果optional确实存在值,那么该函数返回值为true
        if (optional1.isPresent()) {
            System.out.println("optional1 present!");
        }

        //如果optional没有值,那么默认返回传入的other
        String res = optional1.orElse("default");
        System.out.println("res's value after orElse:" + res);
        try {
            /**
             * 如果没有该值,那么抛出{@link NoSuchElementException}
             */
            res = optional1.orElseThrow();
            System.out.println("res's value after orElseThrow:" + res);
        } catch (NoSuchElementException e) {
            System.out.println("orElseThrow occured!");
        }

        optional1 = Optional.ofNullable("i have a value");
        res = optional1.orElse("default");
        System.out.println("res's value after orElse:" + res);
    }

    /**
     * 测试{@link java.util.function.Supplier} and {@link java.util.function.Consumer}
     */
    private static void testSupplierConsumer() {
        Supplier<String> supplier1 = new Supplier<String>() {
            @Override
            public String get() {
                return new String("hello world from supplier1");
            }
        };

        //lambda式的supplier,supplier的规定是无参数,且返回一个对象,因此满足该条件
        Supplier<String> supplier2 = () -> new String("hello world from supplier2");

        //本质上supplier是一个容器,对一个方法的封装
        var str1 = getSupplier(supplier1);
        var str2 = getSupplier(supplier2);
        //方法引用默认返回一个supplier,因为该new不接受任何参数,返回一个对象,因此满足条件
        var str3 = getSupplier(String::new);
        System.out.println("str1: " + str1 + "   str2:" + str2 + "   str3:" + str3);

        /////////////////////////////////////////////////////////////////////////////////////////////
        Consumer<String> consumer1 = new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.print(s + "|");
            }
        };
        //lambda式的Consumer,Consumer的约定是接受一个参数,返回值为void,因此满足条件
        Consumer<String> consumer2 = (s) -> System.out.print(s + "^");
        var list = getStrList();
        list.forEach(consumer1);
        System.out.println();
        list.forEach(consumer2);
        System.out.println();

        /////////////////////////////////////////////////////////////////////////////////////////////
        //Predicate谓词接口,用于判断是否符合某个条件,约定是:接受一个参数,返回值为boolean
        Predicate<Integer> predicate1 = new Predicate<Integer>() {
            @Override
            public boolean test(Integer integer) {
                return integer > 2;
            }
        };

        //lambda式的谓词接口
        Predicate<Integer> predicate2 = (num) -> num > 2;
        var numList = getIntList();
        var res = numList.stream().filter(predicate1).collect(Collectors.toList());
        System.out.println(res);
        res = numList.stream().filter(predicate2).collect(Collectors.toList());
        System.out.println(res);

        /////////////////////////////////////////////////////////////////////////////////////////////
        //Function接口:这是一个功能性的接口,主要用于把一种类型的数据处理完成后,可能得到的结果是另外一种类型
        //本质上是上面那些接口的超集,第一个参数为接口的类型,第二个参数为转换后的类型
        Function<String, Character> func1 = new Function<String, Character>() {
            @Override
            public Character apply(String s) {
                if (s.length() <= 2) {
                    return 'a';
                }
                return s.charAt(2);
            }
        };

        Function<String, Character> func2 = (s) -> {
            return s.length() <= 2 ? 'a' : s.charAt(2);
        };
        var varList = getStrList();
        var res2 = varList.stream().map(func1).collect(Collectors.toList());
        System.out.println(res2);
        res2 = varList.stream().map(func2).collect(Collectors.toList());
        System.out.println(res2);
    }

    /**
     * 测试{@link java.util.stream.Stream}里面的函数接口,
     * Stream里面的函数接口非常的多,类似于SQL,分为两种:
     * 1 中间函数 immediate function
     * 2 最终函数(规约) terminal function
     */
    private static void testStream() {
        //将一个数字list,先过滤到大于3的数,然后转换为对应的字母,最后在大写,最后重新收集为一个List
        List<Integer> numList = getIntList();
        List<String> res = numList.stream().filter((num) -> num > 3).map(num -> String.valueOf((char)('a' + num)))
                .map(str -> String.valueOf((char)('A' + str.charAt(0) - 'a'))).collect(Collectors.toList());
        System.out.println(res);

        final int size = 100;
        int[] arr = new int[size];
        Random random = new Random();
        for(int i = 0;i < size;++i){
            arr[i] = random.nextInt(1000);
        }
        //对numArr进行排序,然后得到最前面的5个数据,最后得到最大值
        var res2 = Arrays.stream(arr).sorted().limit(5).min();
        System.out.println("res2:"+ res2.orElseThrow());
    }

    /**
     * 辅助类
     *
     * @param supplier
     * @param <T>
     * @return
     */
    private static <T> T getSupplier(Supplier<T> supplier) {
        return supplier.get();
    }

    /**
     * 测试方法引用的用法
     */
    private static void testMehtodRef() {
        List<String> strs = new ArrayList<>();
        strs.add("one");
        strs.add("two");
        strs.add("three");
        strs.add("four");

        //printSomething本质上是一个Consumer
        strs.forEach(HelloJava8::printSomething);
        System.out.println();
    }

    /**
     * 打印一些东西
     *
     * @param s
     */
    private static void printSomething(String s) {
        System.out.print(s + "\t");
    }

    private static void printSeperator() {
        System.out.println(SEPERATOR);
    }

    /**
     * 辅助方法,获辅助list
     *
     * @return
     */
    private static List<String> getStrList() {
        List<String> strs = new ArrayList<>();
        strs.add("one");
        strs.add("two");
        strs.add("three");
        strs.add("four");
        return strs;
    }

    /**
     * 获取辅助list
     *
     * @return
     */
    private static List<Integer> getIntList() {
        List<Integer> intList = new ArrayList<>();
        for (int i = 1; i <= 10; ++i) {
            intList.add(i);
        }
        return intList;
    }

原文地址:https://www.cnblogs.com/seancheer/p/11721950.html

时间: 2024-07-30 19:28:40

Java8新特性代码示例(附注释)- 方法引用,Optional, Stream的相关文章

初识Java8新特性Lambda(三 ) 之lambda类库Stream

简介 Java SE 8 增加了新的语言特性(例如 lambda 表达式和默认方法),为此 Java SE 8 的类库也进行了很多改进,本文简要介绍了这些改进.在阅读本文前,你应该先阅读 深入浅出Java 8 Lambda(语言篇),以便对 Java SE 8 的新增特性有一个全面了解. 背景(Background) 自从lambda表达式成为Java语言的一部分之后,Java集合(Collections)API就面临着大幅变化.而 JSR 355(规定了 Java lambda 表达式的标准)

Java 8 新特性:Lambda 表达式之方法引用(Lambda 表达式补充版)——诺诺&quot;涂鸦&quot;记忆

----------   诺诺学习技术交流博客.期待与您交流!    ---------- 详情请查看:http://blog.csdn.net/sun_promise  方法引用 (注:此文乃个人查找资料然后学习总结的,若有不对的地方,请大家指出,非常感谢!) 1.方法引用简述 方法引用是用来直接访问类或者实例的已经存在的方法或者构造方法.方法引用提供了一种引用而不执行方法的方式,它需要由兼容的函数式接口构成的目标类型上下文.计算时,方法引用会创建函数式接口的一个实例. 当Lambda表达式中

11年 C# 4.0四大新特性代码示例与解读

摘要:今天我们结合代码实例来具体看一下C#4.0中的四个比较重要的特性. 之前的文章中,我们曾介绍过C#的历史及C# 4.0新增特性,包括:dynamic. 命名和可选参数.动态导入以及协变和逆变等.今天我们结合代码实例来具体看一下C#4.0中的四个比较重要的特性. 1.dynamic ExpandoObject 熟悉js的朋友都知道js可以这么写 : var t = new Object(); t.Abc = ‘something’; t.Value =243; 现在这个js动态语言的特性,我

Android 使用Java8新特性之&quot;方法引用&quot;

前言 上一文:Android 使用Java8新特性之Lambda expression (附命令者模式简化) 说过lambda表达式,在android studio中的环境配置及应用.本文讲下Java8新特性之"方法引用". "方法引用",它其实可以看成lambda表达式的一种简写形式. 再回顾一下lambda表达式的应用场景:简化仅含单一抽象方法接口的调用 方法引用的4种形式 方法引用的符号形式,形如, [className | class-instance]::

Java8新特性(一)_interface中的static方法和default方法

为什么要单独写个Java8新特性,一个原因是我目前所在的公司用的是jdk8,并且框架中用了大量的Java8的新特性,如上篇文章写到的stream方法进行过滤map集合.stream方法就是接口Collection中的default方法.所以准备专门写写关于java8新特性的文章,虽然现在10已经发布了.但还是要认真的去了解下新版本的变化. static方法 java8中为接口新增了一项功能:定义一个或者更多个静态方法.用法和普通的static方法一样. 代码示例 public interface

JAVA8新特性——方法引用

JAVA9都要出来了,JAVA8新特性都没搞清楚,是不是有点掉队哦~ 在Lamda新特性的支持下,JAVA8中可以使用lamda表达式来创建匿名方法.然而,有时候我们仅仅是需要调用一个已存在的方法(如java中已经定义好的方法),在这时候java8新特性"方法引用"将会进一步简化操作(注意:需要有Lamda的支持). 方法引用的四种形式: 引用静态方法-->类名称::static 方法名称: 引用某个对象的实例的普通方法-->示例化对象::普通方法: 引用某个类型的任意对象

乐字节-Java8新特性-接口默认方法之Stream流(下)

接上一篇:<Java8新特性之stream>,下面继续接着讲Stream 5.流的中间操作 常见的流的中间操作,归为以下三大类:筛选和切片流操作.元素映射操作.元素排序操作: 操作 描述 筛选和切片 filter(T -> boolean):保留 boolean 为 true 的元素 limit(long n):返回前 n 个元素 skip(long n):去除前 n 个元素 distinct():去除重复元素,这个方法是通过类的 equals 方法来判断两个元素是否相等的 映射 map

java8 新特性精心整理

前言 越来越多的项目已经使用 Java 8 了,毫无疑问,Java 8 是Java自Java 5(发布于2004年)之后的最重要的版本.这个版本包含语言.编译器.库.工具和 JVM 等方面的十多个新特性.在本文中我们将学习这些新特性,并用实际的例子说明在什么场景下适合使用. 引用:本文参考了这两篇文章,加以自己的理解,整理成一份最容易理解的 Java8 新特性文章,有少部分章节可能内容一致,但绝对不是抄袭,只是为了文章的完整性,大部分常用的地方加了我自己的理解和示例. https://blog.

java8 新特性精心整理(全)

前言 越来越多的项目已经使用 Java 8 了,毫无疑问,Java 8 是Java自Java 5(发布于2004年)之后的最重要的版本.这个版本包含语言.编译器.库.工具和 JVM 等方面的十多个新特性.在本文中我们将学习这些新特性,并用实际的例子说明在什么场景下适合使用. 引用:本文参考了这两篇文章,加以自己的理解,整理成一份最容易理解的 Java8 新特性文章,有少部分章节可能内容一致,但绝对不是抄袭,只是为了文章的完整性,大部分常用的地方加了我自己的理解和示例. https://blog.