Java函数式编程案例(JDK8新特性)

虽然现在jdk13都快出来了,但是最主流最稳定还是JDK8吧,JDK8也有很多新特性,一般新特性是对以前旧版本的优化或者衍生出的用法,我个人认为这个JDK8的函数式编程很有用,不仅可以优化代码还可以提高效率。通过看了书籍《Java 8函数式编程》自己提取出了对自己目前有用的一些操作,如果读者感觉不能满足你的需求可以看看书,顺便可以看一下《Java 8 Action》里面也有一些介绍。下面我就先上我的案例代码了哦:


import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;
import java.util.function.IntFunction;
import java.util.stream.Collectors;
import java.util.stream.IntStream;


public class Main {
    public static void main(String[] args) {
        System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~[基本数据类型列表操作]~~~~~~~~~~~~~~~~~~~~~~~~~~");
        System.out.println("---------[生成[n,m)的数组]-------------");
        int[] intArray1 = IntStream.range(2, 9).toArray();
        for (int anInt : intArray1) {
            System.out.print(anInt + "\t");
        }

        System.out.println("\n---------[生成[n,m)的列表(基本数据类型装箱)]-------------");
        List integerCollect = IntStream.range(2, 9).boxed().collect(Collectors.toList());
        integerCollect.forEach(integer -> System.out.print(integer + "\t"));

        // List获取到基本数据类型的流
        IntStream intStream = integerCollect.stream().mapToInt(Integer::intValue);

        System.out.println("\n---------[生成[n,m)的偶数数组]-------------");
        int[] intArray2 = IntStream.range(2, 9).filter(i -> i % 2 == 0).toArray();
        for (int i : intArray2) {
            System.out.print(i + "\t");
        }

        System.out.println("\n---------[[n,m)的平均数]-------------");
        double asDouble = IntStream.range(2, 9).average().getAsDouble();
        System.out.println(asDouble);

        System.out.println("---------[[n,m)的平方和]-------------");
        int sum = IntStream.range(2, 9).map(x -> x * x).sum();
        System.out.println(sum);

        System.out.println("---------[[n,m)的最大奇数]-------------");
        int reduce = IntStream.range(2, 9).filter(x -> x % 2 != 0).max().getAsInt();
        System.out.println(reduce);

        System.out.println("---------[[n,m)的水仙花数]-------------");
        int[] ints = IntStream.range(1, 10000).filter(i -> isNarcissisticNumber(i)).toArray();
        for (int anInt : ints) {
            System.out.print(anInt + "\t");
        }

        System.out.println("\n---------[1到3随机生成两个数乘积的概率]-------------");
        // 表示N次,N越大概率越准确
        final int N = 100000;
        double val = 1.0 / N;
        // 因为测试的数量大就是用了并行流,效率高点
        Map collect =
                IntStream.range(0, N).parallel().mapToObj(nxm()).collect(Collectors.groupingBy(x -> x,
                        Collectors.summingDouble(x -> val)));
        collect.entrySet().forEach(value -> System.out.println(value.toString()));

        System.out.println("\n~~~~~~~~~~~~~~~~~~~~~~~~~~[实体列表操作]~~~~~~~~~~~~~~~~~~~~~~~~~~");
        List userList = new ArrayList<>();
        userList.add(new Person(21, "张三", 1, "深圳"));
        userList.add(new Person(12, "张思", 0, "上海"));
        userList.add(new Person(32, "李四", 1, "武汉"));
        userList.add(new Person(21, "王五", 0, "北京"));
        userList.add(new Person(22, "赵器", 0, "武汉"));
        System.out.println("---------[按城市分组获取全部信息]-------------");
        Map> personCollect = userList.stream().collect(Collectors.groupingBy(Person::getCity));
        personCollect.entrySet().forEach(value -> System.out.println(value.toString()));

        System.out.println("---------[按城市分组获取个数]-------------");
        Map numCollect = userList.stream().collect(Collectors.groupingBy(Person::getCity, Collectors.counting()));
        numCollect.entrySet().forEach(value -> System.out.println(value.toString()));

        System.out.println("---------[按城市分组获取个人姓名]-------------");
        Map> nameCollect = userList.stream().collect(Collectors.groupingBy(Person::getCity, Collectors.mapping(Person::getName,
                Collectors.toList())));
        nameCollect.entrySet().forEach(value -> System.out.println(value.toString()));

        System.out.println("---------[按年龄排序]-------------");
        List ageCollect = userList.stream().sorted(Comparator.comparingInt(Person::getAge)).collect(Collectors.toList());
        ageCollect.forEach(person -> System.out.println(person.toString()));

        System.out.println("---------[按照年龄排序只要年龄数据]-------------");
        List personAgecollect = userList.stream().map(Person::getAge).sorted().collect(Collectors.toList());
        personAgecollect.forEach(age -> System.out.print(age + "\t"));

        System.out.println("\n---------[过滤sex为1的数据]-------------");
        List filterSexCollect = userList.stream().filter(person -> person.getSex() != 1).collect(Collectors.toList());
        filterSexCollect.forEach(person -> System.out.println(person.toString()));

        System.out.println("---------[年龄总和]-------------");
        Integer sum1 = userList.stream().map(Person::getAge).mapToInt(Integer::intValue).sum();
        Integer sum2 = userList.stream().map(Person::getAge).reduce(0, (x, y) -> x + y);
        System.out.println("基本数据类型流求和:"+sum1);
        System.out.println("封装数据类型流求和:"+sum2);
    }

