Java 8 新特性 Stream
Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。
Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。
Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。
这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。
元素流在管道中经过中间操作(intermediate operation)的处理,
最后由最终操作(terminal operation)得到前面处理的结果。
+--------------------+ +------+ +------+ +---+ +-------+
| stream of elements +-----> |filter+-> |sorted+-> |map+-> |collect|
+--------------------+ +------+ +------+ +---+ +-------+
以上的流程转换为 Java 代码为:
List<Integer> transactionsIds =
widgets.stream()
.filter(b -> b.getColor() == RED)
.sorted((x,y) -> x.getWeight() - y.getWeight())
.mapToInt(Widget::getWeight)
.sum();
应用场景
mans 类有很多卡类,先初始化一些数据。
List<Man> mans = new ArrayList<>();
mans.add(new Man("001","张三",Arrays.asList(new Card("工商银行","9558800001"),new Card("工商银行","9558800002"),new Card("建设银行","6227001234"))));
mans.add(new Man("002","李四",Arrays.asList(new Card("招商银行","6225800002"),new Card("建设银行","6227035248"))));
mans.add(new Man("003","王五",Arrays.asList(new Card("建设银行","6227056547"),new Card("中国银行","6013832547"),new Card("民生银行","4074058542"))));
mans.add(new Man("004","赵六",Arrays.asList(new Card("工商银行","9558832458"),new Card("工商银行","9558832547"),new Card("建设银行","6227032578"))));
mans.add(new Man("005","孙七",Arrays.asList(new Card("中国银行","6013825847"),new Card("农业银行","6228836547"),new Card("招商银行","6225014582"))));
mans.add(new Man("006","张三",Arrays.asList(new Card("工商银行","9558832587"),new Card("交通银行","6222814578"),new Card("工商银行","9558865427"))));
1,查找张三的男人,for是这样的,
public List<Man> getByName(List<Man> mans){
List<Man> temp = new ArrayList<>();
for(Man man : mans){
if("张三".equals(man.getName())){
temp.add(man);
}
}
return temp;
}
改进后:
public List<Man> getByName8(List<Man> mans) {
return mans.stream().filter(m -> "张三".equals(m.getName())).collect(Collectors.toList());
}
这里的集合相当与数据库的表,而filter相当于数据库的where。
filter 方法 : 用于通过设置的条件过滤出元素。
2,继续,查找id为007的男人,id唯一,for是这样的
public Man getById(List<Man> mans) {
for (Man man : mans) {
if ("007".equals(man.getId())) {
return man;
}
}
return null;
}
改进后:
public Man getById8(List<Man> mans) {
return mans.stream().filter(m -> "oo7".equals(m.getId())).findFirst().orElse(null);
}
3,继续,获取名字叫张三(因有同名)的所有银行卡,这里不讨论实际业务意义,只讲技术,哈哈,用for是这样的。
public List<Card> getAllCardByName(List<Man> mans) {
List<Card> cards = new ArrayList<>();
for (Man man : mans) {
if ("张三".equals(man.getName())) {
cards.addAll(man.getCards());
}
}
return cards;
}
改进后:
public List<Card> getAllCardByName8(List<Man> mans) {
return mans.stream().filter(m -> "张三".equals(m.getName())).flatMap(m -> m.getCards().stream())
.collect(Collectors.toList());
}
https://blog.csdn.net/weixin_41888813/article/details/82908534 Java8Stream map和flatmap的区别
Collectors 类实现了很多归约操作,例如将流转换成集合和聚合元素。Collectors 可用于返回列表或字符串:
List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
System.out.println("筛选列表: " + filtered);
String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(", "));
System.out.println("合并字符串: " + mergedString);
4,继续,在3的条件上加个工商银行条件,for
public List<Card> getSomeCardByName(List<Man> mans) {
List<Card> cards = new ArrayList<>();
for (Man man : mans) {
if ("张三".equals(man.getName())) {
for (Card card : man.getCards()) {
if ("工商银行".equals(card.getName())) {
cards.add(card);
}
}
}
}
return cards;
}
改进后:
public List<Card> getSomeCardByName8(List<Man> mans) {
return mans.stream().filter(m -> "张三".equals(m.getName())).flatMap(m -> m.getCards().stream())
.filter(c -> "工商银行".equals(c.getName())).collect(Collectors.toList());
}
5,把张三的名字修改为新张三,for,注意会改变源数据
public List<Man> changeName(List<Man> mans) {
for (Man man : mans) {
if ("张三".equals(man.getName())) {
man.setName("新张三");
}
}
return mans;
}
改进:
public List<Man> changeName8(List<Man> mans) {
return mans.stream().peek(m -> {
if ("张三".equals(m.getName()))
m.setName("新张三");
}).collect(Collectors.toList());
}
实测使用peek好像会有些问题,还是直接使用forEach更加方便。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38CXlZHbvN3cpR2Lc1TPB10QGtWUCpEMJ9CXsxWam9CXwADNvwVZ6l2c052bm9CXUJDT1wkNhVzLcRnbvZ2Lc1TP31EenR0T0cGVNBDOsJGcohVYsR2MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2LcRHelR3LcJzLctmch1mclRXY39DNxMTNwYjM4ETOwATM4EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
orElseThrow()
如果有值则将其返回,否则抛出supplier接口创建的异常。
try {
empty.orElseThrow(()->new RuntimeException());
} catch (Throwable ex) {
//输出: No value present in the Optional instance
System.out.println(ex.getMessage());
}
案例1 :根据Age 分组,并且拆分成两个group
12 public class GroupByDemo {
13 public static void main(String[] args) {
14 Student student1 = new Student(200, "yangtao", "1");
15 Student student2 = new Student(220, "yangtao", "1");
16 Student student3 = new Student(500, "yangtao", "2");
17 Student student4 = new Student(504, "yangtao", "2");
18 List<Student> studentList =new ArrayList<>();
19 studentList.add(student1);
20 studentList.add(student2);
21 studentList.add(student3);
22 studentList.add(student4);
23
24 //单一分组条件,根据code
25 Map<String, List<Student>> singleMap = studentList.stream().collect(Collectors.groupingBy(Student::getCode));
26 //{1=[Student{age=200, username='yangtao', code='1'}, Student{age=220, username='yangtao', code='1'}],
27 // 2=[Student{age=500, username='yangtao', code='2'}, Student{age=504, username='yangtao', code='2'}]}
28
29 //组合分组条件
30
31 Map<String, List<Student>> complexMap = studentList.stream().collect(Collectors.groupingBy(e -> fetchGroupKey(e)));
32 List<Student> studentList1 = complexMap.get("yangtao+1");
33 List<Student> studentList2 = complexMap.get("yangtao+2");
34 System.out.println(complexMap);
35 // {yangtao+2=[Student{age=500, username='yangtao', code='2'}, Student{age=504, username='yangtao', code='2'}], yangtao+1=[Student{age=200, username='yangtao', code='1'}, Student{age=220, username='yangtao', code='1'}]}
36
37 System.out.println(studentList1);
38 System.out.println(studentList2);
39 //[Student{age=200, username='yangtao', code='1'}, Student{age=220, username='yangtao', code='1'}]
40 //[Student{age=500, username='yangtao', code='2'}, Student{age=504, username='yangtao', code='2'}]
41
42 }
43 private static String fetchGroupKey(Student student){
44 return student.getUsername() +"+"+ student.getCode();
45 }
46
47 }
参考来源于:
https://blog.csdn.net/williamtsang/article/details/52634970