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;
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。