jdk1.8新特性(2)

自定义函数式接口编程

我们今天再次定义一个函数式接口,加强一个函数式编程思想,直接上代码,根据代码中demo可以很好帮助我们理解函数式编程。


@FunctionalInterface
interface Functions<T,K>{
    public K get(T t1,T t2);
}

public class Function {
    public static void main(String[] args) {
        //定义4个函数
        Func<Integer,Integer> add = (a,b)->a+b;
        Func<Integer,Integer> Subtraction = (a,b)->a-b;
        Func<Integer,Integer> multi = (a,b)->a*b;
        Func<Integer,Integer> division = (a,b)->a/b;
        System.out.println("加法:"+execute(add,3,3));
        System.out.println("减法:"+execute(Subtraction,3,3));
        System.out.println("乘法:"+execute(multi,3,3));
        System.out.println("除法:"+execute(division,3,3));

    }
    public static Integer execute(Func<Integer,Integer> func,Integer s1,Integer s2){
        //对你定义的函数式逻辑执行,就是执行
        // Func<String,String> func = (a,b)->a.toUpperCase() + "-" + b.toUpperCase();
        Integer s = func.get(s1, s2);
        //可以执行你自己的业务逻辑
        //**********************************
        //返回
        return s;
    }
}

结果

加法:6
减法:0
乘法:9
除法:1

JDK8自带函数式接口

Lambda表达式必须先定义接⼝,创建相关⽅法之后才可使⽤,这样做⼗分不便,其实java8已经内置了许多接⼝, 例如下⾯四个功能型接⼝,所以⼀般很少会由⽤户去定义新的函数式接⼝
Java8的最⼤特性就是函数式接⼝,所有标注了@FunctionalInterface注解的接⼝都是函数式接⼝。

函数式接口名字说明方法概述
Consumer< T>消费型接⼝:有⼊参,⽆返回值void accept(T t);
Supplier< T>供给型接⼝:⽆⼊参,有返回值T get()
Function<T, R>函数型接⼝:有⼊参,有返回值R apply(T t)
Predicate< T>断⾔型接⼝:有⼊参,有返回值,返回值类型确定是booleanboolean test(T t)

consumer

有入参,无返回值
常规调用

package com.example.demo.jdl8;

import org.apache.commons.lang3.StringUtils;
import java.util.function.Consumer;

public class Function2 {
    public static void main(String[] args) {
        //demo1 方法的函数调用,将入参打印出来,模拟消费了数据
        //Consumer<String> consumer = System.out::println;
        //上面例子不好理解可以这样写,跟上面逻辑一模一样
        Consumer<String> consumer = s->System.out.println(s);
        //常规调用
        consumer.accept("大步流星");
        consumer=s -> {
            String s1 = StringUtils.toRootUpperCase(s);
            System.out.println(s1);
        };
        //常规调用
        consumer.accept("jack is a good man");
        //*******************************************************************************
        //函数式调用
        System.out.println("函数式调用");
        execute(consumer,"jack is a good man");
    }
    public static <T> void execute(Consumer<T> consumer,T t){
        consumer.accept(t);
    }
}

结果

大步流星
JACK IS A GOOD MAN
函数式调用
JACK IS A GOOD MAN

集合的foreach函数参数就是消费函数

在这里插入图片描述
在这里插入图片描述

function

public class Function2 {
    public static void main(String[] args) {
        String s1 = "jack is a good man";
//        Function<String, String> toRootUpperCase = StringUtils::toRootUpperCase;
        Function<String, String> toRootUpperCase = s -> StringUtils.toRootUpperCase(s);
        System.out.println(execute(toRootUpperCase, s1));
    }
    public static <T> T execute(Function<T,T> function, T t){
        return function.apply(t);
    }
}

BiFunction传两个参数一个返回值

@FunctionalInterface
public interface BiFunction<T, U, R> {
 R apply(T t, U u);
}

demo


