- 作者:老汪软件技巧
- 发表时间:2024-10-10 00:01
- 浏览量:
在开发中stream只是方便操作集合/数组的手段,是一次性的,集合/数组才是开发中的目的!
第一部分 初识Stream流1.1 Stream是什么?有什么作用?结合了什么技术?
· 它是简化集合数组操作的API。并且结合了Lambda表达式。
1.2 Stream流处理数据的步骤是什么?
具体就三大步骤:
详细点说就是,当数据源去调用Stream,就会把数据源的数据扔到一条传送带上去,然后就可以调用传送带上的各种方法比如:过滤、排序、去重、分组等等,最后可以获取处理的结果,遍历统计、收集到一个新集合中返回。
接下来我们就来Stream的初体验:
//认识Stream流,掌握其基本使用,体会他的优势
List list = new ArrayList<>();
list.add("张无忌");
list.add("周芷若");
list.add("赵敏");
list.add("张强");
list.add("张三丰");
//目标:找出姓张的人,名字为三个字,存入到一个新集合中去
//1.先用传统方式:
List newList = new ArrayList<>();
for (String name : list) {
if(name.startsWith("张")&& name.length()==3){
newList.add(name);
}
}
System.out.println(newList);
//2.用Stream流解决
List newList2 = list.stream().filter(s->s.startsWith("张")).filter(s->s.length()==3)
.collect(Collectors.toList());
System.out.println(newList2);
这里的.stream 就会得到一个流,可以理解为一个传送带,并会把这里list集合中的五个数据扔到传送带上,所以此时stream流上已经有集合中的数据了
然后用链式编程接着写.filter是过滤的意思
可以看到过滤里面是需要个匿名对象,可以简化成lambda。
这个s起什么名都可以,它会自动帮你遍历整个流上的所有元素。
后面的.startsWith("张")和.length()==3 是过滤的条件,符合条件的才会留下,最后返回一个新的流,最后.collect收集并toList(),意味着收集到一个List集合中去
第二部分 获取Stream流
· 获取 集合 的Stream流:
分单列集合和双列集合
//获取集合的Stream流
//单列集合,怎么拿Stream流
Collection list = new ArrayList<>();
Stream s2 = list.stream();
//Map集合,怎么拿Stream流
Map m1 = new HashMap<>();
// m1.stream(); 是错的
//可以分开 先拿键流
Stream s1 = m1.keySet().stream();
// 再拿值流
Stream s3 = m1.values().stream();
//获取键值对流
Stream> s4 = m1.entrySet().stream();
· 获取 数组 的Stream流:
.of可以接可变参数,有几个接几个;也可以直接 接数组。
//获取数组的Stream流
String[] names = {"张三丰","张无忌","张翠山","赵敏","周芷若"};
Stream s5 = Arrays.stream(names);
System.out.println(s5.count());
Stream s6 = Stream.of(names);
Stream s7 = Stream.of("张三丰","张无忌","张翠山","赵敏","周芷若"); //可变类型
第三部分 Stream流的中间方法
· 中间方法指的是调用完成后会返回新的Stream流,可以继续使用(支持链式编程)
List list = new ArrayList<>();
list.add("张无忌");
list.add("周芷若");
list.add("赵敏");
list.add("张强");
list.add("张三丰");
//过滤方法:
list.stream().filter(name -> name.startsWith("张")&&name.length()==3)
.forEach(name-> System.out.println(name));
//排序方法:
List list2 = new ArrayList<>();
list2.add(6.66);
list2.add(3.14);
list2.add(9.99);
list2.add(6.66);
list2.add(1.11);
list2.stream().sorted().forEach(price-> System.out.println(price));//默认是升序
System.out.println("-------------------");
list2.stream().sorted((p1,p2)->Double.compare(p2,p1)).forEach(price-> //降序写法
System.out.println(price));
System.out.println("-------------------");
list2.stream().sorted((p1,p2)->Double.compare(p2,p1)).limit(2).forEach(price->
System.out.println(price)); //降序并只取前两个
System.out.println("-------------------");
list2.stream().sorted((p1,p2)->Double.compare(p2,p1)).skip(2).forEach(price->
System.out.println(price)); //降序并跳过前两个
System.out.println("-------------------");
list2.stream().sorted((p1,p2)->Double.compare(p2,p1)).distinct().forEach(price->
System.out.println(price)); //降序并去重
//如果希望自定义对象能够去重,就要重写:equals方法和hashCode方法! distinct里面就有!
System.out.println("-------------------");
//映射/加工方法:把原来的流上的数据变成新数据,又放回流上!
list2.stream().map(s->"加上10后:"+(s+10)).forEach(s-> System.out.println(s));
//合并流:
Stream s1 = Stream.of("张无忌", "赵敏", "周芷若");
Stream s2 = Stream.of(1, 2, 3);
Stream<Object> s3 = Stream.concat(s1, s2);
s3.forEach(s-> System.out.println(s));
每个细节都在注释中!
第四部分 Stream流的终结方法
· 终结方法是指调用完成后不会返回新的Stream,所以没法继续使用流
下面先来了解四个简单的方法:
List teachers = new ArrayList<>();
teachers.add(new Teacher("张三", 23, 5000));
teachers.add(new Teacher("李四", 24, 16000));
teachers.add(new Teacher("王五", 25, 700));
teachers.add(new Teacher("赵六", 26, 3000));
teachers.add(new Teacher("田七", 27, 8000));
teachers.add(new Teacher("田七", 27, 18000));
teachers.stream().filter(t->t.getSalary()>9000).forEach(t-> System.out.println(t));
System.out.println("===========================");
long count = teachers.stream().filter(t -> t.getSalary() > 9000).count();
System.out.println(count);
System.out.println("===========================");
//max和min要给别人一个比较规则(在max括号里)
Optional max = teachers.stream().max((s1, s2) -> Double.compare(s1.getSalary(), s2.getSalary()));
Teacher maxT = max.get();
System.out.println(maxT);
System.out.println("===========================");
Optional min = teachers.stream().min((s1, s2) -> Double.compare(s1.getSalary(), s2.getSalary()));
Teacher minT = min.get();
System.out.println(minT);
· 收集Stream流
List list = new ArrayList<>();
list.add("张无忌");
list.add("周芷若");
list.add("赵敏");
list.add("张强");
list.add("张三丰");
//收集到一个list集合中
List list2 = list.stream().filter(n -> n.startsWith("张")).collect(Collectors.toList());
System.out.println(list2);
//收集到一个Set集合中
Set set3 = list.stream().filter(n -> n.startsWith("张")).collect(Collectors.toSet());
System.out.println(set3);
Object[] array = list.stream().filter(n -> n.startsWith("张")).toArray();
String string = Arrays.toString(array);
System.out.println(string);
//收集到map中 键是老师名 值是薪水
//Map map = teachers.stream().collect(Collectors.toMap(t->t.getName(), t->t.getSalary());
Map map = teachers.stream().collect(Collectors.toMap(Teacher::getName, Teacher::getSalary));
System.out.println(map);
第五部分 方法中的可变参数
● 就是一种特殊形参,定义在方法、构造器的形参列表里,格式是:数据类型...参数名称;
可变参数的特点和好处
● 特点:可以不传数据给它;可以传一个或者同时传多个数据给它;也可以传一个数组给它。
● 好处:常常用来灵活的接收数据。
public class ParamDemo1 {
public static void main(String[] args)
{
//认识可变参数
show();
show(23);
show(13,55,88,46);
}
public static void show(int... nums)
{
int sum = 0;
for (int num : nums) {
sum += num;
}
System.out.println(sum);
System.out.println(Arrays.toString(nums));
System.out.println("==============");
}
}
有个问题在方法中内部怎么拿数据?
其实可变参数对内就是一个数组
比如这样都可以~结果:
注意:可变参数在函数参数中只能有一个!!!且放在最后面
第六部分 Collections工具类
Collections
● 是一个用来操作集合的工具类
Collections提供的常用静态方法 (挺实用De)
因为都是static静态的,所以直接用Collections. 来调用
简单展示一下前两个(比较简单)
关于Stream流就到这里~