JDK8/1.8新特性用法汇总

目录

1、Optional容器

2、Stream流

3、Lambda匿名函数


1、Optional容器

package com.xch.feature01;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;

/**
 * @author Chenghe Xu
 * @date 2022/7/22 11:11
 */
public class Test05 {

    public static void main(String[] args) {
        
        /**
         * Java 8引入Optional类来防止空指针异常
         * Optional类实际上是个容器:它可以保存类型T的值,或者保存null
         * 使用Optional类我们就不用显式进行空指针检查了
         */
        
        //Optional产生对象的of()、ofNullable()方法的使用和区别:
        //of()是指返回一个Optional包含的非null值对象
        Optional<String> optional1=Optional.of("原测试值001");
        //ofNullable()是指返回一个Optional包含的可为null值对象
        Optional<String> optional2=Optional.ofNullable(null);
        
        //Optional判断orElse()、orElseGet()方法的使用和区别:
        //orElse()是指Optional对象如果非null,则返回该值,否则返回other值或函数执行结果
        //orElse()方法缺点:orElse里的函数一定会执行,但是结果是由orElse()方法选择输出
        System.out.println(optional1.orElse(createTest()));
        System.out.println(optional2.orElse(createTest()));
        System.out.println("============================");
        //orElseGet()是指Optional对象如果非null,则返回该值,否则返回lambda匿名表达式执行结果
        System.out.println(optional1.orElseGet( Test05::createTest ));
        System.out.println(optional2.orElseGet( () -> createTest() ));
        
        //orElseThrow()方法的使用,不为null则输出,否则报自定义的异常信息
        System.out.println("---------------------------");
        System.out.println(optional1.orElseThrow(()->new IllegalArgumentException("this optional is empty")));
//        System.out.println(optional2.orElseThrow(()->new IllegalArgumentException("this optional is empty")));
        
        Optional<Person> optional3=Optional.ofNullable(new Person("小徐",21));
        Optional<Person> optional4=Optional.ofNullable(null);
        
        //Optional的isPresent()方法使用
        //用来验证Optional实例中的值是否有值,有值返回true,若为null则返回false
        System.out.println(optional3.isPresent());
        System.out.println(optional4.isPresent());
        
        //Optional的ifPresent()方法使用
        //是一种函数式编程接口:如果Optional中为非null,则调用consumer函数
        optional3.ifPresent(person -> person.func1());
        optional3.ifPresent(Person::func1);
        optional3.ifPresent(person -> Person.func2(person));
        optional3.ifPresent(Person::func2);
        //Optional为null,则不输出
        optional4.ifPresent(Person::func2);

        //Optional的ifPresentOrElse()方法使用
        //是一种函数式编程接口:如果Optional中为非null,则调用前面consumer函数
        optional3.ifPresentOrElse(Person::func1,Person::func3);
        //Optional为null,则调用后面的runnable函数
        optional4.ifPresentOrElse(Person::func2,Person::func3);

        //Optional的map()方法使用(传入匿名函数的参数:一个调用对象T,一个出参R)
        //map方法可以实现对Optional实例进行连续操作,如果optional中有值,就调用mapping函数得到返回值
        System.out.println(optional3.map(x1->x1.getName()));
        System.out.println(optional3.map(Person::getName));
        
        Person p1=new Person("小军", 23);
        System.out.println(optional3.map(x3 -> p1.getName()));
        
        System.out.println(optional3.map(x4->x4.func4("测试")));
        System.out.println(optional3.map(x5->Person.func5("测试")));

        System.out.println(optional3.map(x6->x6.func6()));
        System.out.println(optional3.map(Person::func6));
        System.out.println(optional3.map(x7->Person.func7()));

        //Optional为null,则调用后面的orElse/orElseGet函数
        System.out.println(optional4.map(x6->x6.func6()).orElse("Optional对象为null"));

        System.out.println(optional4.map(Person::func6).orElseGet(p1::func6));
        System.out.println(optional4.map(Person::func6).orElseGet(()->p1.func6()));
        
        System.out.println(optional4.map(Person::func6).orElseGet(Person::func7));
        System.out.println(optional4.map(Person::func6).orElseGet(()->Person.func7()));
        
        //综合测试
        //其中,ls.size()>x是判断表达式,返回结果为true/false
        //Optional.map()不为null时,orElse/orElseGet函数不影响执行结果,仅为了让返回参数为Boolean
        //Optional.map()为null时,返回orElse/orElseGet函数执行结果,否则返回Optional.empty
        List<String> list1 = Arrays.asList("aa", "bb", "cc");
        List<String> list2 = null;

        Optional<Boolean> flag1 = Optional.ofNullable(list1).map(ls -> ls.size() >= 4);
        Optional<Boolean> flag2 = Optional.ofNullable(list2).map(ls -> ls.size() >= 4);

        Boolean flag3 = Optional.ofNullable(list1).map(ls -> ls.size() >= 4).orElse(false);
        Boolean flag4 = Optional.ofNullable(list1).map(ls -> list1.size() >= 4).orElse(true);
        
        //Optional.ofNullable()返回null后,直接执行orElse/orElseGet函数,不执行map函数
        Boolean flag5 = Optional.ofNullable(list2).map(ls -> list2 == null).orElse(true);
        
        //Optional<T>和T类型转换方法
        //T转Optional<T>方法:of/ofNullable(of方法null会报错)
        //Optional<T>转T方法:get/orElse/orElseGet(get方法null会报错)
        Optional<Boolean> flag6 = Optional.ofNullable(flag5);
        Boolean flag7 = flag6.get();

        Optional<Integer> flag8 = Optional.ofNullable(list1).map(List::size);
        Optional<String> flag9 = Optional.ofNullable(list1).map(ls -> ls.get(2));

        Integer flag10 = Optional.ofNullable(list2).map(List::size).orElse(999);

        System.out.println(flag1);
        System.out.println(flag2);
        System.out.println(flag3);
        System.out.println(flag4);
        System.out.println(flag5);
        System.out.println(flag6);
        System.out.println(flag7);
        System.out.println(flag8);
        System.out.println(flag9);
        System.out.println(flag10);
        System.out.println("=====================");
        
        //可以通过map一直判空
        //map中输入的功能函数不能为null,输入的功能函数结果可以为null
        Person person11 = null;
        Person person12 = new Person();
        Person person13 = new Person("XIAO",21);
        System.out.println(Optional.ofNullable(person11).map(Person::getName));
        System.out.println(Optional.ofNullable(person12).map(Person::getName));
        System.out.println(Optional.ofNullable(person13).map(Person::getName));
        System.out.println(Optional.ofNullable(person11).map(Person::getName).orElse("出现null"));
        System.out.println(Optional.ofNullable(person12).map(Person::getName).orElse("出现null"));
        System.out.println(Optional.ofNullable(person13).map(Person::getName).orElse("出现null"));

        //可以通过map一直判空,返回Boolean
        //其中orElse方法对应ofNullable返回null执行的
        //map方法直接输出true/false
        //因此,第四个true是orElse输出的,第五/六个true是map输出的
        System.out.println(Optional.ofNullable(person11).map(person->Objects.isNull(person.getName())));
        System.out.println(Optional.ofNullable(person12).map(person->Objects.isNull(person.getName())));
        System.out.println(Optional.ofNullable(person13).map(person->Objects.isNull(person.getName())));
        System.out.println(Optional.ofNullable(person11).map(person->Objects.isNull(person.getName())).orElse(true));
        System.out.println(Optional.ofNullable(person12).map(person->Objects.isNull(person.getName())).orElse(true));
        System.out.println(Optional.ofNullable(person13).map(person->Objects.isNull(person.getName())).orElse(true));
        
    }
    
