java8-stream-流操作

java 发展史
在这里插入图片描述

java8-stream-流操作
java 8 全新引入的Stream API 核心接口就是:
java.util.stream.Stream< T > 接口
好处:
代码简洁
代码语义清晰

代码示例:

公共部分代码

package com.test.testjavaee;

import lombok.Data;		
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @date 2018/7/24 16:45
 * @since
 */
public class Java8_stream {

    public static void main(String[] args) {
		List<Temp> temps = new ArrayList<>();
		temps.add(new Temp("张三", 18, 800, "2017/06/15 14:11:17"));
		temps.add(new Temp("李四", 19, 1500, "2017/06/14 14:11:17"));
		temps.add(new Temp("王五", 25, 2000, "2017/06/16 13:11:17"));
		temps.add(new Temp("王五1", 19, 900, "2017/06/16 14:10:17"));
		temps.add(new Temp("王五2", 21, 1800, "2017/06/17 14:11:17"));
		
		//**1,创建 stream 的几种方式
        testCreateStream();
        //**2,filter,中间操作,对list 集合进行条件判断,留下满足条件的数据。
        testFilter();
        //**3,map,中间操作
        testMap();
        //4,flatMap 合并两个流
        testFlatMap();
        //5,distinct,中间操作,去重
        testDistinact(temps);
        //6,peek,中间操作
        testPeek(temps);

        //7,spike,limit,中间操作
        testSpikeAndLimit();
// ========================以下为终端操作=========================================
        //**8,接口终端操作,forEach,forEachOrdered
        testForEach(temps);
        //9,终端操作 toArray,把集合转换成数组
        testToArray(temps);
        //10,终端操作,min,max
        testMinAndMax(temps);
        //11,终端操作,findFirst,findAny
        testFindFirstAndFindAny(temps);
        //12,终端操作,count,anyMatch,allMatch,noneMatch
        test_count_anyMatch_allMatch_noneMatch();
        //13,终端操作,reduce,可以用来累计求和等操作
        testReduce();
        //**14,终端操作,collect,归约操作的方式collect,收集器操作,收集器操作,可以当做是一种更高级的归约操作;
        testCollect(temps);
        //在java8中,很多的stream的终端操作,都返回了一个Optional<T>对象,这个对象,是用来解决空指针的问题,而产生的一个类
	}
}

@Data
class Temp{
    String name;
    int age;
    double salary;
    String brithday;

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

    public Temp(String name, int age, double salary){
        this.name = name;
        this.age = age;
        this.salary = salary;
    }

    public Temp(String name, int age, double salary, String brithday){
        this.name = name;
        this.age = age;
        this.salary = salary;
        this.brithday = brithday;
    }
}

1,创建 stream 的几种方式:

private static void testCreateStream(){
    System.out.println("执行创建stream 方法=====================");
    String[] aa = {"a", "b", "c"};
    //方式一
    Arrays.stream(aa).forEach(System.out::print);
    System.out.println();
    //方式二
    Stream.of(aa).forEach(System.out::print);
    System.out.println();
    //方式三,最常用的一种方式
    Arrays.asList(aa).stream().forEach(System.out::print);
    System.out.println();
    //方式四
    Stream.iterate(0, x -> x + 1).limit(10).forEach(temp -> System.out.print(temp));
    System.out.println();
}

2,filter,中间操作,对list 集合进行条件判断,留下满足条件的数据:

private static void testFilter() {
    //.filter(当前对象 -> )
    Arrays.stream(new String[]{"a","b","c"}).filter(temp -> "c".equals(temp)).forEach(System.out::print);
    System.out.println();
}

3,map,中间操作,把当前对象转换成其他类型:

private static void testMap() {
    /*作用:
        可以用来对对象也可以是基本数据类型也可以是引用类型,进行处理后返回
        可以用来对对象中的某个元素进行操作并返回,如只返回该对象中的某个字段
        可以对当前对象进行转换,如把 json 转成对象。
        <R> Stream<R> map(Function<? super T, ? extends R> mapper);
        这个接口,接收一个泛型T,返回泛型R,map函数的定义,返回的流,表示的泛型是R对象,这个表示,调用这个函数后,可以改变返回的类型,
     */
    Stream<Integer> stream = Arrays.stream(new Integer[]{1, 2, 3});
    stream.map(str -> Integer.toString(str)).forEach(i -> {
        System.out.print(i + " ");
    });

    List<Temp> temps = Arrays.asList(new Temp("a", 21, 800), new Temp("b", 25, 1800), new Temp("c", 19, 2000));
    //方式一  .map(当前对象 -> 对当前对象进行操作并返回操作的结果)
    temps.stream().map(temp -> temp.getName()).forEach(name -> System.out.print(name));
    System.out.println();
    //方式二
    temps.stream().map(Temp::getName).forEach(name -> System.out.print(name));
    System.out.println();
    temps.stream().map(temp -> temp.getName().toUpperCase()).collect(Collectors.toList()).forEach(System.out::print);
    System.out.println();
    temps.stream().map(Temp::getName).map(temp -> (temp + "_").toUpperCase()).collect(Collectors.toList()).forEach(System.out::print);
    System.out.println();
    temps.stream().filter(temp -> temp.getAge() > 20).map(temp -> temp.getAge() * 2).collect(Collectors.toList()).forEach(temp-> System.out.print(temp + " "));
    
}