public class Function2 {
    public static void main(String[] args) {
        BiFunction<Integer,Integer,Integer> add = (a,b)->a+b;
        BiFunction<Integer,Integer,Integer> Subtraction = (a,b)->a-b;
        BiFunction<Integer,Integer,Integer> multi = (a,b)->a*b;
        BiFunction<Integer,Integer,Integer> division = (a,b)->a/b;
        System.out.println(execute(add,3,3));
        System.out.println(execute(Subtraction,3,3));
        System.out.println(execute(multi,3,3));
        System.out.println(execute(division,3,3));
    }
    public static <T> T execute(BiFunction<T,T,T> function, T t,T t1){
        return function.apply(t,t1);
    }
}

Supplier

提供者函数

    public static void main(String[] args) {
        Supplier<String> supplier = ()->"jack is good man";
        String execute = execute(supplier);
        System.out.println(execute);
    }
    public static <T> T execute(Supplier<T> function){
        return function.get();
    }

Predicate

断言

public class Function2 {
    public static void main(String[] args) {
        //断言型接口用于集合的过滤
        Predicate<String> predicate = a->a.length()>3;
        System.out.println(filter(predicate,Lists.newArrayList("aaaa","b","ccc","ddddd")));
    }
    public static <T> List<T> filter(Predicate<T> predicate,List<T> list) {
        List<T> results = new ArrayList<>();
        for (T str : list) {
            if (predicate.test(str)) {
                results.add(str);
            }
        }
        return results;
    }
}

方法的函数调用

我们之前调用方法都是对象名.方法名或者类名.方法名。现在如果将方法函数式调用需要使用::,返回最终是一个函数式对象。

public class Function2 {
    public static void main(String[] args) {
        System.out.println("************************构造方法demo开始*****************");
        //调用无参的构造方法,无入参无返回值
        Supplier<Clazz> loader = Clazz::new;
        Clazz clazz = loader.get();
        System.out.println("利用函数式接口无参构造方法创建的对象:"+ JSON.toJSONString(clazz));
        System.out.println("*****************************************");

        //构造函数参数不同,取决于function的引用,new方法永远有一个默认的返回值,就是这个对象
        //所以档没有参数是就是一个Supplier生产者,只有返回值没有参数
        //如果有一个参数,就是function,一个参数一个返回值,返回值永远是类对象
        Function<String, Clazz> stringClazzCacheLoader = Clazz::new;
        Clazz apply = stringClazzCacheLoader.apply("张三");
        System.out.println("利用函数式接口一个参构造方法创建的对象:"+JSON.toJSONString(apply));
        //两个参数的构造方法返回值就是bifunction,一次类推
        //如果jdk自带的函数式接口不满足要求,可以自定义函数式接口
        BiFunction<String, Integer, Clazz> bi = Clazz::new;
        Clazz clazz1 = bi.apply("张三", 22);
        System.out.println("利用函数式接口两个参构造方法创建的对象:"+JSON.toJSONString(clazz1));
        System.out.println("************************构造方法demo结束*****************");

        System.out.println("************************静态方法demo开始*****************");
        //getStatic没有参数 只有一个返回值,所有函数式接口为Supplier,一次类推
        Supplier<String> getStatic = Clazz::getStatic;
        System.out.println("函数式调用静态方法,返回值类型取决于参数与返回值:"+getStatic.get());
        System.out.println("************************静态方法demo结束*****************");

        System.out.println("************************实例方法demo开始*****************");
        //调用实例方法有两种,一种是根据实例调用 一种是根据类调用 根据类调用默认第一个参数为实例(这个是默认的 必须传值)
        //Clazz clazz2 = Clazz.class.newInstance();
        Clazz clazz2 = new Clazz("李四",22);
        //getName方法,没有入参  有返回值  生产者对象,也就是Supplier函数
        //第一种调用方方式 实例::方法名
        Supplier<String> getName = clazz2::getName;
        String name = getName.get();
        System.out.println("实例::方法名 调用:"+name);//李四
        //第二种调用方式 类型::实例方法 默认必须有一个参数 第一个参数必须为实例
        Function<Clazz, String> getName1 = Clazz::getName;
        String apply1 = getName1.apply(clazz2);
        System.out.println("类型::实例方法(默认必须有一个参数 第一个参数必须为实例) 调用:"+apply1);//李四
        System.out.println("************************实例方法demo结束*****************");
    }
}
class Clazz{

    private String name;
    private Integer age;

    public Clazz() {
    }

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

    public static String getStatic(){
        return "空空如也";
    }

