JDK8新特性之Stream流详解

JDK8新特性之Stream流式操作

  • 1 流概述
  • 2 Stream流的几种获得方式
  • 3 Stream流的筛选操作
  • 4 Stream流的map映射
  • 5 Stream流的查找与匹配
  • 5 Stream流的reduce规约
  • 6 Stream流映射到数值流
  • 7 Stream流的collect规约
  • 7 Stream流的实际使用

1 流概述

  流是 JDK8 新增的成员,允许以声明性方式处理数据集合,可以把 Stream 流看作是遍历数据集合的一个高级迭代器
  使用流的好处: 代码以声明性方式书写:说明想要完成什么,而不是说明如何完 成一个操作 可以把几个基础操作连接起来,来表达复杂的数据处理的流水 线,同时保持代码清晰可读

  流是什么?
  从支持数据处理操作的源生成元素序列.数据源可以是集合,数组 或 IO 资源
  从操作角度来看,流与集合是不同的. 流不存储数据值; 流的目的 是处理数据,它是关于算法与计算的. 如果把集合作为流的数据源,创建流时不会导致数据流动; 如果流 的终止操作需要值时,流会从集合中获取值; 流只使用一次 流中心思想是延迟计算,流直到需要时才计算值
JDK8新特性之Stream流详解_第1张图片
流使用时一般包括三件事:
  1) 一个数据源(如集合)来执行一个查询;
  2) 一个中间操作链,形成一条流的流水线
   3) 一个终端操作,执行流水线,生成结果

2 Stream流的几种获得方式

public class Test01 {
    public static void main(String[] args) {
        //1 如何获得流,可以通过 Collection 集合,数据, 根据字面量获得流
        // 1.1 通过 Collection 获得流
        List<String> list = new ArrayList<>();
        Collections.addAll(list, "aa", "hello", "jj", "dd", "mm", "test");
        Stream<String> stream1 = list.stream();
        System.out.println(stream1);
        stream1.forEach(System.out::println);

        //  1.2 根据数组获得流
        String[]data = {"zhangsan","lisi","wangwu"};
        Stream<String> stream2 = Arrays.stream(data);
        stream2.forEach(s -> System.out.print(s + " "));
        System.out.println();

        // 1.3 直接通过值获得流
        Stream<String> stream3 = Stream.of("1", "2", "3", "4");
        stream3.forEach(s -> System.out.print(s + " "));
        System.out.println();

        // 1.4 无限流
        Stream.iterate(100, x -> x + 3).limit(10).forEach(s -> System.out.print(s + " "));
        System.out.println();
    }
}
java.util.stream.ReferencePipeline$Head@50040f0c
aa
hello
jj
dd
mm
test
zhangsan lisi wangwu 
1 2 3 4 
100 103 106 109 112 115 118 121 124 127 

3 Stream流的筛选操作

public class Test01 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        Collections.addAll(list, "aa", "aa", "cc", "d","bb");

        Stream<String> stream = list.stream();

        //流的筛选与切片
        //去重:distinct()
        stream.distinct().forEach(System.out::println);
        System.out.println("-------------1-----------");

        //过滤filter(Predicate predicate); 传递一个Predicate接口
        //   stream.filter(x -> x.length()>2).forEach(System.out::println);

        //java.lang.IllegalStateException:  流只能使用一次

        list.stream().filter(x -> x.length() > 2).forEach(System.out::println);
        System.out.println("-------------2-----------");

        //sorted()排序操作  Comparator comparator 传递一个Comparator接口
        list.stream().sorted(String::compareTo).forEach(System.out::println);
        System.out.println("-------------3-----------");

        //limt()截断操作
        list.stream().limit(5).forEach(System.out::println);
        System.out.println("--------------4----------");

        //skip()跳过
        list.stream().skip(3).forEach(System.out::println);
        System.out.println("---------------5---------");

    }
}
aa
cc
d
bb
-------------1-----------
-------------2-----------
aa
aa
bb
cc
d
-------------3-----------
aa
aa
cc
d
bb
--------------4----------
d
bb
---------------5---------

Process finished with exit code 0

4 Stream流的map映射

public class Test02 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        Collections.addAll(list, "aa", "aa", "bb", "cc", "d", "eeeeee");

        //map(Function mapper); 传递一个Function接口

        //为每个元素应用toUpperCase()把小写转换为大写
        list.stream().map(String::toUpperCase).forEach(System.out::println);

        //list每个每个元素的长度,然后拼接空格  2 2 2 2 1 6
        list.stream().map(String::length).map(len->len + " ").forEach(System.out::println);
        System.out.println("----------2-------");
        
        //转换为数值流
        List<Integer> integerList= Arrays.asList(54,1,78,90,345);
        IntStream intStream = integerList.stream().mapToInt(x->x);
        intStream.forEach(x->System.out.print(x+" "));

    }
}
AA
AA
BB
CC
D
EEEEEE
2 
2 
2 
2 
1 
6 
----------2-------
54 1 78 90 345 
Process finished with exit code 0

5 Stream流的查找与匹配