4,flatMap 合并两个流:

private static void testFlatMap() {
    String[] strings = {"aaa", "bbb", "ccc"};
    String[] strings2 = {"d", "e", "f"};

    Arrays.stream(strings).map(str -> str.split("")).flatMap(Arrays::stream).forEach(str-> System.out.print(str));
}

5,distinct、sorted 中间操作,去重、排序:

private static void testDistinact(List<Temp> temps) {
    //去重,排序
    //默认为升序,
        //根据某个字段升序排序, .sorted(Comparator.comparing(Temp::getAge))

    Arrays.asList(1, 4, 1, 2, 3).stream().distinct().sorted().forEach(i -> System.out.print(i));
    System.out.println();
    //设置为降序
    Arrays.asList("1", "4", "1", "2", "3").stream().distinct().sorted(Comparator.reverseOrder()).forEach(str -> System.out.print(str));

    System.out.println();
    //根据某个字段降序排序, .sorted(Comparator.comparing(Temp::getBrithday).reverseOrder())
    List<Temp> collect = temps.stream().sorted(Comparator.comparing(Temp::getBrithday).reversed()).collect(Collectors.toList());
    collect.forEach(temp -> System.out.println(temp.toString()));

}

6,peek,中间操作,:

private static void testPeek(List<Temp> temps) {
    //方式一
    Stream<Temp> peek = temps.stream().filter(temp ->
        temp.getAge() > 20
    ).peek(temp -> {
        temp.setSalary(temp.getSalary() * 2);
    });
    //方式二
//        Stream<Temp> peek = temps.stream().filter(temp -> {
//            return temp.getAge() > 20;
//        }).peek(temp -> {
//            temp.setSalary(temp.getSalary() * 2);
//        });
    peek.forEach(temp -> System.out.println(temp.getSalary()));

}

7,spike,limit,中间操作,跳过、限制数量:

private static void testSpikeAndLimit() {
  	//无限流,从 1 开始。
  	Stream.iterate(1, x -> ++x).skip(5).limit(10).forEach(temp-> System.out.print(temp + " "));
}

============================ 以下为终端操作 ==================================

8,接口终端操作,forEach,forEachOrdered:

 private static void testForEach(List<Temp> temps) {
    List<Integer> list = temps.stream().map(Temp::getAge).collect(Collectors.toList());
    //串行执行
    list.stream().forEach(age -> System.out.print(age + " ") );
    System.out.println();
    list.stream().forEachOrdered(age-> System.out.print(age + " "));
    System.out.println();
    //parallelStream 并行执行,forEach 输出的顺序会乱,forEachOrdered 不会乱
    list.parallelStream().forEach(age-> System.out.print(age + " "));
    System.out.println();
    list.parallelStream().forEachOrdered(age-> System.out.print(age + " "));
}

9,终端操作 toArray,把集合转换成数组:

 private static void testToArray(List<Temp> temps) {
    List<Integer> list = temps.stream().map(temp -> temp.getAge()).collect(Collectors.toList());
    //使用 stream 把集合转换成数组
    //方式一,指明类型
    Integer[] integers = list.stream().toArray(Integer[]::new);
    System.out.print(integers.toString() + " ");
    //方式二
    Integer[] integers1 = list.stream().toArray(temp -> new Integer[list.size()]);
    //方式三,未指明类型
    Object[] objects = list.stream().toArray();
    //使用 list 自带的 toArray 方法进行转换
    Integer[] integers2 = list.toArray(new Integer[list.size()]);
    Object[] objects1 = list.toArray();
}

10,终端操作,min,max:

