什么是 Stream

Stream 中文称为 “”,通过将集合转换为这么一种叫做 “流” 的元素序列,通过声明性方式,能够对集合中的每个元素进行一系列并行或串行的流水线操作

什么是流操作

整个流操作就是一条流水线,将元素放在流水线上一个个地进行处理。

其中数据源便是原始集合,然后将如 List<T> 的集合转换为 Stream<T> 类型的流,并对流进行一系列的中间操作,比如过滤保留部分元素、对元素进行排序、类型转换等;最后再进行一个终端操作,可以把 Stream 转换回集合类型,也可以直接对其中的各个元素进行处理,比如打印、比如计算总数、计算最大值等等。

数据准备

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

/**
 * 测试用
 */

// 自动生成get和set方法
@Data
// 全参构造
@AllArgsConstructor
// 无参构造
@NoArgsConstructor
// 自动toString
@ToString
public class UserTest {
    /** id */
    private Integer id;
    /** 名称 */
    private String name;
    /** 年龄 */
    private Integer age;
}
/**
 * Stream流常用操作
 *
 * @author xiaofei
 */
public class StreamDemo {
    UserTest u1 = new UserTest(1, "a", 58);
    UserTest u2 = new UserTest(2, "b", 14);
    UserTest u3 = new UserTest(3, "c", 95);
    UserTest u4 = new UserTest(4, "b", 25);
    List<UserTest> list = Arrays.asList(u1, u2, u3, u4, u5, u6);

}

常用方法

1、filter(T -> boolean)

filter中返回true代表当前元素会被保留下来

    list.stream()
            // 查询id大于2的
           .filter(u -> u.getId() > 2)
            // 把流转换为list
           .collect(Collectors.toList())
           // 迭代流中的每个数据
           .forEach(System.out::println);

   控制台输出:    {
                       UserTest(id=3, name=c, age=95)
                       UserTest(id=4, name=b, age=25)
                   }

2、distinct()

去除重复元素

    /**
     * 根据某个实体属性去重
     */
    public static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
        Map<Object, Boolean> seen = new ConcurrentHashMap<>();
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }

    list.stream()
        // 根据名称去重
       .filter(distinctByKey(p -> p.getName()))
        // 把流转换为list
       .collect(Collectors.toList())
       // 迭代流中的每个数据
       .forEach(System.out::println);

   控制台输出:{    
                   UserTest(id=1, name=a, age=58)
                UserTest(id=2, name=b, age=14)
                UserTest(id=3, name=c, age=95)
              }

3、sorted()

按年龄排序—>正序

    list.stream()
           .forted(Comparator.comparing(UserTest::getAge))
            // 把流转换为list
           .collect(Collectors.toList())
           // 迭代流中的每个数据
           .forEach(System.out::println);

   控制台输出:    {
                       UserTest(id=2, name=b, age=14)
                    UserTest(id=4, name=b, age=25)
                    UserTest(id=1, name=a, age=58)
                    UserTest(id=3, name=c, age=95)
                   }

按年龄排序—>倒序

    list.stream()
           .forted(Comparator.comparing(UserTest::getAge).reversed())
            // 把流转换为list
           .collect(Collectors.toList())
           // 迭代流中的每个数据
           .forEach(System.out::println);

   控制台输出:    {
                    UserTest(id=3, name=c, age=95)
                    UserTest(id=1, name=a, age=58)
                    UserTest(id=4, name=b, age=25)
                    UserTest(id=2, name=b, age=14)
                   }

4、limit(long n)

返回前2个元素

    list.stream()
           .limit(2)
            // 把流转换为list
           .collect(Collectors.toList())
           // 迭代流中的每个数据
           .forEach(System.out::println);

   控制台输出:    {
                    UserTest(id=1, name=a, age=58)
                    UserTest(id=2, name=b, age=14)
                   }

5、skip(long n)

去除前3个元素

    list.stream()
           .limit(3)
            // 把流转换为list
           .collect(Collectors.toList())
           // 迭代流中的每个数据
           .forEach(System.out::println);

   控制台输出:    {
                    UserTest(id=4, name=b, age=25)
                   }

6、map(T -> R)

获取所有名字并转换为大写

    list.stream()
           .map(u -> u.getName().toUpperCase())
            // 把流转换为list
           .collect(Collectors.toList())
           // 迭代流中的每个数据
           .forEach(System.out::println);

   控制台输出:    {
                    A
                    B
                    C
                    B
                   }

7、map(T -> R)

算所有人年龄总和

    list.stream()
           .map(UserTest::getAge)
           .reduce(0, Integer::sum)
            // 把流转换为list
           .collect(Collectors.toList())
           // 迭代流中的每个数据
           .forEach(System.out::println);

   控制台输出:    {
                    192
                   }