    public static String createTest(){
        System.out.println("原测试值为null--生产一个对象");
        return "新测试值002";
    }
    
}

@Data
@NoArgsConstructor
@AllArgsConstructor
class Person{

    String name;
    Integer age;

    public void func1(){
        System.out.println("执行lambda函数1");
    }

    public static void func2(Person person){
        System.out.println("执行lambda函数2"+"--"+person);
    }

    public static void func3(){
        System.out.println("执行lambda函数3");
    }
    
    public String func4(String str){
        return "返回出参4"+"--"+str;
    }

    public static String func5(String str){
        return "返回出参5"+"--"+str;
    }

    public String func6(){
        return "返回出参6";
    }

    public static String func7(){
        return "返回出参7";
    }

}

2、Stream流

package com.xch.feature01;

import cn.hutool.core.collection.CollectionUtil;
import lombok.AllArgsConstructor;
import lombok.Data;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * @author Chenghe Xu
 * @date 2022/7/26 11:50
 */
class Test07 {
    public static void main(String[] args) {
        
        List<Integer> list= Arrays.asList(6,6,7,8,8,9);
        System.out.println(list);
        
        //Stream去重
        List<Integer> list1=list.stream().distinct().collect(Collectors.toList());
        System.out.println(list1);

        //stream过滤
        List<Integer> list2=list.stream().filter(x->x==9).collect(Collectors.toList());
        List<Integer> list3=list.stream().filter(x->x==19).collect(Collectors.toList());
        System.out.println(list2);
        System.out.println(list3);

        System.out.println(Optional.ofNullable(list2.size()==0?null:list2.get(0)).orElseGet(()->null));
        System.out.println(Optional.ofNullable(list3.size()==0?null:list3.get(0)).orElseGet(()->null));
        
        System.out.println(list2.size()==0?null:list2.get(0));
        System.out.println(list3.size()==0?null:list3.get(0));
        
    }
}