    /**
     * 判断是否是水仙花数
     *
     * @param a
     * @return
     */
    private static Boolean isNarcissisticNumber(Integer a) {
        // 水仙花数位数是3位开始
        if (a < 100) {
            return false;
        }
        Integer x = a;
        Integer sum = 0;
        while (x > 0) {
            int m = x % 10;
            sum += m * m * m;
            x = x / 10;
        }
        return sum.equals(a);
    }

    /**
     * 获取随机数的乘积
     *
     * @return
     */
    private static IntFunction nxm() {
        return i -> {
            ThreadLocalRandom random = ThreadLocalRandom.current();
            int i1 = random.nextInt(1, 4);
            int i2 = random.nextInt(1, 4);
            return i1 * i2;
        };
    }

}

@Setter
@Getter
@ToString
@AllArgsConstructor
class Person {
    private Integer age;
    private String name;
    private Integer sex;
    private String city;

}

结果如下:

Java函数式编程案例(JDK8新特性)_第1张图片

Java函数式编程案例(JDK8新特性)_第2张图片

总结:

1、Java8采用的是Stream流,这个流分为了并行流和一般流,并行流是数据量大CPU占用高的情况下可以选择并行流,其实主要看机器的性能了。

2、IntStream,LongStream,DoubleStream这些主要是基本数据流,如果要返回封装数据类型调用.boxed()方法

例如:IntStream.range(2, 9).boxed()

3、List的封装数据类型要获取基本数据流,

例如:list.stream().mapToInt(Integer::intValue);

4、可以把条件抽出来独立成函数,减少代码冗余

5、流求值方法有两种:惰性求值法、及早求值法,

惰性求值一般可以理解为记录流的条件,及早求值可以理解为直接获取结果;

例如:IntStream intStream = IntStream.range(2,9); 这个是惰性求值法应用,根据这个流后面还可以加条件,还没有遍历

List integerCollect = IntStream.range(2, 9).boxed().collect(Collectors.toList());这个是及早值求值法的应用,直接根据流获取到结果了,一般我们都采用这个及早值获取结果
因为传统业务都是传集合等,所以很多数据都是固定的,但是有可能可以使用流在后端调用操作,这样调用方直接可以加条件后才会遍历,调用方要什么信息都可以根据自己要求去获取,并且效率也提高了。那本书里面是这么建议的。

6、使用reduce时候前面那个前置的值一定要弄清楚,不是可能会影响最后的结果;

7.。。。。。。。后面发现继续补充,读者们有什么好滴建议都可以发送在评论哦。 

《………………………………………………菜鸟起飞中,请各位走过路过的多多指教……………………………………》

                                                                       

你可能感兴趣的:(java,工具类)