    public Clazz getObject(){
        return this;
    }

    public String getName() {
        return name;
    }

    public Clazz(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

结果

************************构造方法demo开始*****************
利用函数式接口无参构造方法创建的对象:{"object":{"$ref":"@"}}
*****************************************
利用函数式接口一个参构造方法创建的对象:{"name":"张三","object":{"$ref":"@"}}
利用函数式接口两个参构造方法创建的对象:{"age":22,"name":"张三","object":{"$ref":"@"}}
************************构造方法demo结束*****************
************************静态方法demo开始*****************
函数式调用静态方法,返回值类型取决于参数与返回值:空空如也
************************静态方法demo结束*****************
************************实例方法demo开始*****************
实例::方法名 调用:李四
类型::实例方法(默认必须有一个参数 第一个参数必须为实例) 调用:李四
************************实例方法demo结束*****************

集合操作Stream

如图
在这里插入图片描述
数据元素:原始集合,如List、Set、Map等
生成流:可以是串⾏流stream() 或者并⾏流 parallelStream()
中间操作:可以是 排序,聚合,过滤,转换等
终端操作,很多流操作本身就会返回⼀个流,所以多个操作可以直接连接起来,最后统⼀进⾏收集

中间操作(map、filter、sort、limit、allMatch、anyMatch、max、min、reduce等函数)并行流parallelStream

详见下面代码demo

 /*****************map函数************************/
        System.out.println("--------------map start------------------------------------");
        List<String> strings = Lists.newArrayList("1", "2", "3", "4");
        //map 函数  对集合进行置换
        //例如将某个集合中的vo对象置换为pojo对象,类似与js的map函数
        //接受的是一个function函数
        List<Integer> collect = strings.stream().map(Integer::parseInt).collect(Collectors.toList());
        //同上 List<Integer> collect = strings.stream().map(s->Integer.parseInt(s)).collect(Collectors.toList());
        System.out.println("map 转换,字符换转integer :"+collect);
        System.out.println("--------------map end------------------------------------");
        System.out.println();

        System.out.println("--------------filter start------------------------------------");
        /*****************filter函数************************/
        List<String> strings1 = Lists.newArrayList("啦啦小魔仙", "小施主", "段水流", "王","",null,"a");
        //filter 接受的是一个断言函数,返回值为boolean
        List<String> collect1 = strings1.stream().filter(StringUtils::isNoneBlank).collect(Collectors.toList());
        System.out.println("filter去空:"+collect1);
        //取到字符串长度大于3的数据
        List<String> collect2 = strings1.stream().filter(s -> StringUtils.length(s) > 3).collect(Collectors.toList());
        System.out.println("filter获取字符长度大于3:"+collect2);
        System.out.println("--------------filter start------------------------------------");
        System.out.println();

        System.out.println("--------------sort start------------------------------------");
        List<String> collect3 = collect1.stream().sorted().collect(Collectors.toList());
        System.out.println("默认自然顺序排序,类需要实现Comparable接口:"+collect3);
        //自定义排序规则 自定义Comparator,实现方法
        List<String> collect4 = collect1.stream().sorted((a, b) -> b.length() - a.length()).collect(Collectors.toList());
        System.out.println("自定义排序规则,按照长度进行排序:"+collect4);

        //传递 Comparator.comparing ,传递一个function 按照集合中对象的哪个属性排序
        List<String> collect5 = collect1.stream().sorted(Comparator.comparing(a -> a.length())).collect(Collectors.toList());
        System.out.println("自定义排序规则,按照长度进行排序:"+collect5);
        //反转排序
        List<String> collect6 = collect1.stream().sorted(Comparator.comparing(a -> a.length(), Comparator.reverseOrder())).collect(Collectors.toList());

        //String::length 方法的函数调用,返回值正好是一个function函数接口
        List<String> collect7 = collect1.stream().sorted(Comparator.comparing(String::length).reversed()).collect(Collectors.toList());
        System.out.println("自定义排序规则,按照长度进行排序(倒叙):"+collect6);
        System.out.println("自定义排序规则,按照长度进行排序(倒叙):"+collect7);

        //对集合中对象进行连续排序,先按照班级排序 再按照年龄排序
        class Study{
            Integer grade;
            Integer age;
            String name;

            public Study(Integer grade, Integer age, String name) {
                this.grade = grade;
                this.age = age;
                this.name = name;
            }

            public Integer getGrade() {
                return grade;
            }

            public void setGrade(Integer grade) {
                this.grade = grade;
            }

            public Integer getAge() {
                return age;
            }

            public void setAge(Integer age) {
                this.age = age;
            }

            public String getName() {
                return name;
            }

            public void setName(String name) {
                this.name = name;
            }
        }
        List<Study> studies = Lists.newArrayList(
                new Study(10, 8, "周"),
                new Study(11, 9, "赵"),
                new Study(11, 7, "李"),
                new Study(10, 9, "王"),
                new Study(11, 8, "薛"));
        //先按照班级排序  再按照年龄排序  先排序字段再后面
        List<Study> collect8 = studies.stream().sorted(Comparator.comparing(a -> a.age))
                .sorted(Comparator.comparing(a -> a.grade)).collect(Collectors.toList());
        System.out.println("先按照班级排序  再按照年龄排序 :"+JSON.toJSONString(collect8));
        //先按照班级倒叙排序  再按照年龄倒叙排序
        List<Study> collect9 = studies.stream().sorted(Comparator.comparing(Study::getAge,Comparator.reverseOrder()))
                .sorted(Comparator.comparing(Study::getGrade).reversed()).collect(Collectors.toList());
        System.out.println("先按照班级倒叙排序  再按照年龄倒叙排序:"+JSON.toJSONString(collect9));
        System.out.println("--------------sort end------------------------------------");


        System.out.println("--------------limit start------------------------------------");
        List<String> list = Lists.newArrayList("java", "python", "javascript", "golang", "c++", "c");
        List<String> collect10 = list.stream().limit(1).collect(Collectors.toList());
        System.out.println("阶段流"+collect10);
        System.out.println("--------------limit end------------------------------------");

        System.out.println("--------------allMatch anyMatch start------------------------------------");
        List<String> list2 = Lists.newArrayList("java", "python", "javascript", "golang", "c++", "c");
        //allMatch 检查集合所有元素,都符合返回true
        boolean b = list2.stream().allMatch(StringUtils::isNoneBlank);
        System.out.println("集合所有元素是否都不为空:"+b);
        boolean b1 = list2.stream().allMatch(s -> s.length() > 3);
        System.out.println("集合所有元素长度是否都大于3:"+b1);
        //allMatch 检查集合所有元素,只要有一项符合返回true
        boolean b2 = list2.stream().anyMatch(s -> s.length() > 9);
        System.out.println("集合有元素长度都大于9:"+b2);

        System.out.println("--------------allMatch anyMatch end------------------------------------");

        System.out.println("--------------max min start------------------------------------");
        System.out.println("原始集合:"+studies);
//        Optional<Study> max = studies.stream().max((a, c) -> a.getGrade() - c.getGrade());
        Optional<Study> max = studies.stream().max((a, c) -> Integer.compare(a.getGrade(), c.getGrade()));
        Study study = max.isPresent() ? max.get() : null;
        System.out.println("最大班级是:"+study.getGrade());

        Optional<Study> min = studies.stream().min((a, c) -> a.getGrade() - c.getGrade());
        Study study1 = min.isPresent() ? min.get() : null;
        System.out.println("最小班级是:"+study1.getGrade());

        System.out.println("--------------max min end------------------------------------");

        System.out.println("--------------并⾏流parallelStream start------------------------------------");
//        线程池(ForkJoinPool)维护⼀个线程队列
//        可以分割任务,将⽗任务拆分成⼦任务,完全贴合分治思想
//        多数情况下并⾏⽐串⾏快
//        部分情况会有线程安全问题,parallelStream⾥⾯使⽤的外部变量
        List<String> arrayList = Lists.newArrayList("a", "b", "c", "d", "e");
        arrayList.parallelStream().forEach(System.out::println);

        System.out.println("--------------并⾏流parallelStream end------------------------------------");

        System.out.println("--------------reduce start------------------------------------");
//        根据⼀定的规则将Stream中的元素进⾏计算后返回⼀个唯⼀的值
        List<Integer> stringArrayList = Lists.newArrayList(1, 2, 3, 4, 5);
        stringArrayList.stream().forEach(System.out::println);
        Optional<Integer> reduce = stringArrayList.stream().reduce((a, c) -> a + c);
        Integer integer = reduce.isPresent() ? reduce.get() : 0;
        System.out.println("集合的合计:"+integer);
        Integer reduce1 = stringArrayList.stream().reduce(10, (a, c) -> a + c);
        System.out.println("增加初始值10集合的合计:"+reduce1);
        Optional<Integer> reduce2 = stringArrayList.stream().reduce((a, c) -> a > c ? a : c);
        System.out.println("集合的最大值:"+(reduce2.isPresent()?reduce2.get():0));

        System.out.println("--------------reduce end------------------------------------");

collector收集器

Collectors.toList()
Collectors.toMap()
Collectors.toSet()
Collectors.toCollection()
Collectors.toCollection(LinkedList::new)
Collectors.toCollection(CopyOnWriteArrayList::new)
Collectors.toCollection(TreeSet::new)

joining、partitioningBy分组、group by分组、summarizingInt(集合计算)

System.out.println("--------------collector收集器 start------------------------------------");

//        Collectors.toList()
//        Collectors.toMap()
//        Collectors.toSet()
//        Collectors.toCollection()
//            Collectors.toCollection(LinkedList::new)
//            Collectors.toCollection(CopyOnWriteArrayList::new)
//            Collectors.toCollection(TreeSet::new)

        System.out.println("--------------collector收集器 end------------------------------------");

        System.out.println("--------------joining start------------------------------------");
        List<String> arrayList1 = Lists.newArrayList("a", "b", "c", "d", "e");
        String collect11 = arrayList1.stream().collect(Collectors.joining());
        System.out.println("集合转字符串,没有任何分割符:"+collect11);
        String collect12 = arrayList1.stream().collect(Collectors.joining(","));
        System.out.println("集合转字符串,有分割符:"+collect12);
        String collect13 = arrayList1.stream().collect(Collectors.joining(",","[","]"));
        System.out.println("集合转字符串,有分割符并增加前缀与后缀:"+collect13);

        System.out.println("--------------joining end------------------------------------");

        System.out.println("--------------partitioningBy分组 group by分组 start------------------------------------");
        //partitioningBy分组  key是boolean类型  value:此对象的集合类型
        List<Study> studyList = Lists.newArrayList(
                new Study(10, 8, "周"),
                new Study(11, 9, "赵"),
                new Study(11, 7, "李"),
                new Study(10, 9, "王"),
                new Study(11, 8, "薛"));
        //班级大于10小于10的数据
        Map<Boolean, List<Study>> listMap = studyList.stream().collect(Collectors.partitioningBy(s -> s.getGrade() > 10));
        listMap.entrySet().forEach(s->{
            System.out.println("key:"+s.getKey() + ".value:"+JSON.toJSONString(s.getValue()));
        });
        System.out.println();
        //按年龄分组
        Map<Integer, List<Study>> map = studyList.parallelStream().collect(Collectors.groupingBy(s -> s.getAge()));
        map.entrySet().forEach(s->{
            System.out.println("key:"+s.getKey() + ".value:"+JSON.toJSONString(s.getValue()));
        });
        System.out.println("--------------collector收集器 end------------------------------------");
        System.out.println();
        //分组后统计个数
//        Map<Integer, Long> collect14 = studyList.stream().collect(Collectors.groupingBy(s -> s.getAge(), Collectors.counting()));
        Map<Integer, Long> collect14 = studyList.stream().collect(Collectors.groupingBy(Study::getAge, Collectors.counting()));
        collect14.forEach((key,value)->{
            System.out.println("key:"+key + "。value:"+value);
        });

//        summarizing
        IntSummaryStatistics collect15 = studyList.stream().collect(Collectors.summarizingInt(s -> s.getAge()));
        System.out.println("平均值:" + collect15.getAverage());
        System.out.println("⼈数:" + collect15.getCount());
        System.out.println("最⼤值:" + collect15.getMax());
        System.out.println("最⼩值:" + collect15.getMin());
        System.out.println("总和:" + collect15.getSum());

        //还可以这样计算,平均年龄,summarizingInt这个函数求
        Double collect16 = studyList.stream().collect(Collectors.averagingInt(s -> s.getAge()));
//        Double collect16 = studyList.stream().collect(Collectors.averagingInt(Study::getAge));
        System.out.println("平均年龄:"+collect16);
        Integer collect17 = studyList.stream().collect(Collectors.summingInt(s -> s.getAge()));
        System.out.println("总年龄:"+collect17);

分组包括了将list集合转为map的结构,key为同一组相同的数据,value为相同key的数据,是一个集合。如果list转map怎么转呢,就是value不是一个集合,二是一个对象,只是把key提取出来了

public class Test {
    public static void main(String[] args) {
        Study zhangsan = new Study(1,1, 10, "张三");
        Study lisi = new Study(2,1, 10, "李四");
        Study wangwu = new Study(3,2, 11, "王五");
        Study zhaoliu = new Study(4,2, 11, "赵六");
        //一个list集合
        List<Study> studies = Lists.newArrayList(zhangsan, lisi, wangwu, zhaoliu);

        //转为map key为id,id唯一,此时这么做不会报错
//        Map<Long, Study> longStudyMap = Optional.ofNullable(studies)
//                .map(a -> a.stream().collect(Collectors.toMap(Study::getId, b -> b))).orElse(new HashMap<>());
        Map<Long, Study> longStudyMap = Optional.ofNullable(studies)
                .map(a -> a.stream().collect(Collectors.toMap(Study::getId, Function.identity()))).orElse(new HashMap<>());
        System.out.println(longStudyMap);
        //result
        //{1=Test.Study(id=1, grade=1, age=10, name=张三), 2=Test.Study(id=2, grade=1, age=10, name=李四),
        // 3=Test.Study(id=3, grade=2, age=11, name=王五), 4=Test.Study(id=4, grade=2, age=11, name=null)}

        //value是名字,有一个为null会报错
        try {
            Map<Long, String> longStudyMap2 = Optional.ofNullable(studies)
                    .map(a -> a.stream().collect(Collectors.toMap(Study::getId, Study::getName))).orElse(new HashMap<>());
            System.out.println(longStudyMap2);
            //result java.lang.NullPointerException
        } catch (Exception e) {
            e.printStackTrace();
        }

        //处理value为null问题
        Map<Long, String> longStudyMap2 = Optional.ofNullable(studies)
                .map(a -> a.stream().collect(Collectors.toMap(Study::getId, s->
                      Optional.ofNullable(s).map(Study::getName).orElse("此名字是空")
                ))).orElse(new HashMap<>());
        System.out.println(longStudyMap2);
        //{1=张三, 2=李四, 3=王五, 4=moren}



        //转为map key为grade,grade不唯一,用上面的方法会报错
        //根据业务不同有不同的处理方式
        //后面覆盖前面
        Map<Integer, Study> one = Optional.ofNullable(studies).filter(s -> !s.isEmpty())
                .map(a -> a.stream().collect(Collectors.toMap(Study::getGrade, Function.identity(), (key1, key2) -> key2))).orElse(new HashMap<>());
        System.out.println(one);
        //{1=Test.Study(id=2, grade=1, age=10, name=李四), 2=Test.Study(id=4, grade=2, age=11, name=null)}

        //value 拼接起来
        Map<Integer, String> two = Optional.ofNullable(studies).filter(s -> !s.isEmpty())
                .map(a -> a.stream().collect(Collectors.toMap(Study::getGrade,Study::getName, (key1, key2) -> key1 +","+ key2))).orElse(new HashMap<>());
        System.out.println(two);
        //{1=张三,李四, 2=王五,赵六}

        //value 组成集合 同group by
        Map<Integer, List<String>> three =  Optional.ofNullable(studies).filter(s -> !s.isEmpty())
                .map(a->{
                    return a.stream().collect(Collectors.toMap(Study::getGrade, b -> {
                        List<String> getNameList = new ArrayList<>();
                        getNameList.add(b.getName());
                        return getNameList;
                    }, (List<String> value1, List<String> value2) -> {
                        value1.addAll(value2);
                        return value1;
                    }));
                }).orElseGet(HashMap::new);
        System.out.println(three);
        //{1=[张三, 李四], 2=[王五, 赵六]}

    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    static class Study{
        long id;
        Integer grade;
        Integer age;
        String name;
    }
}

利用jdk8维护一个父子结构关系的对象。

public static void main(String[] args) {

        People grandfather = People.builder().id(1).parentId(0).name("爷爷").build();
        People father = People.builder().id(2).parentId(1).name("爸爸").build();
        People uncle = People.builder().id(3).parentId(1).name("叔叔").build();
        People uncle_old = People.builder().id(4).parentId(1).name("大伯").build();

        People sister_one = People.builder().id(5).parentId(3).name("堂姐").build();
        People sister_two = People.builder().id(6).parentId(4).name("堂哥").build();

        People my = People.builder().id(7).parentId(2).name("自己").build();
        People mySon = People.builder().id(8).parentId(7).name("我儿子").build();

        List<People> people = Lists.newArrayList(grandfather, father, uncle, uncle_old, sister_one, sister_two, my, mySon);

        HashMap<String, Long> map = Maps.newHashMap();
        generate(grandfather,people,map);
        JSONObject jsonObject = new JSONObject(grandfather);

        System.out.println( jsonObject.toString());
    }

    private static void generate(People parent, List<People> people, HashMap<String, Long> map) {
        List<People> childList = Lists.newArrayList();
        Optional.ofNullable(people).filter(a->!a.isEmpty()).ifPresent(a->{
            a.stream()
                    .filter(b->!map.containsKey(String.valueOf(b.getId())))
                    .filter(b->b.getParentId() == parent.getId())
                    .forEach(b->{
                        map.put(String.valueOf(b.getId()),b.getParentId());
                        generate(b,people,map);
                        childList.add(b);
                    });
        });
        parent.setChildrenList(childList);
        Optional.ofNullable(childList).filter(a->!a.isEmpty()).ifPresent(a->parent.setParent(true));
    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @Builder
    static class People{
        long id;
        long parentId;
        String name;
        List<People> childrenList;
        boolean isParent;
    }
{
    "isParent":true,
    "name":"爷爷",
    "id":1,
    "childrenList":[
        {
            "isParent":true,
            "name":"爸爸",
            "id":2,
            "childrenList":[
                {
                    "isParent":true,
                    "name":"自己",
                    "id":7,
                    "childrenList":[
                        {
                            "isParent":false,
                            "name":"我儿子",
                            "id":8,
                            "childrenList":[

                            ],
                            "parentId":7
                        }
                    ],
                    "parentId":2
                }
            ],
            "parentId":1
        },
        {
            "isParent":true,
            "name":"叔叔",
            "id":3,
            "childrenList":[
                {
                    "isParent":false,
                    "name":"堂姐",
                    "id":5,
                    "childrenList":[

                    ],
                    "parentId":3
                }
            ],
            "parentId":1
        },
        {
            "isParent":true,
            "name":"大伯",
            "id":4,
            "childrenList":[
                {
                    "isParent":false,
                    "name":"堂哥",
                    "id":6,
                    "childrenList":[

                    ],
                    "parentId":4
                }
            ],
            "parentId":1
        }
    ],
    "parentId":0
}

新内存空间Matespace

jdk8的修改 JDK8 HotSpot JVM 使⽤本地内存来存储类元数据信息,叫做 元空间(Metaspace)
在默认情况下Metaspace的⼤⼩只与本地内存⼤⼩有关
常⽤的两个参数 -XX:MetaspaceSize=N 指Metaspace扩容时触发FullGC的初始化阈值
-XX:MaxMetaspaceSize=N 指⽤于限制Metaspace增⻓的上限,防⽌因为某些情况导致
Metaspace⽆限的使⽤本地内存
不管两个参数如何设置,都会从20.8M开始,然后随着类加载越来越多不断扩容调整直到最⼤
查看⼤⼩ jstat -gc pid MC: current metaspace capacity MU: mateaspace utilization 单位是KB

新特性之try-with-resources

 private static void test(String filepath){
	 try(OutputStream out = new FileOutputStream(filepath);) {
		 out.write((filepath+"XXXXXXXXXXXXXXXXX").getBytes());
		 } catch (Exception e) {
		 e.printStackTrace();
	 }
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值