public class UserPo {
    private String name;
    private Double score;
    
    // 省略构造函数及getter、setter
}

filter

filter:过滤,就是过滤器,符合条件的通过,不符合条件的过滤掉

// 筛选出成绩不为空的学生人数
count = list.stream().filter(p -> null != p.getScore()).count();
map

map:

映射,他将原集合映射成为新的集合,在VO、PO处理的过程中较常见。在本例子中,原集合就是PO集合,新集合可以自定义映射为成绩集合,同时也可以对新集合进行相关操作


// 取出所有学生的成绩
List<Double> scoreList = list.stream().map(p -> p.getScore()).collect(Collectors.toList());

// 将学生姓名集合串成字符串,用逗号分隔
String nameString = list.stream().map(p -> p.getName()).collect(Collectors.joining(","));

sorted

sorted:排序,可以根据指定的字段进行排序


// 按学生成绩逆序排序 正序则不需要加.reversed()
filterList = list.stream().filter(p -> null != p.getScore()).sorted(Comparator.comparing(UserPo::getScore).reversed()).collect(Collectors.toList());

forEach

forEach:这个应该是最常用的,也就是为每一个元素进行自定义操作

除了forEach操作会改变原集合的数据,其他的操作均不会改变原集合,这点务必引起注意

// 学生成绩太差了,及格率太低,给每个学生加10分,放个水
// forEach
filterList.stream().forEach(p -> p.setScore(p.getScore() + 10));

collect

collect:聚合,可以用于GroudBy按指定字段分类,也可以用于返回列表或者拼凑字符串

// 按成绩进行归集
Map<Double, List<UserPo>> groupByScoreMap = list.stream().filter(p -> null != p.getScore()).collect(Collectors.groupingBy(UserPo::getScore));
for (Map.Entry<Double, List<UserPo>> entry : groupByScoreMap.entrySet()) {
    System.out.println("成绩:" + entry.getKey() + " 人数:" + entry.getValue().size());
}

// 返回list
List<Double> scoreList = list.stream().map(p -> p.getScore()).collect(Collectors.toList());
// 返回string用逗号分隔
String nameString = list.stream().map(p -> p.getName()).collect(Collectors.joining(","));

statistics

statistics:统计,可以统计中位数,平均值,最大最小值

DoubleSummaryStatistics statistics = filterList.stream().mapToDouble(p -> p.getScore()).summaryStatistics();
System.out.println("列表中最大的数 : " + statistics.getMax());
System.out.println("列表中最小的数 : " + statistics.getMin());
System.out.println("所有数之和 : " + statistics.getSum());
System.out.println("平均数 : " + statistics.getAverage());

parallelStream

parallelStream:并行流,可以利用多线程进行流的操作,提升效率。但是其不具备线程传播性,因此使用时需要充分评估是否需要用并行流操作


// 并行流
count = list.parallelStream().filter(p -> null != p.getScore()).count();

练习

    Student stuA = new Student(1, "A", "M", 184);
    Student stuB = new Student(2, "B", "G", 163);
    Student stuC = new Student(3, "C", "M", 175);
    Student stuD = new Student(4, "D", "G", 158);
    Student stuE = new Student(5, "A", "M", 158);

// stream-forEach循环

    list.stream().forEach(stu -> System.out.println("stream-forEach: " + stu.getName()));

// stream-filter过滤即执行逻辑

    long count = list.stream().filter(stu -> stu.height > 180).count();
    list.stream().filter(stu -> stu.height > 180)
                 .forEach(stu -> System.out.println("stream-filter: " + stu));
    

// Stream-toMap 为了避免key冲突情况,(key1, key2) -> key1 表示冲突时取前者

    Map<String, Student> maps = list.stream()
            .collect(Collectors.toMap(Student::getName, Function.identity(), (key1, key2) -> key1));
    System.out.println("key-对象" + maps);
    Map<String, Object> newMaps = list.stream()
            .collect(Collectors.toMap(Student::getName, Student::getHeight, (key1, key2) -> key1));

// Stream-distinct 去重 + 指定字段去重


public class StreamUtil {
/**
 * 指定字段去重
 * @param keyExtractor
 * @return
 */
static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Map<Object,Boolean> seen = new ConcurrentHashMap<>();
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
} 
}

    System.out.println("***********Stream-distinct去重  必须重写equals和hashcode方法***********");
    list.stream()
        .distinct()
        .forEach(b -> System.out.println("Stream-distinct去重  " + b.getName()+ "," + b.getHeight()));

    list.stream()
        .filter(StreamUtil.distinctByKey(b -> b.getSex()))
        .forEach(b -> System.out.println("Stream-distinct指定字段去重  " + b.getName()+ "," + b.getSex())); 


    

// 过滤后得到新集合

    List<Student> newList = list.stream().filter(stu -> stu.height > 165)
                                         .collect(Collectors.toList());
    System.out.println("新集合: " + newList);
    