private static void testMinAndMax(List<Temp> temps) {
    List<Double> list = temps.stream().map(Temp::getSalary).collect(Collectors.toList());
    //方式一,Function.identity()
    Optional<Double> min = list.stream().min(Comparator.comparing(Function.identity()));
    Double d = min.get();
    System.out.println("min 方式一 --->" + d);
    //方式二
    Double d2 = list.stream().min((o1, o2) -> o1.compareTo(o2)).get();
    System.out.println("min 方式二 --->" + d2 + "\n");

    Double d3 = list.stream().max(Comparator.comparing(Function.identity())).get();
    System.out.println("max 方式一 --->" + d3);
    Double d4 = list.stream().max((o1, o2) -> o1.compareTo(o2)).get();
    System.out.println("max 方式二 --->" + d4 + "\n");

    System.out.println(String.format("min:%s;max:%s", d, d3));
}

11,终端操作,findFirst,findAny:

private static void testFindFirstAndFindAny(List<Temp> temps) {
    /*findFirst和findAny,通过名字,就可以看到,
    对这个集合的流,做一系列的中间操作后,
    可以调用findFirst,返回集合的第一个对象,
    findAny返回这个集合中,取到的任何一个对象;
     */
    List<String> list = temps.stream().map(Temp::getName).collect(Collectors.toList());
    //未进行中间操作
    Optional<String> first = list.stream().findFirst();
    String s = first.get();
    Optional<String> any = list.stream().findAny();
    String s1 = any.get();

    Optional<String> first1 = list.parallelStream().findFirst();
    String s2 = first1.get();
    String s3 = list.parallelStream().findAny().get();

    System.out.println(s + " ====> " + s2);
    System.out.println(s1 + " =====> " + s3);

    System.out.println("======================================");
    //进行中间操作
    String s4 = list.stream().filter(temp -> !"李四".equals(temp)).findFirst().get();
    String s5 = list.stream().filter(temp -> !"李四".equals(temp)).findAny().get();

    String s6 = list.parallelStream().filter(temp -> !"李四".equals(temp)).findFirst().get();
    String s7 = list.parallelStream().filter(temp -> !"李四".equals(temp)).findAny().get();
    System.out.println(s4 + " -----> " + s6);
    System.out.println(s5 + " -----> " + s7);

}

12,终端操作,count,anyMatch,allMatch,noneMatch:

private static void test_count_anyMatch_allMatch_noneMatch() {
    List<String> list = Arrays.asList("a", "a", "a", "a", "b", "c", "a");
    //anyMatch表示,判断的条件里,任意一个元素成功,返回true
    boolean b = list.stream().anyMatch(temp -> "a".equals(temp));
    //allMatch表示,判断条件里的元素,所有的都是,返回true
    boolean b1 = list.stream().allMatch(temp -> "a".equals(temp));
    //noneMatch跟allMatch相反,判断条件里的元素,所有的都不是,返回true
    boolean b2 = list.stream().noneMatch(temp -> "a".equals(temp));
    //返回集合的记录数
    long count = list.stream().count();
    long count1 = list.stream().filter(temp -> "a".equals(temp)).count();

    System.out.println(b);
    System.out.println(b1);
    System.out.println(b2);
    System.out.println(count);
    System.out.println(count1);
}

13,终端操作,reduce,可以用来累计求和等操作:

private static void testReduce() {
    //reduce 是一种归约操作,将流归约成一个值的操作叫做归约操作,用函数式编程语言的术语来说,这种称为折叠(fold);
    List<Integer> list = Stream.iterate(1, x -> ++x).limit(10).collect(Collectors.toList());
    //jdk1.7 的做法
    Integer i = 0;
    for (Integer integer : list){
        i += integer;
    }
    //方式一
    Integer reduce = list.stream().reduce(0, (a, b) -> a + b, (a, b) -> a - b);
    //方式二
    Integer integer = list.stream().reduce((a, b) -> a + b).get();
    System.out.println(i);
    System.out.println(reduce);
    System.out.println(integer);
}

14,终端操作,collect,归约操作的方式collect,收集器操作,收集器操作,可以当做是一种更高级的归约操作:

private static void testCollect(List<Temp> temps) {
    //转 list
    List<String> list = temps.stream().map(Temp::getName).collect(Collectors.toList());
    
    //转 set
    Set<Integer> set = temps.stream().map(temp -> temp.getAge()).collect(Collectors.toSet());

    //转 map,需要指定key 和 value,Function.identity() 是指当前 Temp 对象本身,当key重复时会报错。
    Map<String, Temp> map = temps.stream().collect(Collectors.toMap(Temp::getName, Function.identity()));
    Map<String, Temp> map2 = temps.stream().collect(Collectors.toMap(Temp::getName, temp -> temp));

    //计算元素中的个数
    Long collect = temps.stream().collect(Collectors.counting());

    //数据求和 sumingInt,sumingLong,sumingDouble
    Integer collect1 = temps.stream().collect(Collectors.summingInt(temp -> temp.getAge()));
    Integer collect13 = set.stream().collect(Collectors.summingInt(temp -> temp));
    System.out.println(collect1 + " max ---> " + collect13);

    //数据求平均值
    Double collect2 = temps.stream().collect(Collectors.averagingDouble(Temp::getSalary));

    //综合处理,求最大值,最小值,平均值,求和
    IntSummaryStatistics collect3 = temps.stream().collect(Collectors.summarizingInt(Temp::getAge));
    System.out.println(collect3.getMax());
    System.out.println(collect3.getMin());
    System.out.println(collect3.getSum());
    System.out.println(collect3.getAverage());
    System.out.println(collect3.getCount());

    //连接字符串
    String collect4 = temps.stream().map(temp -> temp.getName()).collect(Collectors.joining());
    String collect5 = temps.stream().map(Temp::getName).collect(Collectors.joining(","));
    String collect6 = temps.stream().map(Temp::getName).collect(Collectors.joining("--中间分隔符--", "前缀*", "&后缀"));
    System.out.println("字符串连接1 --> " + collect4);//张三李四王五王五1王五2
    System.out.println("字符串连接2 --> " + collect5);//张三--中间分隔符--李四--中间分隔符--王五--中间分隔符--王五1--中间分隔符--王五2
    System.out.println("字符串连接3 --> " + collect6);//前缀*张三--中间分隔符--李四--中间分隔符--王五--中间分隔符--王五1--中间分隔符--王五2&后缀

    //maxBy 按照比较器中比较结果筛选 最大值 -- 取出来的不是最大值 或 最小值
    Optional<Integer> collect7 = temps.stream().map(Temp::getAge).collect(Collectors.maxBy(Integer::max));
    System.out.println("maxBy比较器筛选最大值:" + collect7.get());//18
    Optional<Integer> collect8 = temps.stream().map(Temp::getAge).collect(Collectors.minBy(Integer::min));
    System.out.println("minBy比较器筛选最小值:" + collect8.get());//21

    //归约操作
    Optional<Integer> collect9 = temps.stream().map(Temp::getAge).collect(Collectors.reducing((x, y) -> (x + y)));
    Integer collect10 = temps.stream().map(Temp::getAge).collect(Collectors.reducing(0, (x, y) -> (x + y)));
    System.out.println("归约操作1:" + collect9.get());
    System.out.println("归约操作2:" + collect10);

    //分组操作
    Map<Integer, List<Temp>> collect11 = temps.stream().collect(Collectors.groupingBy(Temp::getAge));
    collect11.forEach((k,v)-> System.out.println("分组操作:" + k + " " + v.size()));

    //分区操作
    Map<Boolean, List<Integer>> collect12 = temps.stream().map(Temp::getAge).collect(Collectors.partitioningBy(age -> age > 20));
    collect12.forEach((k,v)-> System.out.println("分区操作:" + k + " " + v.size()));

}

注意事项:使用stream的toMap()函数时,当key重复,系统会报错相同的key不能形成一个map,那么需要解决这个问题,一:相同key的情况下,丢弃重复的只保留一个,二:相同key的情况下,把value变成list,形成Map(Object,List)的形式。

报错写法:

String[] arr = {"1@1","2@2","3@3","1@4","5@5","6@6"};
// 重复 key 报错的写法
Map<String, String> collect = Stream.of(arr).map(temp -> temp.split("@")).collect(Collectors.toMap(str -> str[0], str -> str[1]));

报错内容:

Exception in thread "main" java.lang.IllegalStateException: Duplicate key 1
	at java.util.stream.Collectors.lambda$throwingMerger$0(Collectors.java:133)
	at java.util.HashMap.merge(HashMap.java:1253)
	at java.util.stream.Collectors.lambda$toMap$58(Collectors.java:1320)
	at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
	at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
	at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
	at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
	at com.example.test.java_base.java8.Java8Test.toMapDuplicateKey(Java8Test.java:20)
	at com.example.test.java_base.java8.Java8Test.main(Java8Test.java:12)

处理方式一:后一个 value 覆盖前一个 value 值:

private static void toMapDuplicateKey() {
   String[] arr = {"1@1","2@2","3@3","1@4","5@5","6@6"};
    
    Map<String, String> collect = Stream.of(arr).map(temp -> temp.split("@"))
            .collect(Collectors.toMap(str -> str[0], str -> str[1], (v1,v2) -> v2));
    System.out.println(collect); // 打印结果:{1=4, 2=2, 3=3, 5=5, 6=6}
}

