前言
没使用stream流操作的时候,操作list集合是不是都用fori循环呢,写法不美观,写法比较麻烦,主要是懒。
用了stream之后,开发效率大大提升了,相见恨晚!!!
一、stream是什么?
Stream是Java 8中引入的一个新特性,用于处理集合对象,允许以声明式方式对集合进行各种操作。
Stream主要关注对集合对象进行各种便利、高效的聚合操作或大批量数据操作。使用Stream可以轻松地执行复杂的查找、过滤、筛选等操作,并且可以链式地组合多个操作,形成一个操作管道。
二、使用步骤
1.创建Stream
定义list(示例):
List<User> userList = new ArrayList<>();
User user1 = new User();
User user2 = new User();
User user3 = new User();
user1.setName("小米");
user1.setAge(12);
user2.setName("华为");
user2.setAge(13);
user3.setName("苹果");
user3.setAge(15);
userList.add(user1);
userList.add(user2);
userList.add(user3);
user对象
package test;
import lombok.Data;
/**
* @program: ruoyi
* @description:
* @author: yangyang
* @create: 2023-08-22 14:00
**/
@Data
public class User {
private Integer age;
private String name;
private Integer sex;
}
创建流:
Stream stream = userList.stream();
2.常用的操作
(1)filter:过滤
List<User> newUserList = userList.stream()
.filter(item -> StringUtils.equals("小米",item.getName()))
.collect(Collectors.toList());
打印: [User(age=12, name=小米, sex=null)]
(2)peek:将userList所有元素的age属性设置15
userList.stream()
.peek(item -> {
item.setAge(15);
})
.collect(Collectors.toList());
打印: [User(age=15, name=小米, sex=null), User(age=15, name=华为, sex=null), User(age=15, name=苹果, sex=null)]
(3)map:取出元素list
List<String> nameList = userList.stream()
.map(item -> item.getName())
.collect(Collectors.toList());
nameList.forEach(System.out::println);
打印: 小米华为苹果
(4)sorted:排序
List<User> newUserList = userList.stream()
.sorted(Comparator.comparing(User::getAge).reversed())
.collect(Collectors.toList());
打印: [User(age=15, name=苹果, sex=null), User(age=13, name=华为, sex=null), User(age=12, name=小米, sex=null)]
(5)findAny和findFirst对比
通常与filter过滤连用,条件成立
findFirst返回第一条,findAny返回任意一条(list数量少通常返回第一条)
User userAny = userList
.stream()
.filter(item ->
item.getAge() >= 12 && item.getAge() <= 20
)
.findAny()
.orElse(null);
User userFirst = userList
.stream()
.filter(item ->
item.getAge() >= 12 && item.getAge() <= 20
)
.findFirst()
.orElse(null);
打印: 两次都为User(age=12, name=小米, sex=null)
(6)其余的方法
①distinct
注意new的对象即便属性相同,内存地址不同不能这么用 因为distinct函数是比较的内存地址
list对象去重参考:
https://blog.youkuaiyun.com/qq_40794453/article/details/135380118?spm=1001.2014.3001.5501
//list中相同元素的内存地址是一样的
@Test
public void filter() {
//list中相同元素的内存地址是一样的
List<String> distinctList = Arrays.asList("abc", "bca", "ddf", "pij", "pij");
Collection<String> distinct = distinctList.stream().distinct().collect(Collectors.toList());
//distinct用来去掉重复的数据
System.out.println(distinct);
}
②limit
@Test
public void limit() {
//list中相同元素的内存地址是一样的
List<String> limitList = Arrays.asList("abc", "bca", "ddf", "pij", "pij");
Collection<String> limit = limitList.stream().limit(2).collect(Collectors.toList());
//limit返回一个给定长度的流,像上面给的参数是2就返回流中前面两个数据
System.out.println(limit);
}
③skip
@Test
public void skip() {
List<String> skipList = Arrays.asList("sex", "hhhhh", "ppt", "idea");
Collection<String> collect = skipList.stream().skip(3).collect(Collectors.toList());
//跳过skip参数中的前N个数据,返回后面的数据
System.out.println(collect);
}
④anyMatch 集合中是否有一个元素满足条件
@Test
public void anyMatch() {
List<String> anymatchList = Arrays.asList("sex", "hhhhh", "ppt", "idea");
boolean any1 = anymatchList.stream().anyMatch(str -> str.contains("g"));
//集合中是否有一个元素满足条件
System.out.println(any1);
}
noneMatch 集合中所有元素都不满足条件
@Test
public void noneMatch() {
//集合中所有元素都不满足条件
List<String> noneMatchList = Arrays.asList("sex", "hhhhh", "ppt", "idea");
//没有长度大于6的元素,属于所有的元素都不满足条件,即返回true
boolean none1 = noneMatchList.stream().noneMatch(str -> str.length() > 6);
System.out.println(none1);
}
allMatch 集合中是否所有的元素都满足条件
@Test
public void allMatch() {
List<String> anymatchList = Arrays.asList("sex", "hhhhh", "ppt", "idea");
boolean all1 = anymatchList.stream().allMatch(str -> str.length() > 3);
//集合中是否所有的元素都满足条件
System.out.println(all1);
}
3.终止操作
(1)count 数量
@Test
public void count() {
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张三-15", "李四-16", "王五-17", "赵六-18");
long count = list.stream().count();
System.out.println(count);
}
(2)toArray () 方法
@Test
public void count() {
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张三-15", "李四-16", "王五-17", "赵六-18");
long count = list.stream().count();
System.out.println(count);
}
(3)collect(Collector collector) 方法:收集流中的数据,放到集合中(List Set Map)
@Test
public void collect() {
// 1. 收集到 List 集合当中:
ArrayList<String> listL = new ArrayList<>();
Collections.addAll(listL, "张三-男-15", "李四-女-16", "王五-女-17", "赵六-男-18");
List<String> newListL = listL.stream().collect(Collectors.toList());
System.out.println(newListL);
// 2. 收集到 Set 集合当中:
ArrayList<String> listS = new ArrayList<>();
Collections.addAll(listS, "张三-男-15", "李四-女-16", "王五-女-17", "赵六-男-18");
java.util.Set<String> newListS = listS.stream().collect(Collectors.toSet());
System.out.println(newListS);
// 3. 收集到 Map 集合当中:
ArrayList<String> listM = new ArrayList<>();
Collections.addAll(listM, "张三-15", "李四-16", "王五-17", "赵六-18");
Map<String, Integer> map = listM.stream()
.collect(Collectors.toMap(s -> s.split("-")[0], s -> Integer.parseInt(s.split("-")[1])));
System.out.println(map);
}
[张三-男-15, 李四-女-16, 王五-女-17, 赵六-男-18]
[李四-女-16, 王五-女-17, 赵六-男-18, 张三-男-15]
{李四=16, 张三=15, 王五=17, 赵六=18}
总结
使用Stream的好处包括减少冗余代码、提高代码可读性和可维护性,以及更好地利用多核处理器进行并行处理。
需要注意的是,虽然Java 8引入了Stream,但并不是所有集合类都支持Stream操作。一些旧版本的Java集合类可能需要使用传统的for循环或其他方法来处理数据。