// stream-聚合操作 最大值,最小值

    System.out.println("**************stream-聚合操作  最大值,最小值************");
    System.out.println("sum: " + list.stream().mapToDouble(Student::getHeight).sum());
    System.out.println("max: " + list.stream().mapToDouble(Student::getHeight).max().getAsDouble());
    System.out.println("min: " + list.stream().mapToDouble(Student::getHeight).min().getAsDouble());
    System.out.println("avg: " + list.stream().mapToDouble(Student::getHeight).average().getAsDouble());
    

// Stream排序

    System.out.println("**************stream-聚合操作  排序************");
    List<Student> collect = list.stream().filter(stu -> stu.getHeight() > 165)
                 .sorted((e1,e2) -> Float.compare(e1.getHeight(), e2.getHeight()))
                 .collect(Collectors.toList());
    System.out.println("stream 排序" + collect);
}

练习2

public static void main(String[] args) {
    List<Transaction> transactions = null;
    Trader raoul = new Trader("Raoul", "Cambridge");
    Trader mario = new Trader("Mario", "Milan");
    Trader alan = new Trader("Alan", "Cambridge");
    Trader brian = new Trader("Brian", "Cambridge");
    transactions = Arrays.asList(
            new Transaction(brian, 2011, 300),
            new Transaction(raoul, 2012, 1000),
            new Transaction(raoul, 2011, 400),
            new Transaction(mario, 2012, 400),
            new Transaction(mario, 2012, 710),
            new Transaction(alan , 2012, 950));
    // ①找出2011年发生的所有交易, 并按交易额排序(从低到高)
    // 方式一:
    Long begin = System.currentTimeMillis();
    List<Transaction> newTr = transactions.stream().filter(tran -> tran.getYear() == 2011)
                                          .collect(Collectors.toList());
    newTr.sort(Comparator.comparing(t -> t.getValue()));
    Long end = System.currentTimeMillis();
    System.out.println("耗时: " + (end - begin) + " " + newTr);
    // 方式二: 差距是35倍左右!
    Long begin2 = System.currentTimeMillis();
    List<Transaction> collect = transactions.stream().filter(tran -> tran.getYear() == 2011)
                                             .sorted((e1,e2) -> Integer.compare(e1.getValue(), e2.getValue()))
                                             .collect(Collectors.toList());
    Long end2 = System.currentTimeMillis();
    System.out.println("耗时: " + (end2 - begin2) + " " + collect);
    // ②交易员都在哪些不同的城市工作过?
    // 方式一:
    transactions.stream()
                .filter(StreamUtil.distinctByKey(tran -> tran.getTrader().getCity()))
                .collect(Collectors.toList())
                .forEach(t -> System.out.println(t.getTrader().getCity()));
    // 方式二:
    List<String> collCityTwo = transactions.stream()
                                        .map(e -> e.getTrader().getCity())
                                        .distinct()
                                        .collect(Collectors.toList());
    System.out.println("城市为: " + collCityTwo);
    //③查找所有来自剑桥的交易员,并按姓名排序
    List<Trader> collPerson = transactions.stream().filter(tran -> tran.getTrader().getCity().equals("Cambridge"))
                                          .map(Transaction::getTrader)
                                          .sorted((e1,e2) -> e1.getName().compareTo(e2.getName()))
                                          .collect(Collectors.toList());
    System.out.println(collPerson);
    // ⑤有没有交易员是在米兰工作的?
    long count = transactions.stream().filter(tran -> tran.getTrader().getCity().equals("Milan")).count();
    System.out.println("是否有人在米兰工作: " + (count > 0));
    // ⑥打印生活在剑桥的交易员的所有交易额总和
    int sum = transactions.stream()
                          .filter(e -> e.getTrader().getCity().equals("Cambridge"))
                          .mapToInt(Transaction::getValue)
                          .sum();
    System.out.println("总额为: " + sum);
    // ⑦所有交易中,最高的交易额是多少
    int max = transactions.stream()
              .mapToInt(Transaction::getValue)
              .max()
              .getAsInt();
    System.out.println("最大值是: " + max);
    // ⑧找到交易额最小的交易
    Transaction transaction = transactions.stream()
                                          .min((e1,e2) -> Integer.compare(e1.getValue(), e2.getValue()))
                                          .get();
    System.out.println("最小值交易是: " + transaction);
}
}
class Trader {
private String name;
private String city;
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public String getCity() {
    return city;
}
public void setCity(String city) {
    this.city = city;
}
@Override
public String toString() {
    return "Trader [name=" + name + ", city=" + city + "]";
}
public Trader(String name, String city) {
    super();
    this.name = name;
    this.city = city;
}
}
class Transaction {
private Trader trader;
private int year;
private int value;
public Trader getTrader() {
    return trader;
}
public void setTrader(Trader trader) {
    this.trader = trader;
}
public int getYear() {
    return year;
}
public void setYear(int year) {
    this.year = year;
}
public int getValue() {
    return value;
}
public void setValue(int value) {
    this.value = value;
}
@Override
public String toString() {
    return "Transaction [trader=" + trader + ", year=" + year + ", value=" + value + "]";
}
public Transaction(Trader trader, int year, int value) {
    super();
    this.trader = trader;
    this.year = year;
    this.value = value;
}
}

泽诺熙
25 声望2 粉丝