处理方式二:当 key 重复,使用 “旧值,新值” 的方式处理:

private static void toMapDuplicateKey2(List<Temp> temps) {
	List<Temp> temps = new ArrayList<>();
    temps.add(new Temp("张三", 18, 800, "2017/06/15 14:11:17"));
    temps.add(new Temp("李四", 19, 1500, "2017/06/14 14:11:17"));
    temps.add(new Temp("王五", 25, 2000, "2017/06/16 13:11:17"));
    temps.add(new Temp("李四2", 19, 900, "2017/06/16 14:10:17"));
    temps.add(new Temp("王五2", 21, 1800, "2017/06/17 14:11:17"));
    temps.add(new Temp("王五3", 19, 1800, "2017/06/17 14:11:17"));
    
    Map<Integer, String> collect = temps.stream().collect(Collectors.toMap(
            temp -> temp.getAge(),
            temp -> temp.getName(),
            (oldValue, newValue) -> oldValue + "," + newValue
    ));
    System.out.println(collect); // 打印结果:{18=张三, 19=李四,李四2,王五3, 21=王五2, 25=王五}

    // 覆盖值的写法
	Map<String, Temp> accountMap = accountBatch.stream().collect(Collectors.toMap(Temp::getName, v1 -> v1, (v1,v2) -> v1));
	// 上面的写法等同于
	Map<String, Temp> accountMap = accountBatch.stream().collect(Collectors.toMap(temp -> temp.getAge(), v1 -> v1, (v1,v2) -> v1));


}

处理方式三:当key重复,使用 list 集合收集:

private static void toMapDuplicateKey2() {
   List<Temp> temps = new ArrayList<>();
    temps.add(new Temp("张三", 18, 800, "2017/06/15 14:11:17"));
    temps.add(new Temp("李四", 19, 1500, "2017/06/14 14:11:17"));
    temps.add(new Temp("王五", 25, 2000, "2017/06/16 13:11:17"));
    temps.add(new Temp("李四2", 19, 900, "2017/06/16 14:10:17"));
    temps.add(new Temp("王五2", 21, 1800, "2017/06/17 14:11:17"));

    Map<Integer, List<String>> collect = temps.stream().collect(Collectors.toMap(
            Temp::getAge,
            temp -> {
                List<String> list = new ArrayList<String>();
                list.add(temp.getName());
                return list;
            },
            (List<String> oldList, List<String> newList) -> {
                oldList.addAll(newList);
                return oldList;
            }));
    System.out.println(collect); // 打印结果: {18=[张三], 19=[李四, 李四2], 21=[王五2], 25=[王五]}
}

完整的代码,如下:

package com.test.testjavaee;

import lombok.Data;		
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @date 2018/7/24 16:45
 * @since
 */
public class Java8_stream {

    public static void main(String[] args) {

        List<Temp> temps = new ArrayList<>();
        temps.add(new Temp("张三", 18, 800, "2017/06/15 14:11:17"));
        temps.add(new Temp("李四", 19, 1500, "2017/06/14 14:11:17"));
        temps.add(new Temp("王五", 25, 2000, "2017/06/16 13:11:17"));
        temps.add(new Temp("王五1", 19, 900, "2017/06/16 14:10:17"));
        temps.add(new Temp("王五2", 21, 1800, "2017/06/17 14:11:17"));


        //**1,创建 stream 的几种方式
//        testCreateStream();

        //**2,filter,中间操作,对list 集合进行条件判断,留下满足条件的数据。
//        testFilter();

        //**3,map,中间操作
//        testMap();

        //4,flatMap 合并两个流
//        testFlatMap();

        //5,distinct,中间操作,去重
        testDistinact(temps);

        //6,peek,中间操作
//        testPeek(temps);

        //7,spike,limit,中间操作
//        testSpikeAndLimit();

// =================================================================

        //**8,接口终端操作,forEach,forEachOrdered
//        testForEach(temps);

        //9,终端操作 toArray,把集合转换成数组
//        testToArray(temps);

        //10,终端操作,min,max
//        testMinAndMax(temps);

        //11,终端操作,findFirst,findAny
//        testFindFirstAndFindAny(temps);

        //12,终端操作,count,anyMatch,allMatch,noneMatch
//        test_count_anyMatch_allMatch_noneMatch();

        //13,终端操作,reduce,可以用来累计求和等操作
//        testReduce();

        //**14,终端操作,collect,归约操作的方式collect,收集器操作,收集器操作,可以当做是一种更高级的归约操作;
        testCollect(temps);

        //在java8中,很多的stream的终端操作,都返回了一个Optional<T>对象,这个对象,是用来解决空指针的问题,而产生的一个类

    }

