JAVA8Streams版权声明

原创
小哥 3年前 (2022-11-11) 阅读数 46 #大杂烩

阅读目录

什么是Stream

首先要说的是,别被它的名字蒙蔽了,这里Stream跟JAVA I/O中的InputStream和OutputStream是两个不同的概念。Java 8中的Stream事实上,这是在函数编程中Monad概念Monad,感觉还是比较抽象的,不容易理解,可以参考 这篇文章 就我个人而言,我认为最好能理解。简单地说,Monad这是一种设计模式,意味着计算过程被分解为多个步骤,通过函数相互连接,这有点像链式操作。

如下所示,是Stream的例子

import java.util.Arrays; import java.util.List;

public class Snippet { public static void main(String[] args) { List myList = Arrays.asList("a1", "a2", "b1", "c2", "c1");

    myList
        .stream()
        .filter(s -> s.startsWith("c"))       //过滤以c字母开头
        .map(String::toUpperCase)        //字符变为大写
        .sorted()                                     //排序
        .forEach(System.out::println);    //打印输出
}

}

使用Stream的好处

  • 对JAVA集合(Collection)对象函数的增强促进了对集合的各种操作(过滤、寻找最大值、最小值、统计等);
  • 更高效,提供串行和并行模式,并行模式利用Java中的fork/join框架技术,可以充分利用多核处理器,提高程序并发性;

Stream的特征

  • 不是数据结构
  • 为lambda表情设计
  • 不支持索引访问
  • 输出为数组或集合很方便。
  • 惰性通道支架
  • 并行计算

如何得到Stream对象

从 Collection 和数组

  • Collection.stream()
  • Collection.parallelStream()
  • Arrays.stream(T array) or Stream.of()

从 BufferedReader

  • java.io.BufferedReader.lines()

静态工厂

  • java.util.stream.IntStream.range()
  • java.nio.file.Files.walk()

自己创建

  • java.util.Spliterator

其它

  • Random.ints()
  • BitSet.stream()
  • Pattern.splitAsStream(java.lang.CharSequence)
  • JarFile.stream()
  • 。。。

Stream操作类型

Stream有两种类型的操作:Intermediate操作和Terminal操作。

Intermediate(中间操作)

Stream可以多次执行Intermediate操作,如前一个示例所示,其中filter、map、sorted都是Intermediate操作,请注意该操作是惰性的,在调用方法时不会真正开始。Stream的遍历。

Terminal(结束操作)

一个Stream只有一个Terminal操作,如前一个示例所示,其中forEach就是Terminal操作,Terminal操作是Stream最后一次操作将仅在此时开始。Stream的遍历。

Stream使用示例

Stream的创建

使用Stream.of

import java.util.stream.Stream;

public class StreamBuilders { public static void main(String[] args) { Stream stream = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9); stream.forEach(p -> System.out.println(p)); } }

使用Arrays.stream

import java.util.Arrays; import java.util.stream.Stream;

public class StreamBuilders { public static void main(String[] args) { Stream stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9}); stream.forEach(p -> System.out.println(p)); } }

使用Collection.stream() or Collection.parallelStream()

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

public class StreamBuilders { public static void main(String[] args) { List list = new ArrayList(Arrays.asList(new Integer[]{ 1, 2, 3, 4, 5, 6, 7, 8, 9 }));

    Stream stream = list.stream();    //or list.parallelStream();
    stream.forEach(p -> System.out.println(p));
}

}

使用IntStream.range

import java.util.stream.IntStream;

public class StreamBuilders { public static void main(String[] args) { IntStream stream = IntStream.range(1, 9); stream.forEach(p -> System.out.println(p)); } }

使用Random.ints()

import java.util.Random; import java.util.stream.IntStream;

public class StreamBuilders { public static void main(String[] args) { IntStream stream = new Random().ints(1, 10); stream.forEach(p -> System.out.println(p)); } }

使用Stream.generate()

import java.util.concurrent.TimeUnit; import java.util.stream.Stream;

public class StreamBuilders { static int i = 0; public static void main(String[] args) { Stream stream = Stream.generate(() -> { try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } return i++; }); stream.forEach(p -> System.out.println(p)); } }

还有很多其他的,这里没有列出。

Stream要收集的类型/数组类型

使用stream.collect(Collectors.toList())

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

public class StreamBuilders { public static void main(String[] args) { List list = new ArrayList(Arrays.asList(new Integer[]{ 1, 2, 3, 4, 5, 6, 7, 8, 9 }));

    Stream stream = list.stream();

    List evenNumbersList = stream.filter(i -> i % 2 == 0).collect(Collectors.toList());

    System.out.print(evenNumbersList);
}

}

使用stream.toArray(EntryType[]::new)

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

public class StreamBuilders { public static void main(String[] args) { List list = new ArrayList(Arrays.asList(new Integer[]{ 1, 2, 3, 4, 5, 6, 7, 8, 9 }));

    Stream stream = list.stream();

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

    System.out.print(Arrays.asList(evenNumbersArr));
}

}

其它转为set,map类似,未列出。

Stream核心操作方法

Intermediate(中间操作),这里只列出了几个常见的操作。

filter方法,过滤元件

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