/**
 * @author Chenghe Xu
 * @date 2022/7/26 16:56
 * 
 * 校验类汇总
 * null方法是判断null
 * empty方法是判断null、空串
 * blank方法是判断null、空串、空格串
 * 
 * 字符串判null、空串、空格串
 * 
 * 集合产生空集合以及判断空集合
 */
class Test08 {

    public static void main(String[] args) {
        
        String str1=null;
        String str2="";
        String str3="  ";
        
        //1、hutool的StrUtil类、ObjectUtil类、CollectionUtil类(常用)
        //isEmpty()方法判断null、空串
        //isBlank()方法判断null、空串、空格串

        //2、java的Collections类(常用)
        
        //3、springframework的Objects类、ObjectUtils类、StringUtils类、CollectionUtils类

        //测试集合拆分方法
        List<Integer> list = Arrays.asList(2, 2, 4, 4, 5, 6, 7, 8, 9);
        List<List<Integer>> split = CollectionUtil.split(list, 2);
        split.forEach(x->System.out.println(x));
        split.forEach(System.out::println);
        
        //Stream转List集合
        List<Integer> list1 = list.stream().collect(Collectors.toList());
        System.out.println(list1);

        //List集合转Set集合(去重)
        Set<Integer> set = list.stream().collect(Collectors.toSet());
        System.out.println(set);

        //List集合转Map集合(先去重)
        Map<Integer, Integer> map_1 = list.stream().distinct().collect(Collectors.toMap(x -> x, x -> x));
        Map<Integer, Integer> map_2 = list.stream().distinct().collect(Collectors.toMap(x -> x, x -> 2*x));
        Map<Integer, Integer> map_3 = list.stream().distinct().collect(Collectors.toMap(x -> x-1, x -> 2*x));
        System.out.println(map_1);
        System.out.println(map_2);
        System.out.println(map_3);
        
        //Arrays数组转Map集合(先去重或选择带重复处理的转Map方法)
        Integer[] arr = new Integer[]{22,22,33,44,55,55,66,77};
        Map<Integer, Integer> integerMap1 = Arrays.stream(arr).distinct().collect(Collectors.toMap(x -> x, Function.identity()));
        //mergeFunction参数传入(x1, x2) -> x1,代表重复则选第一个为key覆盖第二个key
        Map<Integer, Integer> integerMap2 = Arrays.stream(arr).collect(Collectors.toMap(x -> x, Function.identity(), (x1, x2) -> x1));
        System.out.println(integerMap1);
        System.out.println(integerMap2);

        //Function.identity()方法等于x->x,x->{return x;}即为原输出
        Map<Integer, Integer> map_4 = list.stream().distinct().collect(Collectors.toMap(x -> x, Function.identity()));
        System.out.println(map_4);
        //第三个参数mergeFunction提供重复key处理
        Map<Integer, Integer> map_5 = list.stream().collect(Collectors.toMap(x -> x, x -> x,(k1,k2)->k1+k2));
        System.out.println(map_5);
        
        //List集合转Map集合(分类)
        Map<Integer, List<Integer>> map1 = list.stream().collect(Collectors.groupingBy(x -> x));
        Map<Integer, List<Integer>> map2 = list.stream().collect(Collectors.groupingBy(x -> x+1));
        Map<Integer, List<Integer>> map3 = list.stream().collect(Collectors.groupingBy(x -> {return x;}));
        System.out.println(map1);
        System.out.println(map2);
        System.out.println(map3);

        //判断表达式分类
        Map<Boolean, List<Integer>> map4 = list.stream().collect(Collectors.partitioningBy(x->x>=4));
        Map<Boolean, List<Integer>> map5 = list.stream().collect(Collectors.partitioningBy(Predicate.isEqual(4)));
        System.out.println(map4);
        System.out.println(map5);
        
        //高阶综合分类测试
        List<User> users = Arrays.asList(new User("employer", 001, "徐老板")
                , new User("employee", 002, "何员工")
                , new User("employee", 003, "李员工")
                , new User("vip", 004, "黄会员")
                , new User("vip", 005, "梁会员")
                , new User("consumer", 006, "龙顾客")
                , new User("consumer", 007, "朱顾客"));

        //仅按classify分类,equals()方法判断相等则为同一类
        Map<String, List<User>> categories1 = users.stream().collect(Collectors.groupingBy(user -> user.getClassify()));
        Map<String, List<User>> categories2 = users.stream().collect(Collectors.groupingBy(user -> fetchGroupKey1(user)));
        Map<String, List<User>> categories3 = users.stream().collect(Collectors.groupingBy(Test08::fetchGroupKey1));
        System.out.println(categories1);
        System.out.println(categories2);
        System.out.println(categories3);

        //按classify和userId分类,equals()方法判断相等则为同一类
        Map<String, List<User>> categories4 = users.stream().collect(Collectors.groupingBy(user -> user.getClassify()+"-"+user.getUserId()));
        Map<String, List<User>> categories5 = users.stream().collect(Collectors.groupingBy(user -> Test08.fetchGroupKey2(user)));
        Map<String, List<User>> categories6 = users.stream().collect(Collectors.groupingBy(Test08::fetchGroupKey2));
        System.out.println(categories4);
        System.out.println(categories5);
        System.out.println(categories6);
        
    }
    
