一、Stream流的概念
Stream 是Java8中处理集合的关键抽象概念,它可以对集合进行非常复杂的查找、过滤、筛选等操作,在新版的JPA【连接数据库】中,也已经加入了Stream 。
二、为什么要使用Stream流?
每当我们需要对集合中的元素进行操作的时候,总是需要进行循环、循环、再循环。这是理所当然的么?不是。循环 是做事情的方式,而不是目的。每个需求都要循环一次,还要搞一个新集合来装数据,如果希望再次遍历,只能再使 用另一个循环从头开始。Stream能给我们带来更加优雅的写法, Stream API给我们操作集合带来了强大的功用,同时Stream API操作简单,容易上手。 对集合的操作语法简洁:性能比传统快。
三、Stream流的原理
注意:Stream和IO流(InputStream/OutputStream)没有任何关系,请暂时忘记对传统IO流的固有印象!
Stream流式思想类似于工厂车间的“生产流水线”,Stream流不是一种==数据结构==,==不保存数据==,而是对数据进行==加工 处理==。Stream可以看作是流水线上的一个工序。在流水线上,通过多个工序让一个原材料加工成一个商品。
四、获取Stream流对象
public static void main(String[] args) {
//1.通过List集合对象调用stream
List<String> list=new ArrayList<>();
list.add("刘能");
list.add("赵四");
list.add("谢广坤");
Stream<String> stream = list.stream();
//2.通过数组类的stream方法
int[] num ={1,2,3,4,5};
IntStream stream1 = Arrays.stream(num);
//3.通过stream类的of方法
Stream<String> stringStream = Stream.of("张三", "李四", "王五", "赵六");
//4.
//上面都是获取的串行流。还可以获取并行流。如果流中的数据量足够大,并行流可以加快处速度。
Stream<String> stringStream1 = list.parallelStream();
}
五、 Stream流中常见的api
Stream有如下三个操作步骤:
一、创建Stream
从一个数据源,如集合、数组中获取流。
二、中间操作
一个操作的中间链,对数据源的数据进行操作。
中间操作api: 一个操作的中间链,对数据源的数据进行操作。而这种操作的返回类型还是一个Stream对象。
三、终止操作
一个终止操作,执行中间操作链,并产生结果。
终止操作api: 一个终止操作,执行中间操作链,并产生结果,返回类型不在是Stream流对象。
Stream中间操作
1.筛选,filter:接收Lambda,从流中排除某些操作;
//创建流对象
personList.stream()
.filter(iteam->iteam.getAge()>20)//过滤掉年龄小于20岁,中间操作
.forEach(System.out::println);//循环输出,终止操作
2.distinct: 筛选去重,通过流所生成元素的hashCode()和equals()去除重复元素。
//2.交易员都在哪些不同的城市工作过?
transactions.stream().map(iteam->iteam.getTrader().getCity())
.distinct()//去除重复
.forEach(System.out::println);
3. 映射,map:接收Lambda,将元素转换成其他形式或提取信息。接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
//创建流对象
personList.stream().map(iteam->{
Map map=new HashMap();
map.put("name", iteam.getName());
map.put("age", iteam.getAge());
return map;
}).forEach(System.out::println);
4.排序,sorted:
sorted()--自然排序(Comparable)
sorted(Comparator com)--定制排序(Comparator)
personList.stream()
.sorted(((o1, o2) -> o1.getAge()-o2.getAge()))//根据年龄排序
.forEach(System.out::println);
根据字符串首字母排序:
transactions.stream()
.map(iteam->iteam.getTrader().getName())
.sorted((o1, o2) -> o1.substring(0,1).compareTo(o2.substring(0,1)))//截取第一个字符进行比较
.distinct()
.forEach(System.out::println);
Stream终止操作
1.查找与排序:
allMatch--检查是否匹配所有元素
anyMatch--检查是否至少匹配一个元素
noneMatch--检查是否没有匹配所有元素
findFirst--返回第一个元素
findAny--返回当前流中的任意元素
count--返回流中元素的总个数
max--返回流中最大值
min--返回流中最小值
//字符串长度最大的
Optional<Person> max = personList.stream().max(((o1, o2) -> o1.getName().length() - o2.getName().length()));
System.out.println(max);
//第一个出现的
Optional<Person> first = personList.stream()
.filter(iteam -> iteam.getAge() > 20)
.filter(iteam -> iteam.getSex() == 'F')
.findFirst();
System.out.println(first);
match:
//5.有没有交易员是在米兰工作的?
//allmatch:全部元素都与条件都匹配
//anymatch:任意一个元素与条件匹配
//notmatch:没有一个元素与我们的条件匹配
boolean b = transactions.stream()
.anyMatch(iteam -> iteam.getTrader().getCity().equals("Milan"));
System.out.println("有没有交易员在米兰工作:"+b);
2.规约,reduce:Stream API的归约操作可以将流中元素反复结合起来,得到一个值
//求出所有年龄的和
Optional<Integer> reduce = personList.stream()
.map(iteam -> iteam.getAge())
.reduce((a, b) -> a + b);
System.out.println(reduce.get());
3.收集,collect:将流转换为其他形式,接收一个Collector接口实现 ,用于给Stream中汇总的方法
//搜集collect match
//年龄大于20且为F
List<Person> collect = personList.stream()
.filter(iteam -> iteam.getAge() > 20)
.filter(iteam->iteam.getSex()=='F')
.collect(Collectors.toList());
System.out.println(collect);
练习题:
//交易员类
public static class Trader {
private final String name;
private final String city;
public Trader(String name, String city) {
this.name = name;
this.city = city;
}
public String getName() {
return name;
}
public String getCity() {
return city;
}
@Override
public String toString() {
return "Trader{" +
"name='" + name + '\'' +
", city='" + city + '\'' +
'}';
}
}
//交易记录
public static class Transaction {
private final Trader trader;
private final int year;
private final int value;
public Transaction(Trader trader, int year, int value){
this.trader = trader;
this.year = year;
this.value = value;
}
public Trader getTrader(){
return this.trader;
}
public int getYear(){
return this.year;
}
public int getValue(){
return this.value;
}
public String toString(){
return "{" + this.trader + ", " +
"year: "+this.year+", " +
"value:" + this.value +"}";
}
}
Trader raoul = new Trader("Raoul", "Cambridge");
Trader mario = new Trader("Mario", "Milan");
Trader alan = new Trader("Alan", "Cambridge");
Trader brian = new Trader("Brian", "Cambridge");
List<Transaction> transactions = Arrays.asList(
new Transaction(brian, 2011, 300),
new Transaction(raoul, 2012, 1000),
new Transaction(raoul, 2011, 400),
new Transaction(mario, 2012, 710),
new Transaction(mario, 2012, 700),
new Transaction(alan, 2012, 950)
);
(1) 找出2011年发生的所有交易,并按交易额排序(从低到高)。
(2) 交易员都在哪些不同的城市工作过?
(3) 查找所有来自于剑桥的交易员,并按姓名排序。
(4) 返回所有交易员的姓名字符串,按字母顺序排序。
(5) 有没有交易员是在米兰工作的?
(6) 打印生活在剑桥的交易员的所有交易额。
(7) 所有交易中,最高的交易额是多少?
(8) 找到交易额最小的交易。答案:
//1.找出2011发生的所有交易,交易额从低到高排序
transactions.stream()
.filter(iteam->iteam.getYear()==2011)
.sorted((o1, o2) -> o1.getValue()-o2.getValue())
.forEach(System.out::println);
//2.交易员都在哪些不同的城市工作过?
transactions.stream().map(iteam->iteam.getTrader().getCity())
.distinct()//去除重复
.forEach(System.out::println);
//3.查找所有来自于剑桥的交易员,并按姓名排序。
transactions.stream()
.filter(iteam->iteam.getTrader().getCity().equals("Cambridge"))
.sorted((o1, o2) -> o1.getTrader().getName().length()-o2.getTrader().getName().length())
.forEach(System.out::println);
//4.返回所有交易员的姓名字符串,按字母顺序排序 //compareTo
transactions.stream()
.map(iteam->iteam.getTrader().getName())
.sorted((o1, o2) -> o1.substring(0,1).compareTo(o2.substring(0,1)))//截取第一个字符进行比较
.distinct()
.forEach(System.out::println);
//5.有没有交易员是在米兰工作的?
//allmatch:全部元素都与条件都匹配
//anymatch:任意一个元素与条件匹配
//notmatch:没有一个元素与我们的条件匹配
boolean b = transactions.stream()
.anyMatch(iteam -> iteam.getTrader().getCity().equals("Milan"));
System.out.println("有没有交易员在米兰工作:"+b);
//6.打印生活在剑桥的交易员的所有交易额
Optional<Integer> milan = transactions.stream()
.filter(iteam -> iteam.getTrader().getCity().equals("Cambridge"))
.map(iteam -> iteam.getValue())
.reduce((a, c) -> a + c);
System.out.println("生活在剑桥的交易员的所有交易额"+milan.get());
//7.所有交易中,最高的交易额是多少?
Optional<Integer> max = transactions.stream()
.map(iteam->iteam.getValue())
.max((o1, o2) ->o1-o2);
System.out.println("最高的交易额为:"+max.get());
//8.找到交易额最小的交易
Optional<Transaction> min = transactions.stream()
.min((o1, o2) -> o1.getValue() - o2.getValue());
System.out.println("交易额最小的交易为:"+min.get());
————————————————
版权声明:本文为CSDN博主「Have_MonkeyG」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Have_MonkeyG/article/details/125906861