    private static void testCollect(List<Temp> temps) {
        //转 list
        List<String> list = temps.stream().map(Temp::getName).collect(Collectors.toList());

        //转 set
        Set<Integer> set = temps.stream().map(temp -> temp.getAge()).collect(Collectors.toSet());

        //转 map,需要指定key 和 value,Function.identity() 是指当前 Temp 对象本身,当key重复时会报错。
        Map<String, Temp> map = temps.stream().collect(Collectors.toMap(Temp::getName, Function.identity()));
        Map<String, Temp> map2 = temps.stream().collect(Collectors.toMap(Temp::getName, temp -> temp));

        //计算元素中的个数
        Long collect = temps.stream().collect(Collectors.counting());

        //数据求和 sumingInt,sumingLong,sumingDouble
        Integer collect1 = temps.stream().collect(Collectors.summingInt(temp -> temp.getAge()));
        Integer collect13 = set.stream().collect(Collectors.summingInt(temp -> temp));
        System.out.println(collect1 + " max ---> " + collect13);

        //数据求平均值
        Double collect2 = temps.stream().collect(Collectors.averagingDouble(Temp::getSalary));

        //综合处理,求最大值,最小值,平均值,求和
        IntSummaryStatistics collect3 = temps.stream().collect(Collectors.summarizingInt(Temp::getAge));
        System.out.println(collect3.getMax());
        System.out.println(collect3.getMin());
        System.out.println(collect3.getSum());
        System.out.println(collect3.getAverage());
        System.out.println(collect3.getCount());

        //连接字符串
        String collect4 = temps.stream().map(temp -> temp.getName()).collect(Collectors.joining());
        String collect5 = temps.stream().map(Temp::getName).collect(Collectors.joining(","));
        String collect6 = temps.stream().map(Temp::getName).collect(Collectors.joining("--中间分隔符--", "前缀*", "&后缀"));
        System.out.println("字符串连接1 --> " + collect4);//张三李四王五王五1王五2
        System.out.println("字符串连接2 --> " + collect5);//张三--中间分隔符--李四--中间分隔符--王五--中间分隔符--王五1--中间分隔符--王五2
        System.out.println("字符串连接3 --> " + collect6);//前缀*张三--中间分隔符--李四--中间分隔符--王五--中间分隔符--王五1--中间分隔符--王五2&后缀

        //maxBy 按照比较器中比较结果筛选 最大值 -- 取出来的不是最大值 或 最小值
        Optional<Integer> collect7 = temps.stream().map(Temp::getAge).collect(Collectors.maxBy(Integer::max));
        System.out.println("maxBy比较器筛选最大值:" + collect7.get());//18
        Optional<Integer> collect8 = temps.stream().map(Temp::getAge).collect(Collectors.minBy(Integer::min));
        System.out.println("minBy比较器筛选最小值:" + collect8.get());//21

        //归约操作
        Optional<Integer> collect9 = temps.stream().map(Temp::getAge).collect(Collectors.reducing((x, y) -> (x + y)));
        Integer collect10 = temps.stream().map(Temp::getAge).collect(Collectors.reducing(0, (x, y) -> (x + y)));
        System.out.println("归约操作1:" + collect9.get());
        System.out.println("归约操作2:" + collect10);

        //分组操作
        Map<Integer, List<Temp>> collect11 = temps.stream().collect(Collectors.groupingBy(Temp::getAge));
        collect11.forEach((k,v)-> System.out.println("分组操作:" + k + " " + v.size()));

        //分区操作
        Map<Boolean, List<Integer>> collect12 = temps.stream().map(Temp::getAge).collect(Collectors.partitioningBy(age -> age > 20));
        collect12.forEach((k,v)-> System.out.println("分区操作:" + k + " " + v.size()));

    }

    private static void testReduce() {
        //reduce 是一种归约操作,将流归约成一个值的操作叫做归约操作,用函数式编程语言的术语来说,这种称为折叠(fold);
        List<Integer> list = Stream.iterate(1, x -> ++x).limit(10).collect(Collectors.toList());
        //jdk1.7 的做法
        Integer i = 0;
        for (Integer integer : list){
            i += integer;
        }
        //方式一
        Integer reduce = list.stream().reduce(0, (a, b) -> a + b, (a, b) -> a - b);
        //方式二
        Integer integer = list.stream().reduce((a, b) -> a + b).get();
        System.out.println(i);
        System.out.println(reduce);
        System.out.println(integer);


    }

