乐趣区

关于java8:Java-Stream-API

Java Stream API

[TOC]

Java8 中 的 Steam 能够定义为来自起源的元素序列,Streams 反对对元素进行聚合操作,这里的元素指的是为流提供数据的汇合和 数组,在聚合操作中咱们能够依据咱们需要来获取出合乎咱们要求的数据

在操作 Stream 流之前咱们应该晓得,Streams API 都是间接针对流的操作,因而首先咱们要先会创立一个 Steam。

在粒度级别,Collection 和 Stream 之间的区别与计算事物的工夫无关。甲Collection 是一个存储器内数据结构,其中认为所述数据结构以后具备的所有值。必须先计算汇合中的每个元素,而后能力将其增加到汇合中。Stream 在概念上是一个管道,其中元素是按需计算的。

这个概念带来了显着的编程劣势。这个想法是,用户将仅从 Stream 中提取他们须要的值,并且这些元素仅在须要时(对用户不可见)生成。这是生产者 - 消费者关系的一种模式。

在 Java 中,java.util.Stream示意能够对其执行一个或多个操作的流。流操作要么是两头的,要么是终端的。

终端操作 返回一个特定类型的后果和 两头操作 返回流自身,所以咱们能够连锁的一排的多个办法,以在多个步骤中执行该操作。

流是在源上创立的,例如 java.util.Collection 喜爱 ListSet。在 Map 不间接反对,咱们能够创立映射键,值。

流操作能够程序或并行执行。当并行执行时,它被称为并行流

1. 创立流

上面给出了一些创立流的形式

1.1 Stream.of()
 public static void main(String[] args)
     {
         // 通过 Stream.of 办法获取一个数据流
         Stream<Integer> stream = Stream.of(1,2,3,4,5,6,7,8,9);
         stream.forEach(p -> System.out.println(p));
     }
1.2 Stream.of(数组)

咱们能够通过引入一个数组的形式生成一个流

public static void main(String[] args)
     {Stream<Integer> stream = Stream.of( new Integer[]{1,2,3,4,5,6,7,8,9} );
         stream.forEach(p -> System.out.println(p));
     }
1.3 列表.steam(罕用)

工作中咱们常常应用通过一个汇合来获取一个流,流中的元素都是来自 List

public static void main(String[] args)
     {List<Integer> list = new ArrayList<Integer>();
 
         for(int i = 1; i< 10; i++){list.add(i);
         }
 
         Stream<Integer> stream = list.stream();
         stream.forEach(p -> System.out.println(p));
     }
1.4 Stream.generate() 或者 Stream.iterate()

// 上面的代码中,咱们从给的元素中创立一个流,然而咱们只是限度去获取 20 个,因而咱们用 limit 进行限度

 public static void main(String[] args)
     {
         Stream<Integer> randomNumbers = Stream
             .generate(() -> (new Random()).nextInt(100));
 
         randomNumbers.limit(20)
              .forEach(System.out::println);
     }

1.5 字符串字符流

