#学习笔记
Java 中的 Stream
类(java.util.stream.Stream
)是 Java 8 引入的核心特性之一,主要用于对集合、数组等数据源进行声明式、函数式风格的数据处理。它的核心作用是为复杂的数据操作提供一种高效、简洁且可并行化的编程模型。
一、Stream流的创建
//共用代码块
private static List<Integer> list;
static {
list = Arrays.asList(1,2,3);
}
1-1 .stream() 并发 遍历输出有序
Stream<Integer> stream = list.stream();
stream.forEach(System.out::println);
1-2 .parallelStream() 并行 遍历输出无序
Stream<Integer> parallelStream = list.parallelStream();
parallelStream.forEach(System.out::println);
1-3 Arrays.stream() 将数组中的元素转换成Stream对象
IntStream streamArray = Arrays.stream(new int[]{1, 2, 3});
streamArray.forEach(System.out::println);
1-4 Stream.of() 处理散点数据
Stream<Serializable> of = Stream.of(1, "hello", true, new int[]{1, 2, 3});
of.forEach(System.out::println);
1-5 Stream.iterate() 无限流 适用:等差数列 每个新元素基于前一个元素得出
//这里我先用匿名内部类方便理解 后面的我都用lambda表达式
//案例 从1开始差值为1输出4个数
Stream<Integer> iterate = Stream.iterate(1, new UnaryOperator<Integer>() {
@Override
public Integer apply(Integer integer) {
return ++integer;
}
}).limit(4); //限定输出4个数
iterate.forEach(System.out::println);
1-6 Stream.generate() 无限流 适用:随机数 独立生成生成元素 每个元素之间无依赖关系
//随机生成4个[0,10)内的整数
Stream<Integer> generate = Stream.generate(()->(int)(Math.random()*10)).limit(4);
generate.forEach(System.out::println);
二、Stream流简单API使用
2-1 过滤(Filter)
// 导包就自己导了
public class StreamFilter {
// 过滤
public static void main(String[] args) {
List<Integer> list = Arrays.asList(2, 4, 6, 8, 1, 3, 5, 7, 10, 2, -1, -2);
/*
需求
①选出偶数 2,4,6,8,10,-2,2
②去除重复的 2,4,6,8,10,-2
③保留4个数 2,4,6,8
④跳过两个元素 6,8
*/
list.stream().filter(i->i%2==0) //选出偶数
.distinct() //去重
.limit(4) //保留4个数
.skip(2) //跳过2个元素
.forEach(System.out::println);
}
}
2-2 映射(Map)
public class StreamMap {
//案例 需求:将集合中所有字母都变成小写
public static void main(String[] args) {
List<String> list = Arrays.asList("I", "LOVE", "CHINA");
list.stream().map(String::toLowerCase).forEach(System.out::println);
}
}
2-3 扁平化(FlatMap)
public class StreamFlatMap {
public static void main(String[] args) {
List<Integer> list1 = Arrays.asList(1, 2, 3);
List<Integer> list2 = Arrays.asList(4, 5, 6);
//这是没有扁平化之前的流
//每个元素都是列表对象
Stream.of(list1,list2).forEach(System.out::println);
//这是扁平化之后的流
//flatMap的作用是将每个元素转换为一个流,然后将所有这些流合并成一个单一的流。
Stream.of(list1,list2).flatMap(i->i.stream()).forEach(System.out::println);
}
}
2-4 排序(Sort)
public class Sort {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(-2, 3, 4, -4, 9, -8, 10);
//升序
list.stream().sorted().forEach(System.out::println);
System.out.println("❀❀❀❀❀❀❀");
//降序
list.stream().sorted(Comparator.reverseOrder()).forEach(System.out::println);
}
}
2-5 匹配(Match)
public class Match {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(2, -1, 4, 0, 3);
//需求1:是否list中所有的元素都大于0
boolean b1 = list.stream().allMatch(i -> i > 0);//false
System.out.println("是否list中所有的元素都大于0:"+b1);
//需求2:是否list中存在小于0的数
boolean b2 = list.stream().anyMatch(i -> i < 0);//true
System.out.println("是否list中存在小于0的数:"+b2);
//需求3:没有一个数大于10吗
boolean b3 = list.stream().noneMatch(i -> i > 10);//true
System.out.println("没有一个数大于10吗:"+b3);
//需求4:返回集合中第一个元素
Optional<Integer> first = list.stream().findFirst();
if (first.isPresent()){
System.out.println("集合中第一个元素:"+first.get());
}
}
}
2-6 统计(count)
学这一块的时候我第一个感觉就是很像数据库
public class StreamCount {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
//需求1 统计list中元素的个数
long count = list.stream().count();
System.out.println("list中元素的个数="+count);
//需求2 求出list中的最大值
Optional<Integer> max = list.stream().max(Comparator.comparingInt(i -> i));
System.out.println("list中的最大值="+max.get());
//需求3 求出list中的最小值
Optional<Integer> min = list.stream().min(Comparator.comparingInt(i -> i));
System.out.println("list中的最小值="+min.get());
}
}
2-7 Stream转换成集合和Collectors部分API
public class StreamCollection {
public static void main(String[] args) {
/*
将Stream对象转换成指定的 集合对象
*/
// 将Stream转换成List
List<Integer> list = Stream.of(1,2,3).collect(Collectors.toList());
System.out.println("list = " + list);
System.out.println("❀❀❀❀❀❀❀❀❀");
// 将Stream转换成Set
Set<Integer> set = Stream.of(1, 2, 3).collect(Collectors.toSet());
System.out.println("set = " + set);
System.out.println("❀❀❀❀❀❀❀❀❀");
// 将Stream转换成map 线性数据转换成散点数据没什么意义 转换key就是value
Map<Integer, Integer> map = Stream.of(1, 2, 3).collect(Collectors.toMap(key -> key, value -> value));
System.out.println("map = " + map);
System.out.println("❀❀❀❀❀❀❀❀❀");
/*
Collectors不但提供了 统计 求和 求平均值 求最大值 求最小值 的方法,还有统计所有信息的方法
*/
//统计
Long count = list.stream().collect(Collectors.counting());
System.out.println("count = " + count);
//求和
System.out.println("sum = " + list.stream().collect(Collectors.summingInt(i -> i)));
//统计所有信息
System.out.println("allinfo = " + list.stream().collect(Collectors.summarizingInt(i -> i)));
//求均值
System.out.println("average = " + list.stream().collect(Collectors.averagingInt(i -> i)));
System.out.println("❀❀❀❀❀❀❀❀❀");
Optional<Integer> max = Stream.of(1,9,2,4,2,6).collect(Collectors.maxBy(Comparator.comparingInt(i -> i)));
if (max.isPresent()){
System.out.println("max = " + max.get());
}
Optional<Integer> min = Stream.of(1,9,2,4,2,6).collect(Collectors.minBy(Comparator.comparingInt(i -> i)));
if (min.isPresent()){
System.out.println("main = " + min.get());
}
}
}
2-8分组(Group)和分区(Partition)
2.8.1先创建一个实体类方便测试
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Product {
private long id;
private String name;
private int price;
private String brand;
}
2.8.2测试类代码
public class Group {
private static List<Product> products = new ArrayList<>();
static {
products.add(new Product(1,"小米12",3200,"小米"));
products.add(new Product(2,"Redmi K60",2399,"小米"));
products.add(new Product(3,"iphone12",4300,"苹果"));
products.add(new Product(4,"华为P60",9999,"华为"));
}
public static void main(String[] args) {
//需求:按照品牌分组 一共分了3组
Map<String, List<Product>> map = products.stream()
.collect(Collectors.groupingBy(Product::getBrand));
System.out.println(map);
/*
输出结果如下
{苹果=[Product(id=3, name=iphone12, price=3300, brand=苹果)],
华为=[Product(id=4, name=华为P60, price=9999, brand=华为)],
小米=[Product(id=1, name=小米12, price=3200, brand=小米),
Product(id=2, name=Redmi K60, price=2399, brand=小米)]}
*/
//需求:以4000元为边界分区
Map<Boolean, List<Product>> collect = products.stream()
.collect(Collectors.partitioningBy(p -> p.getPrice() > 4000));
//大于4000的分在true区域,小于等于4000的分给false区域
System.out.println(collect);
/*
输出结果如下
{false=[Product(id=1, name=小米12, price=3200, brand=小米), Product(id=2, name=Redmi K60, price=2399, brand=小米)],
true=[Product(id=3, name=iphone12, price=4300, brand=苹果), Product(id=4, name=华为P60, price=9999, brand=华为)]}
*/
}
}