    private static void test_count_anyMatch_allMatch_noneMatch() {
        List<String> list = Arrays.asList("a", "a", "a", "a", "b", "c", "a");
        //anyMatch表示,判断的条件里,任意一个元素成功,返回true
        boolean b = list.stream().anyMatch(temp -> "a".equals(temp));
        //allMatch表示,判断条件里的元素,所有的都是,返回true
        boolean b1 = list.stream().allMatch(temp -> "a".equals(temp));
        //noneMatch跟allMatch相反,判断条件里的元素,所有的都不是,返回true
        boolean b2 = list.stream().noneMatch(temp -> "a".equals(temp));
        //返回集合的记录数
        long count = list.stream().count();
        long count1 = list.stream().filter(temp -> "a".equals(temp)).count();

        System.out.println(b);
        System.out.println(b1);
        System.out.println(b2);
        System.out.println(count);
        System.out.println(count1);

    }

    private static void testFindFirstAndFindAny(List<Temp> temps) {
        /*findFirst和findAny,通过名字,就可以看到,
        对这个集合的流,做一系列的中间操作后,
        可以调用findFirst,返回集合的第一个对象,
        findAny返回这个集合中,取到的任何一个对象;
         */
        List<String> list = temps.stream().map(Temp::getName).collect(Collectors.toList());
        //未进行中间操作
        Optional<String> first = list.stream().findFirst();
        String s = first.get();
        Optional<String> any = list.stream().findAny();
        String s1 = any.get();

        Optional<String> first1 = list.parallelStream().findFirst();
        String s2 = first1.get();
        String s3 = list.parallelStream().findAny().get();

        System.out.println(s + " ====> " + s2);
        System.out.println(s1 + " =====> " + s3);


        System.out.println("======================================");
        //进行中间操作
        String s4 = list.stream().filter(temp -> !"李四".equals(temp)).findFirst().get();
        String s5 = list.stream().filter(temp -> !"李四".equals(temp)).findAny().get();

        String s6 = list.parallelStream().filter(temp -> !"李四".equals(temp)).findFirst().get();
        String s7 = list.parallelStream().filter(temp -> !"李四".equals(temp)).findAny().get();
        System.out.println(s4 + " -----> " + s6);
        System.out.println(s5 + " -----> " + s7);

    }

    private static void testMinAndMax(List<Temp> temps) {
        List<Double> list = temps.stream().map(Temp::getSalary).collect(Collectors.toList());
        //方式一,Function.identity()
        Optional<Double> min = list.stream().min(Comparator.comparing(Function.identity()));
        Double d = min.get();
        System.out.println("min 方式一 --->" + d);
        //方式二
        Double d2 = list.stream().min((o1, o2) -> o1.compareTo(o2)).get();
        System.out.println("min 方式二 --->" + d2 + "\n");

        Double d3 = list.stream().max(Comparator.comparing(Function.identity())).get();
        System.out.println("max 方式一 --->" + d3);
        Double d4 = list.stream().max((o1, o2) -> o1.compareTo(o2)).get();
        System.out.println("max 方式二 --->" + d4 + "\n");

        System.out.println(String.format("min:%s;max:%s", d, d3));
    }

    private static void testToArray(List<Temp> temps) {
        List<Integer> list = temps.stream().map(temp -> temp.getAge()).collect(Collectors.toList());
        //使用 stream 把集合转换成数组
        //方式一,指明类型
        Integer[] integers = list.stream().toArray(Integer[]::new);
        System.out.print(integers.toString() + " ");
        //方式二
        Integer[] integers1 = list.stream().toArray(temp -> new Integer[list.size()]);
        //方式三,未指明类型
        Object[] objects = list.stream().toArray();
        //使用 list 自带的 toArray 方法进行转换
        Integer[] integers2 = list.toArray(new Integer[list.size()]);
        Object[] objects1 = list.toArray();
    }

    private static void testForEach(List<Temp> temps) {
        List<Integer> list = temps.stream().map(Temp::getAge).collect(Collectors.toList());
        //串行执行
        list.stream().forEach(age -> System.out.print(age + " ") );
        System.out.println();
        list.stream().forEachOrdered(age-> System.out.print(age + " "));
        System.out.println();
        //parallelStream 并行执行,forEach 输出的顺序会乱,forEachOrdered 不会乱
        list.parallelStream().forEach(age-> System.out.print(age + " "));
        System.out.println();
        list.parallelStream().forEachOrdered(age-> System.out.print(age + " "));
    }

    private static void testSpikeAndLimit() {
        //无限流,从 1 开始。
        Stream.iterate(1, x -> ++x).skip(5).limit(10).forEach(temp-> System.out.print(temp + " "));

    }

