Stream流
1. 获取Stream流
1.1 单列集合
List<String> list = new ArrayList<String>();
Collections.addAll(list, "a", "b", "c", "d");
list.stream().forEach(str -> System.out.print(str + "\t"));
Set<String> set = new HashSet<String>();
Collections.addAll(set, "a", "b", "c", "d");
set.stream().forEach(str -> System.out.print(str + "\t"));
1.2 双列集合
Map<String,Integer> map = new HashMap<String, Integer>();
map.put("a", 1);
map.put("b", 2);
map.put("c", 3);
map.keySet().stream().forEach(k -> System.out.print(k + "\t"));
System.out.println("\n");
map.values().stream().forEach(v -> System.out.print(v + "\t"));
System.out.println("\n");
map.entrySet().stream().forEach(entry -> System.out.print(entry + "\t"));
System.out.println("\n");
1.3 数组
String[] strArray = {"hello","world","java"};
Arrays.stream(strArray).forEach(str -> System.out.print(str + "\t"));
System.out.println("\n");
1.4 其他
Stream<String> stream1 = Stream.of("hello", "world", "java");
Stream<Integer> stream2 = Stream.of(10, 20, 30);
2. 中间方法
2.1 filter()
- 按照一定的规则过滤流中的数据
ArrayList<String> list = new ArrayList<>();
list.add("张三丰");
list.add("张无忌");
list.add("张翠山");
list.add("王二麻子");
list.add("张良");
list.add("谢广坤");
/*
* Stream<T> filter(Predicate predicate):过滤
* Predicate接口中的方法 boolean test(T t):
* 对给定的参数进行判断,返回一个布尔值
*/
list.stream().filter(new Predicate<String>() {
@Override
public boolean test(String s) {
return s.startsWith("张");
}
}).forEach(System.out::println);
// 简化
list.stream().filter(s -> s.startsWith("张")).forEach(System.out::println);
2.2 limit() & skip()
- limit(long n) 只保留流中前n个元素
- skip(long n) 跳过流中的前n个元素
// 创建一个集合,存储多个字符串元素
ArrayList<String> list = new ArrayList<String>();
list.add("林青霞");
list.add("张曼玉");
list.add("王祖贤");
list.add("柳岩");
list.add("张敏");
list.add("张无忌");
// 取前3个数据在控制台输出
list.stream().limit(3).forEach(System.out::println);
// 跳过3个元素,把剩下的元素在控制台输出
list.stream().skip(3).forEach(System.out::println);
// 跳过2个元素,把剩下的元素中前2个在控制台输出
list.stream().skip(2).limit(2).forEach(System.out::println);
2.3 distinct()
- 去除流中相同的元素
//创建一个集合,存储多个字符串元素
ArrayList<String> list = new ArrayList<String>();
list.add("林青霞");
list.add("林青霞");
list.add("林青霞");
list.add("林青霞");
list.add("张曼玉");
list.add("王祖贤");
list.add("柳岩");
list.add("张敏");
list.add("张无忌");
// 去除重复的字符串
list.stream().distinct().forEach(System.out::println);
2.4 map()
- 将流中的元素转换成指定的类型
//创建一个集合,存储多个字符串元素
ArrayList<String> list = new ArrayList<String>();
list.add("林青霞-10");
list.add("张曼玉-15");
list.add("王祖贤-90");
list.add("柳岩-20");
list.add("张敏-46");
list.add("张无忌-18");
// 转换并打印数字
list.stream().map(new Function<String, Integer>() {
@Override
public Integer apply(String s) {
String numStr = s.split("-")[1];
return Integer.valueOf(numStr);
}
}).forEach(System.out::println);
// 精简的写法
list.stream()
.map(s -> Integer.valueOf(s.split("-")[1]))
.forEach(System.out::println);
2.5 Stream.concat()
- 合并两个流
//创建一个集合,存储多个字符串元素
ArrayList<String> list = new ArrayList<String>();
list.add("林青霞");
list.add("张曼玉");
list.add("王祖贤");
list.add("柳岩");
list.add("张敏");
list.add("张无忌");
//需求1:取前4个数据组成一个流
Stream<String> s1 = list.stream().limit(4);
//需求2:跳过4个数据组成一个流
Stream<String> s2 = list.stream().skip(4);
//需求3:合并需求1和需求2得到的流,并把结果在控制台输出
Stream.concat(s1, s2).forEach(System.out::println);
//需求4:合并需求1和需求2得到的流,并把结果在控制台输出,要求字符串元素不能重复
Stream.concat(s1,s2).distinct().forEach(s-> System.out.println(s));
3. 终结方法
3.1 forEach()
ArrayList<String> list = new ArrayList<>();
list.add("张三丰");
list.add("张无忌");
list.add("张翠山");
list.add("王二麻子");
list.add("张良");
list.add("谢广坤");
// void forEach(Consumer action) 对此流的每个元素执行操作
list.stream().forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
// 简化
list.stream().forEach(System.out::println);
3.2 toArray()
ArrayList<String> list = new ArrayList<>();
list.add("张三丰");
list.add("张无忌");
list.add("张翠山");
list.add("王二麻子");
list.add("张良");
list.add("谢广坤");
// Object[] toArray() 返回流生成的数组
Object[] array1 = list.stream().toArray();
System.out.println(Arrays.toString(array1));
// <A> A[] toArray(IntFunction<A[]> generator) 返回流生成的指定类型的数组
/*
* 1. IntFunction的泛型是要返回的具体类型
* 2. apply的形参是流中数据的个数,要跟数组的长度保持一致
* 3. apply的返回值是具体类型的数组
* */
String[] array2 = list.stream().toArray(new IntFunction<String[]>() {
@Override
public String[] apply(int value) {
return new String[value];
}
});
System.out.println(Arrays.toString(array2));
// 简化
/*
* 1. toArray方法的参数的作用:负责创建一个指定类型的数组
* 2. toArray方法的底层,会依次得到流里面的每一个数据,并把数据放到数组中
* 3. toArray方法的返回值:是一个装着流里面所有数据的数组
* */
String[] array3 = list.stream().toArray(num -> new String[num]);
System.out.println(Arrays.toString(array3));
3.3 collect()
ArrayList<String> list = new ArrayList<>();
list.add("小明-男-18");
list.add("小明-男-18");
list.add("小红-女-31");
list.add("小王-男-12");
list.add("小李-女-64");
list.add("小张-男-32");
list.add("小强-男-55");
list.add("小刚-女-21");
// 获取list中性别为男的元素,并转成一个新的list集合
List<String> newList1 = list.stream().filter(s -> "男".equals(s.split("-")[1])).toList();
List<String> newList2 = list.stream().filter(s -> "男".equals(s.split("-")[1])).collect(Collectors.toList());
System.out.println(newList1);
System.out.println(newList2);
// 获取list中性别为男的元素,并转成一个新的set集合
Set<String> newSet = list.stream().filter(s -> "男".equals(s.split("-")[1])).collect(Collectors.toSet());
System.out.println(newSet);
// 将数据转成map的格式,使用名字作为key,年龄作为value
Map<String, Integer> newMap1 = list.stream().distinct().collect(Collectors.toMap(
new Function<String, String>() {
@Override
public String apply(String s) {
return s.split("-")[0];
}
},
new Function<String, Integer>() {
@Override
public Integer apply(String s) {
return Integer.parseInt(s.split("-")[2]);
}
}
));
// 简化
Map<String, Integer> newMap2 = list.stream()
.distinct()
.collect(
Collectors.toMap(
s -> s.split("-")[0],
s -> Integer.parseInt(s.split("-")[2]))
);
System.out.println(newMap1);
System.out.println(newMap2);
3.4 count()
ArrayList<String> list = new ArrayList<>();
list.add("张三丰");
list.add("张无忌");
list.add("张翠山");
list.add("王二麻子");
list.add("张良");
list.add("谢广坤");
// long count() 返回此流中的元素数
System.out.println(list.stream().count());
4. 练习
1. 练习1
/*
* 1. 定义一个集合,并添加一些整数1,2,3,4,5,6,7,8,9,10
* 过滤奇数,只保留偶数,并将结果保存为数组
* */
public static void main(String[] args) {
List<Integer> nums = new ArrayList<>();
Collections.addAll(nums, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Integer[] array = nums.stream().filter(num -> num % 2 == 0).toArray(Integer[]::new);
System.out.println(Arrays.toString(array));
}
2. 练习2
/*
* 2. 创建一个ArrayList集合,并添加一下字符串,字符串前面是姓名,后面是年龄
* “zhangsan”, 23
* "lisi", 45
* "wangwu", 25
* 保留年龄大于等于24的人,并将结果收集到Map集合中,姓名为键,年龄为值
* */
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "zhangsan,23", "lisi,45", "wangwu,37");
Map<String, Integer> collect = list.stream()
.filter(s -> Integer.parseInt(s.split(",")[1]) >= 24)
.collect(
Collectors.toMap(
s -> s.split(",")[0],
s -> Integer.parseInt(s.split(",")[1])
)
);
System.out.println(collect);
}
3. 练习3
/*
* 3. 现在有两个ArrayList集合,分别存储6名男演员名称和6名女演员名称,要求完成如下的操作
* 男演员只要名字为3个字的前三人
* 女演员只要姓林的,并且不要第一个
* 把过滤后的男演员姓名和女演员姓名合并到一起
* 把上一步操作后的元素作为构造方法的参数创建演员对象,遍历数据
* 演员类Actor已经提供,里面有一个成员变量,一个带参构造方法,以及成员变量对应的get/set方法
* */
public static void main(String[] args) {
//创建集合
ArrayList<String> manList = new ArrayList<String>();
manList.add("周润发");
manList.add("成龙");
manList.add("刘德华");
manList.add("吴京");
manList.add("周星驰");
manList.add("李连杰");
ArrayList<String> womanList = new ArrayList<String>();
womanList.add("林心如");
womanList.add("张曼玉");
womanList.add("林青霞");
womanList.add("柳岩");
womanList.add("林志玲");
womanList.add("王祖贤");
Stream<String> manStream = manList.stream().filter(s -> s.length() == 3).limit(3);
Stream<String> womanStream = womanList.stream().filter(s -> s.startsWith("林")).skip(1);
Stream.concat(manStream, womanStream)
.map(s -> new Actor(s))
.forEach(actor -> System.out.println(actor));
}
class Actor {
private String name;
public Actor(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Actor{" +
"name='" + name + '\'' +
'}';
}
本文是原创文章,转载请注明来自 Lazyking.site
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果
Steam卡片