首先要說的是,不要被它的名稱騙了,這裡的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<String> 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有兩種類型的操作:Intermediate操作和Terminal操作。
Stream可以進行多次的Intermediate操作,如前面開頭的那個例子,其中filter、map、sorted都是Intermediate操作,注意該操作是惰性化的,當調用到該方法的時候,並沒有真正開始Stream的遍歷。
一個Stream只有一個Terminal操作,如前面開頭的那個例子,其中forEach就是Terminal操作,Terminal操作是Stream的最後一個操作,這時候才會開始Stream的遍歷。
使用Stream.of
import java.util.stream.Stream;
public class StreamBuilders
{
public static void main(String[] args)
{
Stream<Integer> 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<Integer> 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<Integer> list =
new ArrayList<Integer>(Arrays.asList(new Integer[]{ 1, 2, 3, 4, 5, 6, 7, 8, 9 }));
Stream<Integer> 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<Integer> stream = Stream.generate(() -> {
try
{
TimeUnit.SECONDS.sleep(1);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
return i++;
});
stream.forEach(p -> System.out.println(p));
}
}
其它還有很多,這裡暫不一一列出。
使用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<Integer> list =
new ArrayList<Integer>(Arrays.asList(new Integer[]{ 1, 2, 3, 4, 5, 6, 7, 8, 9 }));
Stream<Integer> stream = list.stream();
List<Integer> 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<Integer> list =
new ArrayList<Integer>(Arrays.asList(new Integer[]{ 1, 2, 3, 4, 5, 6, 7, 8, 9 }));
Stream<Integer> stream = list.stream();
Integer[] evenNumbersArr = stream.filter(i -> i % 2 == 0).toArray(Integer[]::new);
System.out.print(Arrays.asList(evenNumbersArr));
}
}
其它轉為set,map的類似,不一一列出。
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<String> list = new ArrayList<String>(Arrays.asList(new String[]{
"Amitabh", "Shekhar", "Aman", "Rahul",
"Shahrukh", "Salman", "Yana", "Lokesh"}));
Stream<String> 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<String> list = new ArrayList<String>(Arrays.asList(new String[]{
"Amitabh", "Shekhar", "Aman", "Rahul",
"Shahrukh", "Salman", "Yana", "Lokesh"}));
Stream<String> stream = list.stream();
stream.filter((s) -> s.startsWith("A")).map(String::toUpperCase).forEach(System.out::println);
}
}
sorted方法,排序,可以傳入自定義排序接口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<String> list = new ArrayList<String>(Arrays.asList(new String[]{
"Amitabh", "Shekhar", "Aman", "Rahul",
"Shahrukh", "Salman", "Yana", "Lokesh"}));
Stream<String> 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<String> 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<String> list = new ArrayList<String>(Arrays.asList(new String[]{
"Amitabh", "Shekhar", "Aman", "Rahul",
"Shahrukh", "Salman", "Yana", "Lokesh"}));
Optional<String> reduced = list.stream().reduce((s1, s2) -> s1 + "#" + s2);
reduced.ifPresent(System.out::println);
//打印結果:Amitabh#Shekhar#Aman#Rahul#Shahrukh#Salman#Yana#Lokesh
}
}
所謂的短路操作。指的是如果符合要求的話,就不繼續執行接下來的操作,類似於&&和||操作,
在Stream中,類似的有anyMatch()和findFirst()方法,
anyMatch(),返回布爾值,只要找到一個匹配的元素,就停止接下來的元素遍歷;
boolean matched = list.stream().anyMatch((s) -> s.startsWith("A"));
System.out.println(matched);
// Output: true
findFirst(),返回元素,同樣,只返回第一個元素,不會全部遍歷;
String firstMatchedName = list.stream().filter((s) -> s.startsWith("L")).findFirst().get();
System.out.println(firstMatchedName);
// Output: Lokesh
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<Integer> list =
new ArrayList<Integer>(Arrays.asList(new Integer[]{ 1, 2, 3, 4, 5, 6, 7, 8, 9 }));
// Here creating a parallel stream
Stream<Integer> stream = list.parallelStream();
Integer[] evenNumbersArr = stream.filter(i -> i % 2 == 0).toArray(Integer[]::new);
System.out.print(Arrays.asList(evenNumbersArr));
}
}
下面給出一個使用Stream與不使用Stream示例,用於統計字符長度為3的字符串個數。
import java.util.Arrays;
import java.util.List;
public class Java8Tester {
public static void main(String args[]){
List<String> 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/