    private static void testPeek(List<Temp> temps) {
        //方式一
        Stream<Temp> peek = temps.stream().filter(temp ->
            temp.getAge() > 20
        ).peek(temp -> {
            temp.setSalary(temp.getSalary() * 2);
        });
        //方式二
//        Stream<Temp> peek = temps.stream().filter(temp -> {
//            return temp.getAge() > 20;
//        }).peek(temp -> {
//            temp.setSalary(temp.getSalary() * 2);
//        });
        peek.forEach(temp -> System.out.println(temp.getSalary()));

    }

    private static void testDistinact(List<Temp> temps) {
        //去重,排序
        //默认为升序,
            //根据某个字段升序排序, .sorted(Comparator.comparing(Temp::getAge))

        Arrays.asList(1, 4, 1, 2, 3).stream().distinct().sorted().forEach(i -> System.out.print(i));
        System.out.println();
        //设置为降序
        Arrays.asList("1", "4", "1", "2", "3").stream().distinct().sorted(Comparator.reverseOrder()).forEach(str -> System.out.print(str));

        System.out.println();
        //根据某个字段降序排序, .sorted(Comparator.comparing(Temp::getBrithday).reverseOrder())
        List<Temp> collect = temps.stream().sorted(Comparator.comparing(Temp::getBrithday).reversed()).collect(Collectors.toList());
        collect.forEach(temp -> System.out.println(temp.toString()));

    }

    private static void testFlatMap() {
        String[] strings = {"aaa", "bbb", "ccc"};
        String[] strings2 = {"d", "e", "f"};

        Arrays.stream(strings).map(str -> str.split("")).flatMap(Arrays::stream).forEach(str-> System.out.print(str));


    }

    private static void testMap() {
        /*作用:
            可以用来对对象也可以是基本数据类型也可以是引用类型,进行处理后返回
            可以用来对对象中的某个元素进行操作并返回,如只返回该对象中的某个字段
            可以对当前对象进行转换,如把 json 转成对象。
            <R> Stream<R> map(Function<? super T, ? extends R> mapper);
            这个接口,接收一个泛型T,返回泛型R,map函数的定义,返回的流,表示的泛型是R对象,这个表示,调用这个函数后,可以改变返回的类型,
         */
        Stream<Integer> stream = Arrays.stream(new Integer[]{1, 2, 3});
        stream.map(str -> Integer.toString(str)).forEach(i -> {
            System.out.print(i + " ");
        });

        List<Temp> temps = Arrays.asList(new Temp("a", 21, 800), new Temp("b", 25, 1800), new Temp("c", 19, 2000));
        //方式一  .map(当前对象 -> 对当前对象进行操作并返回操作的结果)
        temps.stream().map(temp -> temp.getName()).forEach(name -> System.out.print(name));
        System.out.println();
        //方式二
        temps.stream().map(Temp::getName).forEach(name -> System.out.print(name));
        System.out.println();
        temps.stream().map(temp -> temp.getName().toUpperCase()).collect(Collectors.toList()).forEach(System.out::print);
        System.out.println();
        temps.stream().map(Temp::getName).map(temp -> (temp + "_").toUpperCase()).collect(Collectors.toList()).forEach(System.out::print);
        System.out.println();
        temps.stream().filter(temp -> temp.getAge() > 20).map(temp -> temp.getAge() * 2).collect(Collectors.toList()).forEach(temp-> System.out.print(temp + " "));

    }

    private static void testFilter() {
        //.filter(当前对象 -> )
        Arrays.stream(new String[]{"a","b","c"}).filter(temp -> "c".equals(temp)).forEach(System.out::print);
        System.out.println();
    }


    private static void testCreateStream(){
        System.out.println("执行创建stream 方法=====================");
        String[] aa = {"a", "b", "c"};
        //方式一
        Arrays.stream(aa).forEach(System.out::print);
        System.out.println();
        //方式二
        Stream.of(aa).forEach(System.out::print);
        System.out.println();
        //方式三,最常用的一种方式
        Arrays.asList(aa).stream().forEach(System.out::print);
        System.out.println();
        //方式四
        Stream.iterate(0, x -> x + 1).limit(10).forEach(temp -> System.out.print(temp));
        System.out.println();

    }



}

@Data
class Temp{
    String name;
    int age;
    double salary;
    String brithday;

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

    public Temp(String name, int age, double salary){
        this.name = name;
        this.age = age;
        this.salary = salary;
    }

    public Temp(String name, int age, double salary, String brithday){
        this.name = name;
        this.age = age;
        this.salary = salary;
        this.brithday = brithday;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值