精华内容
下载资源
问答
  • JDK1.8特性
    2021-12-28 13:44:12

    jdk1.8新特性知识点:

    • Lambda表达式
    • 函数式接口
    • *方法引用和构造器调用
    • Stream API
    • 接口中的默认方法和静态方法
    • 新时间日期API

    更多相关内容
  • jdk1.8特性

    2018-03-13 11:30:56
    JDK1.8特性简介剖析,仅做参考,希望大家相互学习 作为Comparator 和Runnable早期的证明,在JDK中已经定义的接口恰巧作为函数接口而与lambdas表达式兼容。同样方式可以在你自己的代码中定义任何函数接口或第三方...
  • Jdk1.8特性.md

    2021-09-28 14:30:28
    Jdk1.8特性.md
  • 视频教程地址:http://www.gulixueyuan.com/course/56
  • JDK1.8特性:JDK1.8究竟有那些新特性JDK1.8概述 JDK1.8,又称之为Java 8(我习惯叫它为JDK1.8,后续统一叫做JDK1.8),是Java语言开发的一个主要版本。Oracle公司于2014年3月18日发布,它支持函数式编程,新的...

    JDK1.8新特性:JDK1.8究竟有那些新特性呢

    JDK1.8概述

    JDK1.8,又称之为Java 8(我习惯叫它为JDK1.8,后续统一叫做JDK1.8),是Java语言开发的一个主要版本。Oracle公司于2014年3月18日发布,它支持函数式编程,新的JavaScript引擎,新的日期API,新的Stream API等。

    JDK1.8相比1.7之前版本,有以下几方面的优化:

    速度更快;

    代码更少(Lambda表达式);

    强大Stream API;

    便于并行;

    最大化减少空指针异常(OPtional类)。

    举例如下,JDK1.8的特性是不是与众不同。

    package com.xcbeyond.study.jdk8;
    
    import org.junit.Test;
    import java.util.Arrays;
    import java.util.List;
    
    /**
     * JDK1.8新特性
     * @Auther: xcbeyond
     * @Date: 2019/11/27 0027 23:53
     */
    public class Java8Test {
    
        @Test
        public void java8Example() {
            // 定义一个整型list,对其进行遍历
            Integer[] numArray={1,2,3,4,5,6,7,8};
            List<Integer> numList= Arrays.asList(numArray);
    
            /**
             * 方式1:常规foreach
             */
            for (int num : numList) {
                System.out.println(num);
            }
    
            /**
             * 方式2:JDK1.8 新特性写法(Lambda表达式)
             *  代码量是不是少了很多
             */
            numList.forEach((num) -> System.out.println(num));
        }
    }
    

    新特性

    JDK1.8新增了非常多的特性,本专题主要讨论以下几个:

    Lambda表达式:Lambda允许把函数作为一个方法的参数(函数作为参数传递到方法中)。
    方法引用:方法引用提供了非常有用的语法,可以直接引用已有Java类或对象(实例)的方法或构造器。与lambda联合使用,方法引用可以使语言的构造更紧凑简洁,减少冗余代码。
    默认方法:默认方法就是一个在接口里面有了一个实现的方法。
    新工具:新的编译工具,如:Nashorn引擎 jjs、 类依赖分析器jdeps。
    Stream API:新添加的Stream API(java.util.stream) 把真正的函数式编程风格引入到Java中。
    Date Time API:加强对日期与时间的处理。
    Optional类:Optional 类已经成为 Java 8 类库的一部分,用来解决空指针异常。
    Nashorn,JavaScript引擎:JDK1.8提供了一个新的Nashorn javascript引擎,它允许我们在JVM上运行特定的javascript应用。

    Lambda 表达式的结构

    一个 Lambda 表达式可以有零个或多个参数
    参数的类型既可以明确声明,也可以根据上下文来推断。例如:(int a)与(a)效果相同
    所有参数需包含在圆括号内,参数之间用逗号相隔。例如:(a, b) 或 (int a, int b) 或 (String a, int b, float c)
    空圆括号代表参数集为空。例如:() -> 42
    当只有一个参数,且其类型可推导时,圆括号()可省略。例如:a -> return a*a
    Lambda 表达式的主体可包含零条或多条语句
    如果 Lambda 表达式的主体只有一条语句,花括号{}可省略。匿名函数的返回类型与该主体表达式一致
    如果 Lambda 表达式的主体包含一条以上语句,则表达式必须包含在花括号{}中(形成代码块)。匿名函数的返回类型与代码块的返回类型一致,若没有返回则为空

    Lambda 表达式重要特征

    可选类型声明 - 无需声明参数的类型。编译器可以从该参数的值推断。

    可选圆括号参数 - 无需在括号中声明参数。对于多个参数,括号是必需的。

    可选大括号 - 表达式主体没有必要使用大括号,如果主体中含有一个单独的语句。

    可选return关键字 - 编译器会自动返回值,如果主体有一个表达式返回的值。花括号是必需的,以表明表达式返回一个值。

    小试牛刀

    new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("我是传统的写法");
                }
            }).start();
    //------------------------------------------------------------
    new Thread(() -> System.out.println("我是Lambda的写法")).start();
    
    

    输出结果
    在这里插入图片描述

    Stream

    Stream是一组用来处理数组,集合的API。

    1.1 特性
    不是数据结构,没有内部存储。
    不支持索引访问。
    延迟计算
    支持并行
    很容易生成数据或集合
    支持过滤,查找,转换,汇总,聚合等操作。
    1.2 运行机制
    Stream分为源source,中间操作,终止操作。

    流的源可以是一个数组,集合,生成器方法,I/O通道等等。

    一个流可以有零个或多个中间操作,每一个中间操作都会返回一个新的流,供下一个操作使用,一个流只会有一个终止操作。

    Stream只有遇到终止操作,它的源才会开始执行遍历操作。

    1.1 Stream的创建

    1.通过数组,Stream.of()
    2.通过集合
    3.通过Stream.generate方法来创建
    4.通过Stram.iterate方法
    5.其他API

    import java.util.Arrays;
        import java.util.List;
        import java.util.stream.IntStream;
        import java.util.stream.Stream;
        
        public class CreateStream {
        
        	//通过数组,Stream.of()
            static void gen1(){
                String[] str = {"a","b","c"};
                Stream<String> str1 = Stream.of(str);
            }
        
        	//通过集合
            static void gen2(){
                List<String> strings = Arrays.asList("a", "b", "c");
                Stream<String> stream = strings.stream();
            }
        
        	//通过Stream.generate方法来创建
            static void gen3(){
            	//这是一个无限流,通过这种方法创建在操作的时候最好加上limit进行限制
                Stream<Integer> generate = Stream.generate(() -> 1);
                generate.limit(10).forEach(x -> System.out.println(x));
            }
            
        	//通过Stram.iterate方法
            static void gen4(){
                Stream<Integer> iterate = Stream.iterate(1, x -> x +1);
                iterate.forEach(x -> System.out.println(x));
            }
        
        	//其他API
            static void gen5(){
                String str = "abc";
                IntStream chars = str.chars();## 标题
                chars.forEach(x -> System.out.println(x));
            }
        }
    
    

    日期和时间

    • Instant 本质上是一个数字时间戳。可以从a中检索当前的Instant Clock。这对于某个时间点的日志记录和持久性非常有用。
    • LocalDateTime 存储日期和时间。这会存储类似’2010-07-23T15:47:25.890’的日期时间。
    • .ZonedDateTime 使用时区存储日期和时间。如果您想要考虑到日期和时间的准确计算ZoneId,例如“欧洲/巴黎”,这将非常有用。在可能的情况下,建议使用没有时区的更简单的类。时区的广泛使用往往会给应用程序增加相当大的复杂性
    • LocalTime 没有日期存储时间。存储像’11:30’这样的时间,可用于存储开盘或收盘时间。
    • Instant 本质上是一个数字时间戳。可以从a中检索当前的Instant Clock。这对于某个时间点的日志记录和持久性非常有用。

    其他类型

    • Month 用来存储一个月。这样可以隔离单个月份,例如“DECEMBER”。
    • DayOfWeek 用来存储一个星期的日子。这样可以隔离存储一个星期几,例如“星期二”
    • Year 用来存储一年。这样可以隔离一年,例如’2010’。
    • YearMonth 用来存储年加月份的时间。这会存储一年和一个月,例如“2010-12”,并可用于信用卡到期。
    • MonthDay 用来存储月份和日子。它存储月份和日期,例如“12-03”,可用于存储年度活动,如生日,而不存储年份。

    Spring Data API

    
    <!--java 8 time date 支持-->
    <dependency>
    	<groupId>org.hibernate</groupId>
    	<artifactId>hibernate-java8</artifactId>
    	<version>5.0.12.Final</version>
    </dependency>
    

    MyBatis

    <dependency>
    	<groupId>org.mybatis</groupId>
    	<artifactId>mybatis-typehandlers-jsr310</artifactId>
    	<version>1.0.1</version>
    </dependency>
    
    展开全文
  • jdk1.8特性详解:(http://www.oschina.net/translate/everything-about-java-8) JDK包含的基本组件包括: javac – 编译器,将源程序转成字节码 jar – 打包工具,将相关的类文件打包成一个文件 javadoc – ...
  • jdk1.8特性】之Function

    千次阅读 2019-09-16 14:14:12
    笔者日常: 来吧,Function~ 相关声明: 本文按照以下顺序进行说明并给出简单的使用示例: 序号 接口 1 Function<T, R> 2 IntFunction<R> 3 DoubleFunction<...T...

    笔者日常 来吧,Function~


    相关声明

    • 本文按照以下顺序进行说明并给出简单的使用示例:

      序号接口
      1Function<T, R>
      2IntFunction<R>
      3DoubleFunction<R>
      4LongFunction<R>
      5ToIntFunction<T>
      6ToLongFunction<T>
      7ToDoubleFunction<T>
      8IntToDoubleFunction
      9IntToLongFunction
      10LongToDoubleFunction
      11LongToIntFunction
      12DoubleToIntFunction
      13DoubleToLongFunction
      14BiFunction<T, U, R>
      15ToIntBiFunction<T, U>
      16ToLongBiFunction<T, U>
      17ToDoubleBiFunction<T, U>
    • 先给出下文的示例中所涉及到的模型:

      /**
       * 员工实体模型
       *
       * @author JustryDeng
       * @date 2019/7/15 19:48
       */
      @Data
      @AllArgsConstructor
      @NoArgsConstructor
      @Builder
      public class Staff implements Serializable {
      
          /** 姓名 */
          private String name;
      
          /** 年龄 */
          private Integer age;
      
          /** 工号 */
          private String staffNo;
      
      }
      

    Function<T, R>

    • R apply(T t) 输入T类型的参数,运行相关逻辑后,返回R类型的结果。
      使用示例:

      /**
       *  R apply(T t): 输入T类型的参数,运行相关逻辑后,返回R类型的结果。
       */
      @Test
      public void test1() {
          Function<String, Staff> function = x -> {
              Staff s = new Staff();
              s.setName(x + ", 咿呀咿呀哟!");
              return s;
          };
      
          Staff staff = function.apply("邓某");
          // 输出: 邓某, 咿呀咿呀哟!
          System.out.println(staff.getName());
      }
      
    • Function<V, R> compose(Function<? super V, ? extends T> before) 由两个旧的Function得到一个新的Function。

      假设: 现有式子functionC = functionB.compose(functionA),functionA 泛型为<P1, R1>, functionB泛型为<R1, R2>。

      那么, 上述式子的逻辑是:先运行functionA<P1, R1>的apply方法,然后将其返回值作为functionB<R1, R2>的apply方法的入参,执行functionB<R1, R2>的apply方法,返回一个泛型为<P1, R2>的functionC<P1, R2>。

      使用示例:

       /**
        * <V> Function<V, R> compose(Function<? super V, ? extends T> before):由两个旧的Function得到一个新的Function。
        *
        * 假设:现有式子functionC = functionB.compose(functionA),
        *      functionA泛型为<P1, R1>, functionB泛型为<R1, R2>。
        *
        * 那么,上述式子的逻辑是:先运行functionA<P1, R1>的apply方法,然后将其返回值
        *                     作为functionB<R1, R2>的apply方法的入参,执行
        *                     functionB<R1, R2>的apply方法,返回一个泛型为
        *                     <P1, R2>的functionC<P1, R2>。
        */
       @Test
       public void test2() {
       
           Function<String, Integer> functionA = x -> {
               Objects.requireNonNull(x, "参数不能为空");
               x = x.replace(" ", "");
               return x.length();
           };
       
           Function<Integer, Staff> functionB = x -> {
               Objects.requireNonNull(x, "参数不能为空");
               Staff s = new Staff();
               s.setAge(x);
               return s;
           };
       
           Function<String, Staff> functionC = functionB.compose(functionA);
           Staff staff = functionC.apply(" 我 是 参 数 ! ");
           // 输出: Staff(name=null, age=5, staffNo=null)
           System.out.println(staff);
       }
      
    • Function<T, V> andThen(Function<? super R, ? extends V> after 由两个旧的Function得到一个新的Function。
      假设: 现有式子functionC = functionA.andThen(functionB),functionA泛型为<P1, R1>, functionB泛型为<R1, R2>。
      那么, 上述式子的逻辑是:先运行functionA<P1, R1>的apply方法,然后将其返回值作为functionB<R1, R2>的apply方法的入参,执行functionB<R1, R2>的apply方法,返回一个泛型为<P1, R2>的functionC<P1, R2>。
      注: functionA.andThen(functionB)是先执行functionA,再执行functionB;而functionA.compose(functionB)是先执行functionB,再执行functionA。
      使用示例:

       /**
        * <V> Function<T, V> andThen(Function<? super R, ? extends V> after):由两个旧的Function得到一个新的Function。
        *
        * 假设:现有式子functionC = functionA.andThen(functionB),
        *      functionA泛型为<P1, R1>, functionB泛型为<R1, R2>。
        *
        * 那么,上述式子的逻辑是:先运行functionA<P1, R1>的apply方法,然后将其返回值
        *                     作为functionB<R1, R2>的apply方法的入参,执行
        *                     functionB<R1, R2>的apply方法,返回一个泛型为
        *                     <P1, R2>的functionC<P1, R2>。
        *
        * 注: functionA.andThen(functionB)是先执行functionA,再执行functionB;
        *     而functionA.compose(functionB)是先执行functionB,再执行functionA。
        */
       @Test
       public void test3() {
       
           Function<String, Integer> functionA = x -> {
               Objects.requireNonNull(x, "参数不能为空");
               x = x.replace(" ", "");
               return x.length();
           };
       
           Function<Integer, Staff> functionB = x -> {
               Objects.requireNonNull(x, "参数不能为空");
               Staff s = new Staff();
               s.setAge(x);
               return s;
           };
       
           Function<String, Staff> functionC = functionA.andThen(functionB);
           Staff staff = functionC.apply(" 我 是 参 数 ! ");
           // 输出: Staff(name=null, age=5, staffNo=null)
           System.out.println(staff);
       }
      
    • static Function<T, T> identity() 将输入的参数进行返回,即: return t -> t。
      注: 在某些情景下,使用Function.identity(),会让代码更优雅。
      使用示例:

       /**
        * static <T> Function<T, T> identity(): 将输入的参数进行返回,即: return t -> t。
        *
        * 说明: 在某些情景下,使用Function.identity(),会让代码更优雅。
        */
       @Test
       public void test4() {
           /*
            * 使用普通的lambda表达式
            */
           Map<Integer, String> mapOne = Stream.of("a", "ab", "abc", "abcd", "abcde").collect(
                   Collectors.toMap(String::length, param -> param)
           );
           // 输出: {1=a, 2=ab, 3=abc, 4=abcd, 5=abcde}
           System.out.println(mapOne);
       
           /*
            * 使用Function.identity()无疑更优雅
            */
           Map<Integer, String> mapTwo = Stream.of("a", "ab", "abc", "abcd", "abcde").collect(
                   Collectors.toMap(String::length, Function.identity())
           );
           // 输出: {1=a, 2=ab, 3=abc, 4=abcd, 5=abcde}
           System.out.println(mapTwo);
       }
      

    IntFunction<R>

    • R apply(int value) 入参类型必须为int, (运行相关逻辑后)返回R类型的数据。
      使用示例:
       /**
        * R apply(int value): 入参类型必须为int, (运行相关逻辑后)返回R类型的数据。
        */
       @Test
       public void test5() {
           IntFunction<Staff> intFunction = x -> {
               Staff staff = new Staff();
               staff.setAge(x);
               return staff;
           };
       
           Staff res = intFunction.apply(100);
           // 输出: Staff(name=null, age=100, staffNo=null)
           System.out.println(res);
       }
      

    DoubleFunction<R>

    • R apply(double value) 入参类型必须为double,(运行相关逻辑后)返回R类型的数据。
      使用示例:
       /**
        * R apply(double value): 入参类型必须为double, (运行相关逻辑后)返回R类型的数据
        */
       @Test
       public void test6() {
           DoubleFunction<String> doubleFunction = x -> (x + "").replace(".", "_");
           String res = doubleFunction.apply(10.01);
           // 输出: 10_01
           System.out.println(res);
       }
      

    LongFunction<R>

    • R apply(long value) 入参类型必须为long, (运行相关逻辑后)返回R类型的数据。

      使用示例:

       /**
        * R apply(long value): 入参类型必须为long, (运行相关逻辑后)返回R类型的数据。
        */
       @Test
       public void test7() {
           LongFunction<String> longFunction = x -> (x + "").replace("4", "  8484884  ").trim();
           String res = longFunction.apply(484);
           // 输出: 8484884  8  8484884
           System.out.println(res);
       }
      

    ToIntFunction<T>

    • int applyAsInt(T value) 入参类型为T,(运行相关逻辑后)返回类型必为int。
      使用示例:
       /**
        * int applyAsInt(T value): 入参类型为T, (运行相关逻辑后)返回类型必为int。
        */
       @Test
       public void test8() {
           ToIntFunction<String> toIntFunction = x -> x == null ? 0 : x.length();
           int res = toIntFunction.applyAsInt("蚂蚁呀~嘿!嘿!");
           // 输出: 8
           System.out.println(res);
       }
      

    ToLongFunction<T>

    • long applyAsLong(T value) 入参类型为T, (运行相关逻辑后)返回类型必为long。
      使用示例:
       /**
        * long applyAsLong(T value): 入参类型为T, (运行相关逻辑后)返回类型必为long。
        */
       @Test
       public void test9() {
           ToLongFunction<String> toLongFunction = x -> x == null ? 0 : new SecureRandom(x.getBytes()).nextLong();
           long res = toLongFunction.applyAsLong("蚂蚁呀~嘿!嘿!");
           // 输出: 2677168598702751372
           System.out.println(res);
       }
      

    ToDoubleFunction<T>

    • double applyAsDouble(T value) 入参类型为T,(运行相关逻辑后)返回类型必为double。
      使用示例:
       /**
        * double applyAsDouble(T value): 入参类型为T, (运行相关逻辑后)返回类型必为double。
        */
       @Test
       public void test10() {
           ToDoubleFunction<Float> toDoubleFunction = x -> x == null ? 0.0 : x;
           double res = toDoubleFunction.applyAsDouble(123.4F);
           // 输出: 123.4000015258789 (注:精度问题不在本文的讨论范围内)
           System.out.println(res);
       }
      

    IntToDoubleFunction

    • double applyAsDouble(int value) 入参类型必须为int,(运行相关逻辑后)返回类型必为double。
      使用示例:
       /**
        * double applyAsDouble(int value): 入参类型必须为int, (运行相关逻辑后)返回类型必为double。
        */
       @Test
       public void test11() {
           IntToDoubleFunction intToDoubleFunction = x -> x + 88.8;
           double res = intToDoubleFunction.applyAsDouble(12300);
           // 输出: 12388.8
           System.out.println(res);
       }
      

    IntToLongFunction

    • long applyAsLong(int value) 入参类型必须为int,(运行相关逻辑后)返回类型必为long。
      使用示例:
       /**
        * long applyAsLong(int value): 入参类型必须为int, (运行相关逻辑后)返回类型必为long。
        */
       @Test
       public void test12() {
           IntToLongFunction intToLongFunction = x -> x + 1000L;
           long res = intToLongFunction.applyAsLong(12345);
           // 输出: 13345
           System.out.println(res);
       }
      

    LongToDoubleFunction

    • double applyAsDouble(long value) 入参类型必须为long, (运行相关逻辑后)返回类型必为double。
      使用示例:
       /**
        * double applyAsDouble(long value): 入参类型必须为long, (运行相关逻辑后)返回类型必为double。
        */
       @Test
       public void test13() {
           LongToDoubleFunction longToDoubleFunction = x -> x + 1000000D;
           double res = longToDoubleFunction.applyAsDouble(12345L);
           // 输出: 1012345.0
           System.out.println(res);
       }
      

    LongToIntFunction

    • int applyAsInt(long value) 入参类型必须为long,(运行相关逻辑后)返回类型必为int。
      使用示例:
       /**
        * int applyAsInt(long value): 入参类型必须为long, (运行相关逻辑后)返回类型必为int。
        */
       @Test
       public void test14() {
           LongToIntFunction longToIntFunction = x -> (int)(x / 1000);
           int res = longToIntFunction.applyAsInt(12345L);
           // 输出: 12
           System.out.println(res);
       }
      

    DoubleToIntFunction

    • int applyAsInt(double value) 入参类型必须为double,(运行相关逻辑后)返回类型必为int。
      使用示例:
       /**
        * int applyAsInt(double value): 入参类型必须为double, (运行相关逻辑后)返回类型必为int。
        */
       @Test
       public void test15() {
           DoubleToIntFunction doubleToIntFunction = x -> (int)x;
           int res = doubleToIntFunction.applyAsInt(123.45);
           // 输出: 123
           System.out.println(res);
       }
      

    DoubleToLongFunction

    • long applyAsLong(double value) 入参类型必须为double,(运行相关逻辑后)返回类型必为long。
      使用示例:
       /**
        * long applyAsLong(double value): 入参类型必须为double, (运行相关逻辑后)返回类型必为long。
        */
       @Test
       public void test16() {
           DoubleToLongFunction doubleToLongFunction = x -> (long)x;
           long res = doubleToLongFunction.applyAsLong(112233.4455);
           // 输出: 112233
           System.out.println(res);
       }
      

    BiFunction<T, U, R>

    • R apply(T t, U u) 输入T类型、U类型的参数,运行相关逻辑后,返回R类型的结果。
      使用示例:

       /**
        *  R apply(T t, U u): 输入T类型、U类型的参数,运行相关逻辑后,返回R类型的结果。
        */
       @Test
       public void test17() {
           BiFunction<Integer, String, Staff> biFunction = (x, y) -> {
               Staff s = new Staff();
               s.setAge(x);
               s.setName(y);
               return s;
           };
       
           Staff staff = biFunction.apply(25, "单身邓");
           // 输出: 单身邓, 25岁!
           System.out.println(staff.getName() + ", " + staff.getAge() + "岁!");
       }
      
    • BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after) 由一个旧的BiFunction以及一个旧的Function得到一个新的BiFunction<T, U, V>。
      假设: 现有式子biFunctionC = biFunctionA.andThen(functionB),biFunctionA泛型为<P1, T1, R1>, functionB泛型为<R1, R2>。
      那么, 上述式子的逻辑是:先运行biFunctionA<P1, T1, R1>的apply方法,然后将其返回值作为functionB<R1, R2>的apply方法的入参,执行functionB<R1, R2>的apply方法,返回一个泛型为<P1, T1, R2>的biFunctionC<P1, T1, R2>。
      使用示例:

       /**
        * <V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after):
        *     由一个旧的BiFunction以及一个旧的Function得到一个新的BiFunction<T, U, V>。
        *
        * 假设:现有式子biFunctionC = biFunctionA.andThen(functionB),
        *      biFunctionA泛型为<P1, T1, R1>, functionB泛型为<R1, R2>。
        *
        * 那么,上述式子的逻辑是:先运行biFunctionA<P1, T1, R1>的apply方法,然后将其返回值
        *                     作为functionB<R1, R2>的apply方法的入参,执行
        *                     functionB<R1, R2>的apply方法,返回一个泛型为
        *                     <P1, T1, R2>的biFunctionC<P1, T1, R2>。
        */
       @Test
       public void test18() {
           BiFunction<Integer, String, Staff> biFunctionA = (x, y) -> {
               Staff s = new Staff();
               s.setAge(x);
               s.setName(y);
               return s;
           };
       
           Function<Staff, Map<String, Staff>> functionB = x -> {
               Map<String, Staff> map = new HashMap<>(4);
               map.put(x.getName(), x);
               return map;
           };
       
           BiFunction<Integer, String,  Map<String, Staff>> biFunctionC = biFunctionA.andThen(functionB);
       
           Map<String, Staff> map = biFunctionC.apply(25, "单身邓");
           // 输出: {单身邓=Staff(name=单身邓, age=25, staffNo=null)}
           System.out.println(map);
       }
      

    ToIntBiFunction<T, U>

    • int applyAsInt(T t, U u) 入参类型为T和U,(运行相关逻辑后)返回类型必为int。
      使用示例:
       /**
        * int applyAsInt(T t, U u): 入参类型为T和U, (运行相关逻辑后)返回类型必为int。
        */
       @Test
       public void test19() {
           ToIntBiFunction<String, Double> toIntBiFunction = (x, y) -> Integer.parseInt(x) + y.intValue();
           int res = toIntBiFunction.applyAsInt("123000", 456.789);
           // 输出: 123456
           System.out.println(res);
       }
      

    ToLongBiFunction<T, U>

    • long applyAsLong(T t, U u) 入参类型为T和U, (运行相关逻辑后)返回类型必为long。
      使用示例:
       /**
        * long applyAsLong(T t, U u): 入参类型为T和U, (运行相关逻辑后)返回类型必为long。
        */
       @Test
       public void test20() {
           ToLongBiFunction<String, Double> toLongBiFunction = (x, y) -> Integer.parseInt(x) + y.intValue();
           long res = toLongBiFunction.applyAsLong("123000", 456.789);
           // 输出: 123456
           System.out.println(res);
       }
      

    ToDoubleBiFunction<T, U>

    • double applyAsDouble(T t, U u) 入参类型为T和U,(运行相关逻辑后)返回类型必为double。
      使用示例:
       /**
        * double applyAsDouble(T t, U u): 入参类型为T和U, (运行相关逻辑后)返回类型必为double。
        */
       @Test
       public void test21() {
           ToDoubleBiFunction<String, Double> toDoubleBiFunction = (x, y) -> Integer.parseInt(x) + y;
           double res = toDoubleBiFunction.applyAsDouble("123000", 456.789);
           // 输出: 123456.789
           System.out.println(res);
       }
      


    ^_^ 如有不当之处,欢迎指正

    ^_^ 参考资料
            《jdk api 1.8_google.CHM》

    ^_^ 测试代码托管链接
             https://github.com/JustryDeng…Jdk8Feature

    ^_^ 本文已经被收录进《程序员成长笔记》 ,笔者JustryDeng

    展开全文
  • jdk1.8特性】之Predicate

    千次阅读 2019-08-19 15:34:37
    ^_^ 如有不当之处,欢迎指正 ^_^ 参考链接 Predicate详解 - 简书 ^_^ 参考文档 《jdk api 1.8_google.CHM》 ^_^ 测试代码托管链接 https://github.com/JustryDeng…Jdk8Feature ^_^ 本文已经被收录进《程序员...

    Predicate简介

            Predicate是一个功能性的接口,其功能是判断某个参数是否满足表达式。相似的还有BiPredicate<T, U>(使用 test(T t, U u)方法,判断参数t、u是否满足BiPredicate实例所代表的表达式);DoublePredicate(对于基本数据类型double的Predicate);LongPredicate(对于基本数据类型int的Predicate);IntPredicate(对于基本数据类型long的Predicate)。

    注:本文主要学习Predicate,学会了Predicate,那么自然就学会了BiPredicate<T, U>、DoublePredicate、
            IntPredicate、LongPredicate。


    Predicate学习

    • test(T t)判断t,是否满足Predicate实例所代表的表达式。

    /**
     * test(T t): 判断t,是否满足Predicate实例所代表的表达式
     */
    @Test
    public void test1() {
    
        // 形参x的数据类型,由Predicate<T>的泛型T指定
        // 定义一个 用于判断的表达式(这里为 x >= 1)
        Predicate<Integer> predicate = x -> x >= 1;
    
        // 判断参数是否满足 predicate代表的表达式
        boolean resultOne = predicate.test(0);
        boolean resultTwo = predicate.test(1);
    
        // 输出结果为: false
        System.out.println(resultOne);
        // 输出结果为: true
        System.out.println(resultTwo);
    }

    运行测试类,控制台输出:

    • isEqual(Object targetRef)判断targetRef,是否与Predicate实例所代表的对象相等。

    /**
     * isEqual(Object targetRef): 判断targetRef,是否与Predicate实例所代表的对象相等
     */
    @Test
    public void test2() {
    
        /*
         * 等价于:
         *  Predicate<Object> predicate = x -> {
         *      if (x == objA) {
         *         return true;
         *      }
         *      return x.equals(objA);
         *  };
         */
        Object objA = new Object();
        Predicate<Object> predicate = Predicate.isEqual(objA);
    
    
        // 判断参数是否满足 predicate代表的表达式
        boolean resultOne = predicate.test(objA);
        boolean resultTwo = predicate.test(null);
        boolean resultThree = predicate.test(new Object());
    
        // 输出结果为: true
        System.out.println(resultOne);
        // 输出结果为: false
        System.out.println(resultTwo);
        // 输出结果为: false
        System.out.println(resultThree);
    }

    运行测试类,控制台输出:

    • and(Predicate<? super T> other)对两个Predicate实例取&&,得到新的Predicate实例。

    /**
     * and(Predicate<? super T> other): 对两个Predicate实例取&&,得到新的Predicate实例
     */
    @Test
    public void test3() {
    
        // 定义两个 用于判断的表达式
        Predicate<Integer> predicateOne = x -> x >= 1;
        Predicate<Integer> predicateTwo = x -> x <= 2;
    
        /*
         * 对两个表达式取 &&
         *
         * 等价于:Predicate<Integer> predicateThree = x -> x >= 1 && x <= 2;
         */
        Predicate<Integer> predicateThree = predicateOne.and(predicateTwo);
    
        // 判断参数是否满足 predicateThree代表的表达式
        boolean resultOne = predicateThree.test(0);
        boolean resultTwo = predicateThree.test(1);
        boolean resultThree = predicateThree.test(2);
        boolean resultFour = predicateThree.test(3);
    
        // 输出结果为: false
        System.out.println(resultOne);
        // 输出结果为: true
        System.out.println(resultTwo);
        // 输出结果为: true
        System.out.println(resultThree);
        // 输出结果为: false
        System.out.println(resultFour);
    }

    运行测试类,控制台输出:

    • or(Predicate<? super T> other)对两个Predicate实例取||,得到新的Predicate实例。

    /**
     * or(Predicate<? super T> other): 对两个Predicate实例取||,得到新的Predicate实例
     */
    @Test
    public void test4() {
    
        // 定义两个 用于判断的表达式
        Predicate<Integer> predicateOne = x -> x >= 1;
        Predicate<Integer> predicateTwo = x -> x <= -1;
    
        /*
         * 对两个表达式取 ||
         *
         * 等价于:Predicate<Integer> predicateThree = x -> x >= 1 || x <= -1;
         */
        Predicate<Integer> predicateThree = predicateOne.or(predicateTwo);
    
        // 判断参数是否满足 predicateThree代表的表达式
        boolean resultOne = predicateThree.test(-2);
        boolean resultTwo = predicateThree.test(-1);
        boolean resultThree = predicateThree.test(0);
        boolean resultFour = predicateThree.test(1);
        boolean resultFive = predicateThree.test(2);
    
        // 输出结果为: true
        System.out.println(resultOne);
        // 输出结果为: true
        System.out.println(resultTwo);
        // 输出结果为: false
        System.out.println(resultThree);
        // 输出结果为: true
        System.out.println(resultFour);
        // 输出结果为: true
        System.out.println(resultFive);
    }

    运行测试类,控制台输出:

    • negate()对当前Predicate实例取!,得到新的Predicate实例。

    /**
     * negate(): 对当前Predicate实例取!,得到新的Predicate实例
     */
    @Test
    public void test5() {
    
        // 定义两个 用于判断的表达式
        Predicate<Integer> predicateOne = x -> x >= 1;
    
        /*
         * 等价于:Predicate<Integer> predicate = x -> !(x >= 1);
         * 等价于:Predicate<Integer> predicate = x -> x < 1;
         */
        Predicate<Integer> predicate = predicateOne.negate();
    
        // 判断参数是否满足 predicateThree代表的表达式
        boolean resultOne = predicate.test(0);
        boolean resultTwo = predicate.test(1);
        boolean resultThree = predicate.test(2);
    
        // 输出结果为: true
        System.out.println(resultOne);
        // 输出结果为: false
        System.out.println(resultTwo);
        // 输出结果为: false
        System.out.println(resultThree);
    }

    运行测试类,控制台输出:

    Predicate学习完毕

    ^_^ 如有不当之处,欢迎指正

    ^_^ 参考链接
                   Predicate详解 - 简书

    ^_^ 参考文档
               
      《jdk api 1.8_google.CHM》

    ^_^ 测试代码托管链接
                   
    https://github.com/JustryDeng…Jdk8Feature

    ^_^ 本文已经被收录进《程序员成长笔记》 ,笔者JustryDeng

    展开全文
  • JDK1.8特性知识详解

    2022-03-23 11:36:47
    jdk 1.8特性知识详解
  • jdk1.8特性 stream filter 的使用

    千次阅读 2020-03-31 23:13:17
    } 输出结果: com.intellij.rt.execution.junit.JUnitStarter -ideVersion5 -junit4 com.example.Testjdk18,test 超级记忆 头脑风暴 超级记忆2 头脑风暴2 超级记忆3 头脑风暴3年 ----------------------- 头脑风暴3...
  • 一、JDK1.8特性 JDK1.8概述: JDK1.8,又称之为Java 8(我习惯叫它为JDK1.8,后续统一叫做JDK1.8),是Java语言开发的一个主要版本。Oracle公司于2014年3月18日发布,它支持函数式编程,新的JavaScript引擎,...
  • JDK1.8中文文档

    2018-11-26 10:06:58
    jdk1.8特性 Java 8允许我们给接口添加一个非抽象的方法实现,只需要使用 default关键字即可。 新增lambda表达式 提供函数式接口 Java 8 允许你使用 :: 关键字来传递方法或者构造函数引用 我们可以直接在lambda...
  • 四、Lambda作为参数 在 jdk8 之前,接口可以作为方法参数传入,执行时必须提供接口实现类的实例。从 java8 开始,Lambda 可以作为接口方法实现,当作参数传入,无论从形式上还是实际上都省去了对象的创建。使代码...
  • Jdk1.8特性lambda表达式-3 和forEach()方法 public class Demo3_forEach { public static void main(String[] args) { List<Person> persons= new ArrayList<Person>(){ { //匿名类初始化代码 ...
  • jdk1.8特性.doc

    2020-04-01 13:23:33
    本文主要介绍了JDK1.8版本中的一些新特性,仅供参考。 jdk1.8特性知识点: 1、Lambda表达式 2、函数式接口 3、方法引用和构造器调用 4、Stream API 5、接口中的默认方法和静态方法 6、新时间日期API
  • jdk1.8特性

    2018-07-27 17:43:31
    1.8特性 1. 速度更快 – 红黑树 2. 代码更少 – Lambda 3. 强大的Stream API – Stream 4. 便于并行 – Parallel 5. 最大化减少空指针异常 – Optional
  • jdk1.8list转map的测试类

    2019-09-06 11:01:49
    list转map的测试类,用到jdk1.8的新特性,感觉用起来很方便
  • 总的来说,JDK1.8在以下方面具有新特性: 1. 速度更快 – 红黑树 2. 代码更少 – Lambda 3. 强大的Stream API – Stream 4. 便于并行 – Parallel 5. 最大化减少空指针异常 – Optional
  • JDK1.8特性总结

    2020-04-26 09:55:29
    之前的实习的过程中,一位有着非常丰富经验的CTO曾对我说过,代码的质量,要不断的去提升。从刚开始的CRUD,到具体的业务流程实现,在这个过程中要不断的提炼代码。... (ps,我说:1.8),你知道jdk8...
  • JDK1.8特性(超详细)

    千次阅读 2021-02-12 10:42:07
    这个新特性就是为了我们使用简单的呀,所以java已经内置了一堆函数式接口了。 先来个表格整体概览一下常用的一些: 函数式接口 参数类型 返回类型 用途 Supplier 供给型 无 T 返回类型为T的对象,方法:T get() ...
  • 2、用匿名内部类Runnable接口作为参数开启一个线程,可以精简 3、小结,黑马JDK8新特性的b站视频 二、新增四个函数式接口,一开始觉得没啥用,后来想应该是解耦合以及实现代码复用 Supplier:生产者,有一个get方法 ...
  • Optional是属于JDK1.8API新增的,可以优雅解决空指针异常的问题。也可以去除掉重复的if else逻辑问题。 对着旧的代码,修改为使用Optoinal逻辑,有些例子参考网址的,这个只是我作为笔记。 Optional主要方法: ...
  • 通过jdk1.8特性获取两个时间相减的差值 public static void main(String[] args) throws InterruptedException { // LocalDate today = LocalDate.now(); // System.out.println("Today : " + today); // ...
  • Java1.8特性Lambda表达式
  • jdk 1.8源码下载

    2018-07-31 15:53:15
    相较于之前的jdk版本,jdk1.8加入了很多新特性,诸如Lambda表达式,函数式接口,时间的处理类等新特性,值得一提的是可以在Interface接口中加入default关键字开头的方法,里面可以写实现。这一改动算是为了增加新...
  • 1.将一个对象的属性值复制给另一个对象 BeanUtils.copyProperties...2.jdk1.8特性 获取类目type列表 //获取某一属性集合 List<Integer> categoryTypeList = productInfoList.stream() .map(ProductInfo:...
  • JDK 之前,要在一个接口中添加一个新的抽象方法,那所有的接口实现类都要去实现这个方法,不然就会编译错误,而某些实现类根本就不需要实现这个方法也被迫要写一个空实现,改动会非常大。 所以,接口默认方法...
  • jdk1.8特性总结

    2020-07-29 23:00:02
    这里写自定义目录标题jdk1.8特性总结(便于回忆记录)(一)Lambda表达式1. 函数式编程2. lambda表达式(二) 函数式接口(三)方法引用1. 方法引用2. 构造器引用3. 数组引用(三)Stream API(四)并行流和串行流...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 45,697
精华内容 18,278
关键字:

jdk1.8特性