public class Test03 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        Collections.addAll(list, "aa", "aa", "bb", "cc", "d", "eeeeee", "sssssss");

        //allMatch()判断流中所有的元素是否都匹配给定的谓词
        System.out.println(list.stream().allMatch(s -> s.length() > 3)); //false

        //anyMatch()判断流中是否有某个元素可以匹配指定的谓词
        System.out.println(list.stream().anyMatch(s -> s.equals("wkcto"))); //true

        //noneMathc()判断流中的元素是否都没有匹配指定谓词的
        System.out.println(list.stream().noneMatch(s -> s.equals("jj"))); //false

        //findAny()和findFirst()的返回值类型均为Optional

        //查找任意一个
        System.out.println(list.stream().filter(s -> s.length() > 5).findAny().get());

        //查找第一个
        try {
            System.out.println(list.stream().filter(s -> s.length() > 20).findFirst().get());
        }catch (Exception e) {
            e.printStackTrace();
        }

        //查找第一个,如果不加orElse 会输出Optional.empty
        System.out.println(list.stream().filter(s -> s.length() > 20).findFirst().orElse("不存在"));


    }
}
false
false
true
eeeeee
java.util.NoSuchElementException: No value present
	at java.util.Optional.get(Optional.java:135)
	at Test03.main(Test03.java:26)
不存在

Process finished with exit code 0

5 Stream流的reduce规约

public class Test04 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        Collections.addAll(list, "aa", "aa", "bb", "cc", "d", "eeeeee", "sssssss");

        //1 forEach 遍历
        list.stream().forEach(System.out::println);

        //2 cout 统计
        System.out.println(list.stream().filter(x -> x.length() > 2).count());

        //3 reduce 归纳合并
        //传递的是BinaryOperator accumulator 接口
        Optional<String> reduce = list.stream().reduce((s1, s2) -> s1 + "--" + s2);

        System.out.println(reduce.get());
        //传递Consumer consumer 接口
        reduce.ifPresent(System.out::println);

        //4数值操作
        List<Integer> list2 = Arrays.asList(6, 21, 87, 34, 1, 78, 54);

        //5求和,指定初始值
        //reduce(T identity, BinaryOperator accumulator);
        System.out.println(list2.stream().reduce(0, Integer::sum));

        //求和,没有初始值
        //Optional reduce(BinaryOperator accumulator);
        System.out.println(list2.stream().reduce((x, y) -> x + y).orElse(0));

        //6最值
        //Optional reduce(BinaryOperator accumulator);
        System.out.println(list2.stream().reduce(Math::max).get());
        System.out.println(list2.stream().reduce(Math::min).get());
    }
}
aa
aa
bb
cc
d
eeeeee
sssssss
2
aa--aa--bb--cc--d--eeeeee--sssssss
aa--aa--bb--cc--d--eeeeee--sssssss
281
281
87
1

Process finished with exit code 0

6 Stream流映射到数值流

public class Test05 {
    public static void main(String[] args) {
        List<Integer> list2 = Arrays.asList(6, 21, 87, 34, 1, 78, 54);

        //求和 IntStream mapToInt(ToIntFunction mapper);
        System.out.println(list2.stream().mapToInt(x->x).sum() );

        //最大值 OptionalInt max(); 
        //public int getAsInt() {
        //  if (!isPresent) {
        //      throw new NoSuchElementException("No value present");
        //  }
        //      return value;
        // }
        System.out.println(list2.stream().mapToInt(x->x).max().getAsInt() );

        //最小值 OptionalInt min();
        //public int orElse(int other) {
        //    return isPresent ? value : other;
        //}
        System.out.println(list2.stream().mapToInt(x->x).min().orElse(0) );

        //平均值
        //DoubleStream mapToDouble(ToDoubleFunction mapper);
        //OptionalDouble average();
        System.out.println(list2.stream().mapToDouble(x->x).average().getAsDouble());
        
        
        //求最大值
        System.out.println(list2.stream().max(Integer::compareTo).get()); 
        
        //求最小值
        list2.stream().min(Integer::compareTo).ifPresent(System.out::println);
    }
}
281
87
1
40.142857142857146
87
1

Process finished with exit code 0

7 Stream流的collect规约

public class Test06 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        Collections.addAll(list, "ss", "aa", "hello", "jj","hello","xx", "good");


        //把 stream 流转换为集合
        Set<String> stringSet = list.stream().collect(Collectors.toSet());
        System.out.println( stringSet );

        //把 Stream 流转换为数组
        Object[] objects = list.stream().toArray();
        System.out.println( Arrays.toString(objects));
        String[] toArray = list.stream().toArray(String[]::new);
        System.out.println(Arrays.toString(toArray));

        //Stream 流转换为字符串
        String collect = list.stream().collect(Collectors.joining(","));
        System.out.println(collect);
    }
}
[ss, aa, jj, xx, hello, good]
[ss, aa, hello, jj, hello, xx, good]
[ss, aa, hello, jj, hello, xx, good]
ss,aa,hello,jj,hello,xx,good

Process finished with exit code 0