    //仅按classify分类,equals()方法判断相等则为同一类
    private static String fetchGroupKey1(User user){
        return user.getClassify();
    }

    //按classify和userId分类,equals()方法判断相等则为同一类
    private static String fetchGroupKey2(User user){
        return user.getClassify()+"-"+user.getUserId();
    }

}

@Data
@AllArgsConstructor
class User{
    
    private String classify;
    private Integer userId;
    private String userName;
    
}

3、Lambda匿名函数

package com.xch.feature01;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;

/**
 * @author Chenghe Xu
 * @date 2022/7/27 12:16
 * 
 * ::引用用法和->实现的区别
 * 
 * ::是指方法引用
 * ->是指匿名函数(Lambda)
 * 
 * 方法引用也是一种函数式接口的书写方式,Lambda表达式也是一种函数式接口;
 * Lambda表达式一般用于自己提供方法体,而方法引用一般直接引用现成的方法。
 * 
 * 方法引用分为三种,方法引用通过一对双冒号:: 来表示,方法引用是一种函数式接口的另一种书写方式
 * 1、静态方法引用,通过类名::静态方法名, 如 Student::say2
 * 2、实例方法引用,通过实例对象::实例方法,如 Student::say1、"xxx"::substring
 * 3、构造方法引用,通过类名::new, 如 Student::new
 */
public class Test09 {
    
    /**
     * 注:要实现@FunctionalInterface注解的接口,才能接收lambda匿名函数
     * 如:Supplier<T>、Predicate<T>、Function<T, R>、Consumer<T>、***Operator、Comparator<T>、Runnable
     * 其中:Predicate<T>是一个返回true/false的lambda函数表达式
     *       Comparator<T>是一个比较器的lambda函数表达式
     *        Runnable是一个无参lambda函数表达式
     * 其中:Function<T, R>的T是指调用对象,R出参,因此apply方法有返回值
     *       BiConsumer<T, U>的T是指调用对象,U是入参,因此accept方法没有返回值
     * 
     * 因此,只有可以接收这些参数的函数才能写lambda表达式
     * 能如:Stream.generate(Math::random);
     * 不能如:System.out.println(Math::random);
     */
    
