java8新特性-流

流是Java API的新成员,它允许你以声明性方式处理数据集合(通过查询语句来表达,而不是临时编写一个实现)。就现在来说,你可以把它们看成遍历数据集的高级迭代器。此外,流还可以透明地并行处理,你无需写任何多线程代码了。
通过parallelStream或者parallel(内部调用join/fork)就能实现并行操作,需要注意的是线程安全问题及合适的方式采用并行。当然并不是所有并行性能就会好,这里涉及到装箱、拆箱、核数、当前cpu使用率等等。

public class StreamTest extends Java8BaseTest {
    @Test
    public void test() {
        //1 筛选重量大于3 2 映射获取颜色 3 去重 4 排序 5 跳过 6 截流 7 合并
        //那么点代码 干了这么多事情,想想,要是不用stream,做这些事情需要多少代码
        List colors = apples.stream().filter((Apple a) -> a.getWeight() > 3)
                .map(Apple::getColor).distinct().sorted().skip(0).limit(3).collect(toList());
        System.out.println(colors.toString());
        Assert.assertEquals(colors.size(), 3);
        Assert.assertEquals(colors.get(0), "green");


        // List转成数组
        Apple[] array = apples.toArray(new Apple[0]);
        // 输出数组
        for (int i = 0; i < array.length; i++) {
            System.out.println("array--> " + array[i]);
        }
    }

    @Test
    public void matchTest() {
        //.allMatch().noneMatch()  匹配 返回true  所以直接结束
        Assert.assertEquals(
                apples.stream().anyMatch(a -> a.getColor().equals("green")), true);

    }

    @Test
    public void findTest() {
        //.findAny() 查找
        Assert.assertEquals(apples.stream().findFirst().get().getColor(), "red");
    }

    @Test
    public void reduceTest() {
        //reduce 让我们计算下价格总和
        Apple c = new Apple(0, 0.0, "");
        double allPrice = apples.stream().reduce(c, (Apple a, Apple b) -> {
            a.setPrice(a.getPrice() + b.getPrice());
            return a;
        }).getPrice();
        //使用mapToDoublesum方法也可以实现数值相加,allPrice1这里的值为10.700000000001 精度问题  使用decimal可以解决
        double allPrice1 = apples.stream().mapToDouble(Apple::getPrice).sum();

        Assert.assertEquals(allPrice == 10.7, true);

    }

    @Test
    public void flatMapTest() {
        //flatMap的作用是将多个流合并成一个流
        List<List<Apple>> appless = new ArrayList<>();
        appless.add(apples);
        appless.add(apples);
        //获取一个流后还可以使用test1中的操作进行过滤 是否很简洁
        List<Apple> newApples = appless.stream().map((List a) -> a.toArray(new Apple[a.size()]))
                .flatMap(Arrays::stream).collect(toList());
        Assert.assertEquals(newApples.size(), apples.size() * 2);

    }

    @Test
    public void pythagoreanTripleTest() {
        //在1-100内的勾股数值  比如 3*3+4*4=5*5 这类数据
        Stream<int[]> pythagoreanTriples =
                //生成1-100的intboxed将原始流转换成一般流(不然后面操作返回数据格式就不符合而报错)  即转换为Stream<Integer>
                IntStream.rangeClosed(1, 100).boxed()
                        //因为内置还有个集合,需要使用flatMap方法将其变为一个集合,合并多个集合为一个
                        .flatMap(a ->
                                //生成a-100的int流
                                IntStream.rangeClosed(a, 100)
                                        //过滤勾股数据
                                        .filter(b -> Math.sqrt(a * a + b * b) % 1 == 0)
                                        //将Integer转换为数组 这里需要使用mapToObj 否则只能发挥Integer
                                        .mapToObj(b ->
                                                new int[]{a, b, (int) Math.sqrt(a * a + b * b)})
                        );
        pythagoreanTriples
                .forEach(t ->
                        System.out.println(t[0] + ", " + t[1] + ", " + t[2]));
    }

    @Test
    public void groupTest() {
        //分组操作
        //按颜色对apples进行分组 返回Map<String,List<Apple>> 如果不用流的话,试想下该怎么做
        //就一行代码搞定,就问简洁不简洁
        // 当然除了groupingBy 还有maxBy(最大 内部其实是通过reducingminBy(最小) summingInt(求和) summarizingInt(包括求和,平均等等都在里面) joining(连接字符串) reducing 很多方法,自行查看CollectorsMap<String, List<Apple>> maps = apples.stream().collect(groupingBy(Apple::getColor));
        System.out.println(maps.toString());
        Assert.assertEquals(maps.size(), 3);

        //groupingBy 接收的是Function 即可以返回其他的值,那么就可以在这里做些内容,比如:
        //redyellow 是我最喜欢的,返回 like ,其他为 hate
        Map<String, List<Apple>> maps1 = apples.stream().collect(groupingBy((Apple a) -> {
            if (a.getColor().equals("red") || a.getColor().equals("yellow")) {
                return "like";
            } else {
                return "hate";
            }

        }));
        System.out.println(maps1.toString());
        //groupingBy 还可以接收第二个为Collector的参数代表map中的value值 好吗~  那么基本上 Collectors方法都可以使用
        // 比如 再传一个groupingBy进行二级分组(循环下去就是N级分组) 无非就是Map又包含了Map
        // 比如 传一个counting计算个数
        Map<String, Long> maps2 = apples.stream().collect(
                groupingBy(Apple::getColor, counting()));
        System.out.println(maps2.toString());
    }

    @Test
    public void joinTest() {
        //查看joining 可知 只能接受字符串 跟我原先想的有些出入 我以为是调用类的.toString()方法获取数据
        //下面三种结果都一样,不过 joining 使用的是StringBuilder,所以方法多种多样,joining性能最佳
        String str = apples.stream().map(Apple::getColor).collect(joining());
        String str1 = apples.stream().map(Apple::getColor)
                .collect(reducing((s1, s2) -> s1 + s2)).get();
        String str2 = apples.stream()
                .collect(reducing("", Apple::getColor, (s1, s2) -> s1 + s2));
        Assert.assertEquals(str, str1);
        Assert.assertEquals(str, str2);
    }
}

你可能感兴趣的:(java8新特性)