public class StreamBuilders { public static void main(String[] args) { List list = new ArrayList(Arrays.asList(new String[]{ "Amitabh", "Shekhar", "Aman", "Rahul", "Shahrukh", "Salman", "Yana", "Lokesh"}));

    Stream stream = list.stream();

    stream.filter((s) -> s.startsWith("A")).forEach(System.out::println);
}

}

map方法,修改元素

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

public class StreamBuilders { public static void main(String[] args) { List list = new ArrayList(Arrays.asList(new String[]{ "Amitabh", "Shekhar", "Aman", "Rahul", "Shahrukh", "Salman", "Yana", "Lokesh"}));

    Stream stream = list.stream();

    stream.filter((s) -> s.startsWith("A")).map(String::toUpperCase).forEach(System.out::println);
}

}

sorted方法sort可以传递到自定义排序接口。Comparator,

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

public class StreamBuilders { public static void main(String[] args) { List list = new ArrayList(Arrays.asList(new String[]{ "Amitabh", "Shekhar", "Aman", "Rahul", "Shahrukh", "Salman", "Yana", "Lokesh"}));

    Stream stream = list.stream();

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

}

**Terminal(结束操作) ,这里只列出了一些常见的。**

这里的示例与前一个类似,因此我不会编写所有代码并列出重要部分。

forEach方法,迭代元素,并执行相关操作。

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

collect方法,从Stream把布景放进去

    List memNamesInUppercase = stream.sorted().map(String::toUpperCase).collect(Collectors.toList());

    System.out.print(memNamesInUppercase);

Match方法、匹配判断Stream中的元素是否符合指定的规则

    boolean matchedResult = list.stream().anyMatch((s) -> s.startsWith("A"));

    System.out.println(matchedResult);

    matchedResult = list.stream().allMatch((s) -> s.startsWith("A"));

    System.out.println(matchedResult);

    matchedResult = list.stream().noneMatch((s) -> s.startsWith("A"));

    System.out.println(matchedResult);

count方法,计数

    long totalMatched = list.stream().filter((s) -> s.startsWith("A")).count();

    System.out.println(totalMatched);

reduce方法,元素组合操作,常用于字符串拼接,数值 sum、min、max、average

import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Optional;

public class StreamBuilders { public static void main(String[] args) { List list = new ArrayList(Arrays.asList(new String[]{ "Amitabh", "Shekhar", "Aman", "Rahul", "Shahrukh", "Salman", "Yana", "Lokesh"}));

    Optional reduced = list.stream().reduce((s1, s2) -> s1 + "#" + s2);

    reduced.ifPresent(System.out::println);

    //打印结果:Amitabh#Shekhar#Aman#Rahul#Shahrukh#Salman#Yana#Lokesh
}

}

Stream短路操作

所谓的短路操作。这意味着如果它满足要求,它将不会继续执行以下操作,类似&&和||操作,

在Stream在中,有类似的anyMatch()和findFirst()方法,

anyMatch(),返回布尔值,只要找到匹配的元素,就停止下一个元素的遍历;

    boolean matched = list.stream().anyMatch((s) -> s.startsWith("A"));

    System.out.println(matched);

    // Output: true

findFirst(),return元素,同样,只返回第一个元素,而不是全部遍历;

    String firstMatchedName = list.stream().filter((s) -> s.startsWith("L")).findFirst().get();

    System.out.println(firstMatchedName);

    // Output: Lokesh

并发parallelStream

Java 7引入了Fork/Join并行计算框架允许我们拆分任务并加速并行处理。编写并行代码通常很困难,而且容易出错。, 但使用 Stream API 不用编写一行多线程代码就可以轻松编写高性能并发程序。

以下示例:

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

public class StreamBuilders { public static void main(String[] args) { List list = new ArrayList(Arrays.asList(new Integer[]{ 1, 2, 3, 4, 5, 6, 7, 8, 9 }));

    // Here creating a parallel stream
    Stream stream = list.parallelStream();
    Integer[] evenNumbersArr = stream.filter(i -> i % 2 == 0).toArray(Integer[]::new);
    System.out.print(Arrays.asList(evenNumbersArr));
}

}

使用Stream与不用Stream对比

这里有一个用途。Stream与不使用Stream示例,用于计算字符的长度。3字符串的数量。

import java.util.Arrays; import java.util.List;

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

  List strings = Arrays.asList("abc", "111", "bc", "efg", "12584","", "1254");

  //使用Java 7, 统计字符长度为3字符串的数量
  long count = 0;
  for(String string: strings){

     if(string.length() == 3){
        count++;
     }
  }
  System.out.println("using java7:Strings of length 3: " + count);

  //使用Java 8的stream, 统计字符长度为3字符串的数量
  count = strings.stream().filter(string -> string.length() == 3).count();
  System.out.println("using java8:Strings of length 3: " + count);

} }

参考资料

http://www.ibm.com/developerworks/cn/java/j-lo-java8streamapi/

http://winterbe.com/posts/2014/07/31/java8-stream-tutorial-examples/

https://www.tutorialspoint.com/java8/java8_streams.htm

http://howtodoinjava.com/core-java/collections/java-8-tutorial-streams-by-examples/

@Author 用同样的风规范农民
@HomePageUrl http://www.cnblogs.com/chenpi/
@Copyright 转载请注明出处,谢谢~

版权声明

所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除

热门