    public static void main(String[] args) {
        //使用Java默认的6大承接返回功能接口对象(@FunctionalInterface注解的接口)
        //目前验最多承接三个参数(调用对象+入参<=2,出参<=1)
        
        //(T:调用对象,U:入参,R:出参)
        //调用静态方法参数顺序是:入参、出参
        //调用实例方法参数顺序是:调用对象、入参、出参
            //调用实例方法也可以用实例对象调用,参数顺序是:入参、出参
        
        //1、使用双冒号::来构造静态函数引用
        Consumer<String> say2 = Student::say2;
        Function<String, String> say4 = Student::say4;
        BiConsumer<Function<String, String>, String> dynamicSay = Student::dynamicSay;
        BiConsumer<Student, String> whoSay = Student::whoSay;
        BiFunction<Integer, String, String> upper1 = Student::upper1;

        //没有返回值void,则用Consumer对象承接,accept调用即可
        say2.accept("1Hello xch");
        dynamicSay.accept("2Hello "::concat,"xch");
        dynamicSay.accept(String::toUpperCase, "3Hello xch");
        whoSay.accept(new Student("4小金",20), "Hello");
        //有返回值Object,则用Function对象承接,apply调用即可
        System.out.println(say4.apply("5Hello xch"));
        System.out.println(upper1.apply(006, "小张"));

        //2、使用双冒号::来构造非静态函数引用
        BiConsumer<Student, String> say1 = Student::say1;
        BiFunction<Student, String, String> say3 = Student::say3;
        Student student1=new Student();
        BiFunction<Integer, String, String> upper2 = student1::upper2;

        say1.accept(new Student(),"7Hello xch");
        System.out.println(say3.apply(new Student(),"8Hello xch"));
        System.out.println(upper2.apply(9, "小杨"));

        //3、构造函数引用
        BiFunction<String, Integer, Student> obj = Student::new;
        Student student2 = obj.apply("10小徐", 21);
        System.out.println(student2);

        //测试
        String content = "Hello JDK8";
        Function<Integer, String> func1 = content::substring;
        BiFunction<Integer, Integer, String> func2 = content::substring;
        System.out.println(func1.apply(2));
        System.out.println(func2.apply(2,content.length()-1));

    }

}
/**
 * final修饰类:
 * 使用final修饰类的目的简单明确,表明这个类不能被继承。
 * 当程序中有永远不会被继承的类时,可以使用final关键字修饰。
 * 被final修饰的类所有成员方法都将被隐式修饰为final方法。
 *
 * final修饰方法:
 * 首要作用是锁定方法,不让任何继承类对其进行修改。
 * 另外一个作用是在编译器对方法进行内联,提升效率。
 *
 * final修饰变量:
 * 当final修饰的是一个基本数据类型数据时,这个数据的值在初始化后将不能被改变。(变为常量)
 * 当final修饰的是一个引用类型数据时,也就是修饰一个对象时,引用在初始化后将永远指向一个内存地址,不可修改;
 * 但是该内存地址中保存的对象信息,是可以进行修改的。
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
final class Student {

    private String sname;
    private Integer age;
    
    public void say1(String content){
        System.out.println(content);
    }
    
    public static void say2(String content){
        System.out.println(content);
    }

    public String say3(String content){
        return content;
    }

    public static String say4(String content){
        return content;
    }

    public static void dynamicSay(Function<String,String> func,String param){
        String result=func.apply(param);
        System.out.println(result);
    }
    
    public static void whoSay(Student student, String content){
        //private可以给本类直接调用
        System.out.println(student.sname + "-" + content);
    }

    public static String upper1(Integer num, String str2){
        return num+"-"+str2.toUpperCase();
    }
    
    public String upper2(Integer num,String str2){
        return num+"-"+str2.toUpperCase();
    }
    /**
     * static主要有4中使用情况:成员变量、成员方法、代码块和内部类
     * static关键字的基本作用就是:方便在没有创建对象的情况下来进行调用(方法/变量)。
     *
     * 常用static修饰成员变量为静态变量:
     * 静态变量属于类,在内存中只有一个复制,只要静态变量所在的类被加载,
     * 这个静态变量就会被分配空间,因此就可以被使用了。
     * 对静态变量的引用有两种方式,分别是“类.静态变量"和”对象.静态变量"
     * 实例变量属于对象,只有对象被创建后,实例变量才会被分配内存空间,
     * 才能被使用,它在内存中存在多个复制,只有用“对象.实例变量”的方式来引用。
     *
     * 常用static修饰成员方法为静态方法:
     * static方法是类的方法,不需要创建对象就可以被调用,而非static方法是对象的方法,
     * 只有对象被创建出来后才可以被使用,static方法中不能使用this和super关键字,
     * 不能直接调用非static方法和非static变量,只能直接访问所属类的静态成员变量和静态成员方法,
     * 因为当static方法被调用时,这个类的对象可能还没被创建,即使已经被创建了,也无法确定调用哪个对象的方法。
     */
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BB-X

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值