Stream流呢,以前我也有所瞭解,像一些面試題中也出現過,Java8的新特性,有一塊就是這個Stream操作集合,而且在看一些項目中也使用的比較多。但總感覺自己學的一知半解,所以今天打算系統的過一下,再鞏固鞏固。 ###概念 Stream是JDK8 API中的新成員,它允許以聲明性方式處理集合。 ...
Stream流呢,以前我也有所瞭解,像一些面試題中也出現過,Java8的新特性,有一塊就是這個Stream操作集合,而且在看一些項目中也使用的比較多。但總感覺自己學的一知半解,所以今天打算系統的過一下,再鞏固鞏固。
概念
Stream是JDK8 API中的新成員,它允許以聲明性方式處理集合。
流程
1、把集合轉換為流Stream
2、操作Stream流
Stream流在管道中經過中間操作(intermediate operation)的處理,最後由最終操作(terminal operation)得到前面處理的結果
一些常見的中間操作和中止操作
- 中間操作(過濾、映射、限制...),可以多個
方法名 | 方法作用 | 返回值類型 | 方法類型 |
---|---|---|---|
filter | 過濾 | Stream | 中間操作 |
map | 映射(轉換)接收一個函數作為參數,這個函數會被應用到每個元素上,並將其映射成為一個新的元素 | Stream | 中間操作 |
peek | 窺探 | Stream | 中間操作 |
skip | 跳過前幾個 | Stream | 中間操作 |
limit | 截取前幾個 | Stream | 中間操作 |
distinct | 去重操作(比較的是地址) | Stream | 中間操作 |
sorted | 排序操作 | Stream | 中間操作 |
- 終止操作(最常見的是收集),只可以設置1個
方法名 | 方法作用 | 返回值類型 | 方法類型 |
---|---|---|---|
collect | 收集處理結果 | 泛型 | 終止操作 |
count | 統計個數 | long | 終止操作 |
forEach | 逐一處理 | void | 終止操作 |
reduce | 彙總操作 | Optional<> 該對象有get方法可以獲取返回值 | 終止操作 |
Stream的3個註意事項:
- Stream中間操作方法返回的是新的流
- Stream不調用終結方法,中間的操作不會執行
- Stream只能調用一次終止操作。得到結果後,不能再次使用這個流。
下麵是一些小demo
點擊查看代碼
/**
* 過濾集合中不符合條件的元素
*/
@Test
public void testfilter(){
List<String> stringList = Arrays.asList("abc", "", "bc", "def", "abcd", "", "jkl");
List<String> aList = stringList.stream().filter(str -> str.contains("a")).collect(Collectors.toList());
aList.forEach(System.err::println);
}
/**
*去重
*/
@Test
public void testDistinct(){
List<String> stringList = Arrays.asList("abc", "", "bc", "def", "abcd", "", "jkl","jkl");
List<String> distinctStr = stringList.stream().distinct().collect(Collectors.toList());
distinctStr.forEach(System.out::println);
//--------------------------------
Product prod1 = new Product(1L, 1, new BigDecimal("15.5"), "麵包", "零食");
Product prod2 = new Product(2L, 2, new BigDecimal("20"), "餅干", "零食");
Product prod3 = new Product(2L, 2, new BigDecimal("20"), "餅干", "零食");
ArrayList<Product> proList = Lists.newArrayList(prod1, prod2, prod3);
List<Product> distinctProList = proList.stream().distinct().collect(Collectors.toList());
distinctProList.forEach(System.out::println);
}
/**
* limit(n)獲取流中的前n個元素
*/
@Test
public void testLimit(){
List<String> stringList = Arrays.asList("abc", "", "bc", "def", "abcd", "", "jkl","jkl");
List<String> limitStr = stringList.stream().limit(3).collect(Collectors.toList());
System.out.println(limitStr);
}
/**
* skip(n)
*/
@Test
public void testSkip(){
List<String> stringList = Arrays.asList("abc", "", "bcd", "def", "abcd", "", "jkl","jkl");
List<String> skipStrList = stringList.stream().skip(2).collect(Collectors.toList());
System.out.println(skipStrList);
}
/**
* map() 接收一個函數作為參數,這個函數會被應用到每個元素上,並將其映射成為一個新的元素
*/
@Test
public void testMap(){
List<String> stringList = Arrays.asList("abc", "", "bcd", "def", "abcd", "", "jkl","jkl");
List<String> mapStrList = stringList.stream().map(str -> str.concat("_map")).collect(Collectors.toList());
System.out.println(mapStrList);
}
@Test
public void testSorted(){
List<String> stringList = Arrays.asList("abc", "", "bcd", "def", "abcd", "", "jkl","jkl");
List<String> sortedStrList = stringList.stream().sorted().collect(Collectors.toList());
System.out.println(sortedStrList);
}
/**
* collect():將流轉換為其他形式 list set map
*/
@Test
public void testCollect(){
List<String> stringList = Arrays.asList("abc", "", "bcd", "def", "abcd", "", "jkl","jkl");
Set<String> collectSet = stringList.stream().collect(Collectors.toSet());
System.out.println(collectSet);
}
/**
* 將流中元素反覆結合起來得到一個結果
*/
@Test
public void testReduce(){
List<String> stringList = Arrays.asList("abc", "", "bcd", "def", "abcd", "", "jkl","jkl");
Optional<String> reduce = stringList.stream().reduce((acc, item) -> {return acc + item;});
if (reduce.isPresent()) System.out.println(reduce.get());
}
/**
* 將流中元素反覆結合起來得到一個結果
*/
@Test
public void testCount(){
List<String> stringList = Arrays.asList("abc", "", "bcd", "def", "abcd", "", "jkl","jkl");
long count = stringList.stream().count();
System.out.println(count);
}