Stream流学习_常用操作api
Stream流学习
初识Stream
背景要求
-
传统代码实现
public class Stream01 { @Test public void test04() { /** * ArrayList<String> list = new ArrayList<>(); * 把所有的张姓 存储到新集合中 * 并且要求名字长度为3 * 打印遍历 */ List<String> strings = Arrays.asList("张三芳", "张无忌", "周芷若", "赵敏"); ArrayList<String> list1 = new ArrayList<>(); // 首先取出来 名字姓为张的 for (String name : strings) { if (name.startsWith("张")){ list1.add(name); } } // 再取出来长度为3的 ArrayList<String> list2 = new ArrayList<>(); for (String s : list1) { if (s.length()==3) { list2.add(s); } } System.out.println("list2 = " + list2); }
这样太繁琐了,也是很啰嗦 接下来看一下stream .
-
stream流实现
/** * @author ShaoCong Lu * @date 2023/6/12 19:46 */ public class Stream01 { @Test public void test04() { /** * ArrayList<String> list = new ArrayList<>(); * 把所有的张姓 存储到新集合中 * 并且要求名字长度为3 * 打印遍历 */ List<String> strings = Arrays.asList("张三芳", "张无忌", "周芷若", "赵敏"); List<String> list = strings.stream().filter(new Predicate<String>() { @Override public boolean test(String s) { return s.startsWith("张"); } }).filter(new Predicate<String>() { @Override public boolean test(String s) { return s.length() == 3; } }).collect(Collectors.toList()); for (String s : list) { System.out.println("s = " + s); } // 或者 这样一行 System.out.println("======================"); strings.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3).forEach(System.out::println); } }
四种获取stream流
- 双列集合首先获取keySet 或者entrySet
- 数组使用Arrays工具类中的方法
- 零散数据 必须是同种类型的数据
使用以上四种方式创建一个stream流
-
单列集合
@Test public void test02() { // 使用第一种方法 单列集合 ArrayList<String> strings = new ArrayList<>(); Collections.addAll(strings,"路","哈","流","是"); Stream<String> stream = strings.stream(); // 获取stream stream.forEach(s -> System.out.println(s)); // s 代表这条流水线的每一个元素 打印完事 , forEach是终结方法 }
-
双列集合 比如map
@Test public void test03() { // 双列集合 HashMap<String, Integer> map = new HashMap<>(); map.put("001",1); map.put("002",2); map.put("003",3); // 获取Set集合 map.keySet().stream().forEach(s -> System.out.println(s)); // 获取所有的key 并且全部打印出来 map.values().stream().forEach(System.out::println); // 获取所有的values 并且打印出来 map.entrySet().stream().forEach(System.out::println); // 获取到所有的entry 键值对 并且都打印出来 }
-
组数
@Test public void test05() { // 数组 int arr[] = {1,2,3,4}; Arrays.stream(arr).forEach(System.out::println); }
-
零散数据
@Test public void test06() { // 零散数据 必须是同种类型的数据 Stream<String> stream = Stream.of("a", "k", "p"); stream.forEach(s -> System.out.println(s)); }
Stream中间方法
filter过滤方法
@Test
public void test07() {
// filter 方法 过滤 1
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"张无忌-15","周芷若-14","赵敏-13","张强-20","张三丰-100","张深山-40","张良-35","王二麻子-37");
// 1. 要求 需要 张
List<String> list1 = list.stream().filter(s -> s.startsWith("张")).collect(Collectors.toList());
//2. 要求 需要 张并且名字为三位数
List<String> list2 = list.stream().filter(s -> s.split("-")[0].length() == 3).collect(Collectors.toList());
System.out.println("list1 = " + list1);
System.out.println("list2 = " + list2);
/**
* list1 = [张无忌-15, 张强-20, 张三丰-100, 张深山-40, 张良-35]
* list2 = [张无忌-15, 周芷若-14, 张三丰-100, 张深山-40]
*/
}
@Test
public void testMap02() {
HashMap<Integer, Emp> empHashMap = new HashMap<>();
empHashMap.put(1,new Emp("路",1,30000.0));
empHashMap.put(2,new Emp("刘",5,8000.0));
empHashMap.put(3,new Emp("郑",3,10000.0));
empHashMap.put(4,new Emp("王",4,18520.0));
// 要求 输出大于一万八的
Set<Integer> keySet = empHashMap.keySet();
for (Integer integer : keySet) {
if (getEmp(empHashMap, integer).getMoy()>18000) {
System.out.println("empHashMap = " + getEmp(empHashMap, integer));
}
}
// stream流
List<Map.Entry<Integer, Emp>> entryList = empHashMap
.entrySet().stream().filter(entry -> entry.getValue().getMoy() > 18000).collect(Collectors.toList());
for (Map.Entry<Integer, Emp> entry : entryList) {
System.out.println("entry = " + entry);
}
}
private Emp getEmp(HashMap<Integer, Emp> empHashMap, Integer integer) {
return empHashMap.get(integer);
}
@Data@AllArgsConstructor@NoArgsConstructor
class Emp{
private String name;
private int empId;
private Double moy;
}
limit 获取前几个元素
@Test
public void test08() {
// limit 获取前几个元素
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"张无忌-15","周芷若-14","赵敏-13","张强-20","张三丰-100","张深山-40","张良-35","王二麻子-37");
// 获取前三个元素
List<String> collect = list.stream().limit(3).collect(Collectors.toList());
for (String s : collect) {
System.out.println("s = " + s);
}
}
skip方法 ,跳过前几个元素
@Test
public void test09() {
// skit 跳过前几个元素
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"张无忌-15","周芷若-14","赵敏-13","张强-20","张三丰-100","张深山-40","张良-35","王二麻子-37");
for (String s : list.stream().skip(5).collect(Collectors.toList())) {
System.out.println("s = " + s);
}
}
distinct 去重
@Test
public void test10() {
// distinct 去重
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"张无忌-15","周芷若-14","赵敏-13","张强-20","张三丰-100","张深山-40","张良-35","王二麻子-37");
List<String> collect = list.stream().distinct().collect(Collectors.toList());
}
concat 合并流
@Test
public void test11() {
// concat 合并流
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"张无忌-15","周芷若-14","赵敏-13","张强-20","张三丰-100","张深山-40","张良-35","王二麻子-37");
ArrayList<String> list2 = new ArrayList<>();
Collections.addAll(list2,"张良-35555","王二麻子-375555");
Stream.concat(list.stream(),list2.stream()).forEach(System.out::println);
}
map 比较难得一个 转换
@Test
public void test12() {
// map 转换
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"张无忌-15","周芷若-14","赵敏-13","张强-20","张三丰-100","张深山-40","张良-35","王二麻子-37");
// 需求 要求只要年龄 并且年龄大与15岁
list.stream()
.map(s -> Integer.parseInt(s.split("-")[1])).filter(integer -> integer >15)
.forEach(System.out::println);
}
排序 sorted
@Test
public void TestList04() {
/**
* 2 定制排序
* sorted(Comparator com):定制排序,自定义Comparator排序器
* 3 升序
* 3.1 自然排序
* list = list.stream().sorted().collect(Collectors.toList());
* 3.2 定制排序
* 根据年龄升序排序。
* list = list.stream().sorted(Comparator.comparing(Student::getAge)).collect(Collectors.toList());
* 4 降序
* 4.1 自然排序
* 使用Comparator 提供的reverseOrder() 方法
* list = list.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
* 4.2 定制排序
* 根据年龄降序排序。
* list = list.stream().sorted(Comparator.comparing(Student::getAge).reversed()).collect(Collectors.toList());
* 5 多字段排序
* list = list.sorted(Comparator.comparing(Student::getName).thenComparing(Student::getAge)).collect(Collectors.toList());
*/
ArrayList<Book> arrayList = new ArrayList<>();
arrayList.add(new Book("红楼梦",100,"曹雪芹"));
arrayList.add(new Book("三国志",99,"罗贯中"));
arrayList.add(new Book("水浒传",101,"施耐庵"));
arrayList.add(new Book("西游记",1020,"吴承恩"));
//按照价格排序 降序
List<Book> list = arrayList.stream().sorted(new Comparator<Book>() {
@Override
public int compare(Book o1, Book o2) {
// return o1.getPrice() - o2.getPrice(); // 降序
return o2.getPrice() - o1.getPrice(); //升序
}
}).collect(Collectors.toList());
for (Book book : list) {
System.out.println("book = " + book);
}
// 默认是升序
ArrayList<Integer> arrayList = new ArrayList<>();
arrayList.add(1);
arrayList.add(2);
arrayList.add(5);
arrayList.add(3);
arrayList.stream().sorted().forEach(System.out::println);
arrayList.stream().sorted(Comparator.reverseOrder()).forEach(System.out::println); // 降序
}
Stream终结方法
这种终结方法后面都是返回值 要不然就是一个集合 要不然就是一个数组类型,或者void 中间方法返回的永远是Stream
forEach遍历
@Test
public void test14() {
// 排序
ArrayList<Integer> arrayList = new ArrayList<>();
arrayList.add(1);
arrayList.add(2);
arrayList.add(5);
arrayList.add(3);
arrayList.stream().sorted(Comparator.reverseOrder()).forEach(System.out::println); // 降序
}
count统计
@Test
public void test15() {
// 排序
ArrayList<Integer> arrayList = new ArrayList<>();
arrayList.add(1);
arrayList.add(2);
arrayList.add(5);
arrayList.add(3);
System.out.println("arrayList.stream().count() = " + arrayList.stream().count());
}
toArray方法 放到数组中
@Test
public void test16() {
// 排序
ArrayList<Integer> arrayList = new ArrayList<>();
arrayList.add(1);
arrayList.add(2);
arrayList.add(5);
arrayList.add(3);
// 解释 Integer[] 这个是返回值类型数组,我们需要Integer类型 value是数组中的个数
// 返回值new Integer[value]; 直接及时new一个数组 并且个数就是value
Integer[] toArray = arrayList.stream().toArray(new IntFunction<Integer[]>() {
@Override
public Integer[] apply(int value) {
return new Integer[value];
}
});
// 改成拉姆达表达式形式
Integer[] array = arrayList.stream().toArray(value -> new Integer[value]);
Integer[] array1 = arrayList.stream().toArray(Integer[]::new);
System.out.println(Arrays.toString(array1));
ArrayList<String> strings = new ArrayList<>();
strings.add("p");
strings.add("u");
strings.add("o");
Object[] toArray1 = strings.stream().toArray();
System.out.println(Arrays.toString(toArray1)); //[p, u, o]
}
三种收集方法
@Test
public void test17() {
ArrayList<String> arrayList = new ArrayList<>();
Collections.addAll(arrayList,"张无忌-男-15","周芷若-女-14","赵敏-女-13","张强-男-20",
"张三丰-男-109","张翠山-男-40","张良-男-35","王二麻子-男-37","谢广坤-男-41");
// 要求 把所有的男性, 收集
// 1. 收集为list
List<String> list = arrayList.stream().filter(s -> "男".equals(s.split("-")[1]))
.collect(Collectors.toList());
System.out.println("list = " + list);
// 2. 收集为set
Set<String> set = arrayList.stream().filter(s -> "男".equals(s.split("-")[1]))
.collect(Collectors.toSet());
System.out.println("set = " + set); // 可以去除重复的
// 3. 收集为map 键 为姓名 值 为年龄 "张无忌-男-15"
Map<String, Integer> map = arrayList.stream().filter(s -> "男".equals(s.split("-")[1]))
.collect(Collectors.toMap(
s -> s.split("-")[0], // 规定键
s -> Integer.parseInt(s.split("-")[2]) // 规定
));
System.out.println("map = " + map);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