Java学习

Java Stream流操作

2020-07-16  本文已影响0人  xiaogp

Java流操作概览

在处理集合时如果需要遍历元素, 并且对每一个元素进行某项操作, 就可以使用Java的流操作

(1) 流操作不更改原始集合, 会生成一个新的集合
(2) 流操作是懒惰执行的, 直到需要拿到执行结果的时候才会执行

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

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

        // filter
        // Arrays
        String[] a = {"a", "bb", "ccc", "dd"};
        long aCount = Arrays.stream(a).filter(x -> x.length() >= 2).count();
        System.out.println(aCount);
        List<String> aa = Arrays.stream(a).filter(x -> x.length() >= 2).collect(Collectors.toList());
        System.out.println(aa);

        // ArrayList
        ArrayList<String> b = new ArrayList<>(Arrays.asList("a", "bb", "ccc", "dd"));
        long bCount = b.stream().filter(x -> x.length() >= 2).count();
        System.out.println(bCount);
        List<String> bb = b.stream().filter(x -> x.length() >= 2).collect(Collectors.toList());
        System.out.println(bb);

        // 使用parallelStream可以并行
        List<String> bbb = b.parallelStream().filter(x -> x.length() >= 2).collect(Collectors.toList());
        System.out.println(bbb);
    }
}

Java流的创建

Collection有stream接口直接创建流, 数组可以通过stream.of静态方法, 或者Arrays.stream可以指定数组的开始和结束位置

// 几种创建流的方式
 // 数组
Stream<Integer> aStream = Stream.of(1, 2, 3, 4, 5);
List<Integer> aList = aStream.filter(x -> x > 3).collect(Collectors.toList());
System.out.println(aList);  // [4, 5]

Stream<String> bStream = Stream.of("1,2,3,4,5".split(","));
List<Integer> bList = bStream.map(x -> Integer.valueOf(x)).filter(x -> x >3).collect(Collectors.toList());
System.out.println(bList);  // [4, 5]

Stream<String> cStream = Arrays.stream("1,2,3,4,5".split(","));
List<Integer> cList = cStream.map(x -> Integer.valueOf(x)).filter(x -> x >3).collect(Collectors.toList());
System.out.println(cList);  // [4, 5]

// 指定数组的开始结束索引位置
Integer[] tmpArray = {1, 2 ,3 ,4, 5};
Stream<Integer> dStream = Arrays.stream(tmpArray, 1, 3);
dStream.forEach(x -> System.out.println(x)); // 2, 3

// 集合Collection
Stream<Integer> eStream = Arrays.asList(1, 2, 3, 4, 5).stream();
List<Integer> eList = eStream.filter(x -> x > 3).collect(Collectors.toList());
System.out.println(eList);  // [4, 5]

转换操作 filter, map, flatMap

流的转换会产生一个新的流, 转换操作需要指定转换函数, 可以使用lambda表达式或者方法引用::

// map
// lambda表达式
 List<Integer> fList = Arrays.asList(1, 2, 3, 4, 5).stream().map(x -> x + 1).collect(Collectors.toList());
System.out.println(fList);
// 方法引用::
List<Integer> gList = Arrays.asList(1, 2, 3, 4, 5).stream().map(streamTest::inc1).collect(Collectors.toList());
System.out.println(gList);
private static Integer inc1(Integer value) {
        return value + 1;
    }

抽取子流 limit和skip

// 抽取子流 limit skip
List<Integer> iList = Arrays.asList(1, 2, 3, 4, 5);
iList.stream().limit(3).forEach(x -> System.out.print(x));  // 123
System.out.println();
iList.stream().skip(1).forEach(x -> System.out.print(x));  // 2345

获取无限流

// 获取无限流
Stream<Integer> jStream = Stream.generate(() -> 1);  // 生成全是1的无限流
//        jStream.forEach(x -> System.out.println(x));
Stream<Double> kStream = Stream.generate(Math::random).limit(10);  // 生成10个[0,1)之间的随机小数
kStream.forEach(x -> System.out.println(x));

排序

// 排序
List<Integer> lList = Arrays.asList(1, 3, 5, 2, 4);
List<Integer> mList = lList.stream().sorted().collect(Collectors.toList());
System.out.println(mList);  // [1, 2, 3, 4, 5]
List<Integer> nList = lList.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
System.out.println(nList);  // [5, 4, 3, 2, 1]

收集结果

可以将流操作之后的结果收集为ArrayListHashSetHashMapString

        Stream<String> stream = Stream.of("2", "2", "3");
        List<String> list = stream.map(s -> s + "_").collect(Collectors.toList());
        Set<String> set = stream.map(s -> s + s).collect(Collectors.toSet());
        Map<String, String> map = stream.map(s -> s + s).collect(Collectors.toMap(k -> k, v -> v + "_", (o, n) -> n));
        String string = stream.collect(Collectors.joining(","));  // 2,2,3

在sql语句in条件查询使用stream收集为,分割字符串:

        conn = connPool.getConnection();
        stmt = conn.createStatement();
        String param = myCollections.stream().map(s -> "\"" + s + "\"").collect(Collectors.joining(","));
        ResultSet rs = stmt.executeQuery(String.format("select feature2 from table where feature1 in (%s) and status='Y'", param));
                while (rs.next()) {
                // TODO
                }

Collectors.toMap第一个参数是获得key,第二个参数是获得value,第三个参数是解决key冲突的处理方式

public static void streamToMao() {
        List<String> a = new ArrayList<>(Arrays.asList("a", "b", "c", "d"));
        Map<String, String> b = a.stream().collect(Collectors.toMap(s -> s, s -> s, (o, n) -> n));
        Map<String, String> c = a.stream().collect(Collectors.toMap(s -> s + "_" + s, s -> s, (o, n) -> n));
        // 方法引用
        Map<String, String> d = a.stream().collect(Collectors.toMap(test2::getString, v -> v, (o, n) -> n));;
        // 等同于
        Map<String, String> e = new HashMap<>();
        for (String item: a) {
            e.put(item + "_" + item, item);
        }
    }

使用基本类型流

使用包装器Stream<>是低效的, 流库有专门的类型IntStream, LongStream, DoubleStream, 无需使用包装器

// 使用基本类型流
IntStream intStream1 = IntStream.of(1, 2, 3, 4, 5);
intStream1.forEach(System.out::print);
DoubleStream doubleStream1 = DoubleStream.of(1.0, 2.0, 3.0);
doubleStream1.forEach(System.out::print);

多维数组的流操作

// 多维数组
Integer[][] multiArray = {{1, 2, 3}, {2, 3, 4}};
Stream<Integer[]> multiStream = Stream.of(multiArray);
//        multiStream.forEach(x -> System.out.println(Arrays.toString(x)));
// 每个元素求长度
//        List<Integer> xLength = multiStream.map(x -> x.length).collect(Collectors.toList());
//        System.out.println(xLength);  // [3, 3]
 // 每个元素求最大
List<Integer> xMax = multiStream.map(x -> Collections.max(Arrays.asList(x))).collect(Collectors.toList());
System.out.println(xMax);  // [3, 4]
上一篇 下一篇

猜你喜欢

热点阅读