public static void main(String[] args)
     {IntStream stream = "12345_abcdefg".chars();
        stream.forEach(p -> System.out.println(p));
         
    //OR
         
        Stream<String> stream = Stream.of("A$B$C".split("\\$"));
        stream.forEach(p -> System.out.println(p));
     

1.6 Stream.builder()

通过创立一个 builder 办法创立一个建造器, 同样生成流

Stream<Object> name = Stream.builder().add("name").build();

2. Stream Collector(流收集器)

在对流中的元素执行中间件操作后, 咱们能够 应用流收集器办法再次将解决过的元素收集到一个汇合中

2.1 将 stream 中的元素收集到一个汇合中

在给定的例子中,首先,咱们在整数 1 到 10 上创立一个流。而后咱们解决流元素以找到所有偶数. 最初将所有的偶数收集到一个汇合中

 public static void main(String[] args)
     {List<Integer> list = new ArrayList<Integer>();
 
         for(int i = 1; i< 10; i++){list.add(i);
         }
 
         Stream<Integer> stream = list.stream();
         List<Integer> evenNumbersList = stream.filter(i -> i%2 == 0)
                                                .collect(Collectors.toList());
         System.out.print(evenNumbersList);
     }
2.2 将 stream 中元素收集到数组中

和上一个实例中的需要一样, 这次咱们是将偶数收集到一个数组中

List<Integer> result = new ArrayList<>();
        for (Integer x : list) {if (x % 2 == 0) {result.add(x);
            }
        }

Integer[] evenNumbersArr = list.stream().filter(x -> x% 2 == 0).toArray(Integer[]::new);


当然流收集器不仅仅能够收集到 List 中, 还有 Set,Map 等方面, 都能够通过 Collectors 进行调用实现

3. 流操作

针对流的操作分为两种 两头流操 作 和 终端操作

  • 两头流操作 操作之后返回的还是一个 Steam 流,
  • 终端操作 操作之后间接对六中的数据进行解决, 没有返回值

    List<String> memberNames = new ArrayList<>();memberNames.add("Amitabh");memberNames.add("Shekhar");memberNames.add("Aman");memberNames.add("Rahul");memberNames.add("Shahrukh");memberNames.add("Salman");memberNames.add("Yana");memberNames.add("Lokesh");
3.1.1 Stream.filter (过滤)
 过滤操作接管了一个 Predicate 类型的办法, 返回一个 合乎 predicate  要求的 steam 流, 比方从以上的汇合中获取 是 A 结尾的城市
memberNames.stream().filter((s) -> s.startsWith("A"))                    .forEach(System.out::println);
3.1.2 Stream.map (转换, 映射)

map 操作 我认为是一种转换或者映射的操作, 例如 咱们将汇合中的小写 字符都转变成大写字符

memberNames.stream().filter((s) -> s.startsWith("A"))                    .map(String::toUpperCase)                    .forEach(System.out::println);
3.1.3 Stream.sorted (排序)

排序接口能够间接对汇合中的元素进行排序, 在 java 8 之前咱们要对 list 中的元素进行排序, 咱们可能比较复杂, 要用 sort 办法, 并用 Compare 匿名外部类, 写法比拟繁琐

memberNames.sort(new Comparator<String>() {@Override            public int compare(String o1, String o2) {return 0;}        });

然而 当初应用 java 8 之后, 咱们能够用另一种形式, 进行排序

memberNames.stream().sorted()                    .map(String::toUpperCase)                    .forEach(System.out::println);

这种形式默认的形式是正向排序, 如果想反向排序, 能够应用 reverse 办法进行扭转程序

3.2 终端操作

终端操作会返回终端操作的后果,

3.2.1 Stream.foreach

foreach 是一个遍历迭代的性能

memberNames.forEach(System.out::println);
3.2.2 collect 收集

collect 是一个收集的办法, 从 Stream 中获取合乎的数据 而后贮存到一个汇合中

List<String> memNamesInUppercase = memberNames.stream().sorted()                            .map(String::toUpperCase)                            .collect(Collectors.toList());         System.out.print(memNamesInUppercase);
3.2.3 match 匹配

match 是 我针对 match 类办法的一种统称, 和 之前讲的 filter 差不多, 然而性能上略微弱小一些, 而且办法比拟多

// 只有 元素中 有一个合乎  是 A 开始的就返回 Trueboolean matchedResult = memberNames.stream()        .anyMatch((s) -> s.startsWith("A")); System.out.println(matchedResult); // 如果元素全副是用 A 结尾的, 那么返回 TruematchedResult = memberNames.stream()        .allMatch((s) -> s.startsWith("A")); System.out.println(matchedResult); // 如果元素没有用 A 结尾的, 返回 truematchedResult = memberNames.stream()        .noneMatch((s) -> s.startsWith("A")); System.out.println(matchedResult);
4.2.4. Stream.count ()

计数的一个终端操作, 返回一个 long 型的 返回值

long totalMatched = memberNames.stream()    .filter((s) -> s.startsWith("A"))    .count(); System.out.println(totalMatched);
4.2.5. Stream.reduce ()

reduce 原意 缩小, 放大 , 依据指定的计算模型将 stream 中的值计算到一个最终后果,

针对这个办法有一个博主文章将的特地好, 在此借鉴一下 java8 reduce

总结 针对 stream 罕用操作方法进行了记录

两头操作

  • filter
  • map
  • distinct
  • sorted
  • peek
  • limit
  • skip

终端操作

  • foreach
  • toArray
  • reduce
  • foreachOrdered
  • min
  • max
  • count
  • anyMatch
  • collect
  • findfirst 等
退出移动版