7 Stream流的实际使用

  汽车枚举类

public enum CarType {
    HATCHBACK, THREECOMPARTMENT,SUV
}

  汽车实体类

public class Car {
    private String brand; //品牌
    private boolean sold; //是否已卖
    private int price;
    private CarType type; //车型

    public Car(String brand, boolean sold, int price, CarType type) {
        this.brand = brand;
        this.sold = sold;
        this.price = price;
        this.type = type;
    }
    public Car(){}

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Car car = (Car) o;
        return sold == car.sold &&
                price == car.price &&
                Objects.equals(brand, car.brand) &&
                type == car.type;
    }

    @Override
    public int hashCode() {
        return Objects.hash(brand, sold, price, type);
    }
    //省略setter和getter方法
    //省略toString 方法
}

  Stream 应用

public class Test {
    public static void main(String[] args) {

        //把 Car 小汽车的数据保存到 List 集合中
        List<Car> carshop = new ArrayList<>();

        carshop.add(new Car("Benz", false, 68, CarType.SUV));
        carshop.add(new Car("Audi", true, 28, CarType.HATCHBACK));
        carshop.add(new Car("BMW", false, 88, CarType.HATCHBACK));
        carshop.add(new Car("Geeley", true, 18, CarType.HATCHBACK));
        carshop.add(new Car("Xiali", true, 8, CarType.THREECOMPARTMENT));
        carshop.add(new Car("Haval", false, 18, CarType.SUV));
        carshop.add(new Car("Jeep", true, 38, CarType.SUV));
        carshop.add(new Car("Honda", false, 28, CarType.THREECOMPARTMENT));
        carshop.add(new Car("Chery", true, 18, CarType.THREECOMPARTMENT));
        carshop.add(new Car("Benz", false, 58, CarType.THREECOMPARTMENT));

        //1 根据价格降序排序后,显示汽车品牌
        carshop.stream()
                .sorted((c1,c2) -> c2.getPrice()-c1.getPrice())
                .map(Car::getBrand)
                .distinct()
                .forEach(System.out::println);
        System.out.println("======================1=========================");

        //2 找出已卖的车, 按价格升序排序
        carshop.stream()
                .filter(car -> car.isSold() )
                .sorted(Comparator.comparing(Car::getPrice))
                .forEach(System.out::println);
        System.out.println("======================2=========================");

        //3 查看有哪些车型
        carshop.stream()
                .map(car -> car.getType())
                .distinct()
                .forEach(System.out::println);
        System.out.println("=======================3========================");

        //4 SUV 型号的车有哪些
        List<Car> collect = carshop.stream()
                .filter(car -> car.getType() == CarType.SUV)
                .collect(Collectors.toList());
        System.out.println("=======================4========================");

        //5 40万以下的车的品牌, 排序
        carshop.stream()
                .filter(car -> car.getPrice() < 40)
                .map(Car::getBrand)
                .distinct()
                .sorted()
                .forEach(System.out::println);
        System.out.println("=========================5======================");

        //6 统计没有卖出去的车的数量
        System.out.println( carshop.stream().filter(car -> !car.isSold()).count() );
        System.out.println("=========================6====================");

        //7 判断是否有 Geeley 品牌的汽车
        System.out.println( carshop.stream().anyMatch(car -> "Geeley".equals(car.getBrand())));
        System.out.println("=========================7======================");

        //8 最贵的车的价格
        System.out.println(carshop.stream().map(Car::getPrice).reduce(Integer::max).get());
        System.out.println("=========================8======================");

        //9 显示已卖出去最贵的车
        System.out.println(carshop.stream().filter(Car::isSold)
                .reduce(BinaryOperator.maxBy((car1,car2) ->(car1.getPrice()-car2.getPrice())))
                .get()
        );
        System.out.println("=========================9======================");

        //9 显示已卖出去最贵的车
        System.out.println(carshop.stream().filter(Car::isSold)
                .collect(Collectors.maxBy(Comparator.comparing(Car::getPrice)))
                .get()
        );
        System.out.println("=========================10======================");

    }
}

  运行结果

BMW
Benz
Jeep
Audi
Honda
Geeley
Haval
Chery
Xiali
======================1=========================
Car{brand='Xiali', sold=true, price=8, type=THREECOMPARTMENT}
Car{brand='Geeley', sold=true, price=18, type=HATCHBACK}
Car{brand='Chery', sold=true, price=18, type=THREECOMPARTMENT}
Car{brand='Audi', sold=true, price=28, type=HATCHBACK}
Car{brand='Jeep', sold=true, price=38, type=SUV}
======================2=========================
SUV
HATCHBACK
THREECOMPARTMENT
=======================3========================
=======================4========================
Audi
Chery
Geeley
Haval
Honda
Jeep
Xiali
=========================5======================
5
=========================6====================
true
=========================7======================
88
=========================8======================
Car{brand='Jeep', sold=true, price=38, type=SUV}
=========================9======================
Car{brand='Jeep', sold=true, price=38, type=SUV}
=========================10======================

你可能感兴趣的:(JDK8)