Java流處理stream使用詳解
基本流
foreach 實現(xiàn)了外部迭代,它是建立于集合的基礎上;
stream 流實現(xiàn)的是內部迭代
中間操作與終端操作
對任意集合使用 stream() 方法來使用流操作來對其進行內部迭代;
中間操作:流水線上的中間操作,他會返回一個 stream
終端操作:一般位于流水線末尾,輸出一個非 stream 類型的值
這是下方代碼的完整運行過程:
- 首先使用 stream 方法使用流來處理集合 names
- 使用過濾器 filter,過濾出字符串中含有字符 a 的字符串
- distinct 進行去重
- toList 將以上所有中間操作過后得到的結果進行匯總,轉換成 list 并輸出
public static void main(String[] args) {
List<String> strings = new ArrayList<>();
strings.add("asd");
strings.add("asd");
strings.add("qwe");
List<String> names = strings.stream()
// 過濾
.filter(d -> {
return d.contains("a");
})
// 去重
.distinct()
// 轉換成列表
.toList();
for (String name : names) System.out.println(name); // 輸出:asd
}一些常見的終端操作
foreach:消費流中所有元素并使用 lambda,該操作返回 void
count:返回流中的元素個數(shù),返回類型為 long
collect:把流處理結果返回成一個集合,譬如 toList 方法
進階流
篩選各異的元素
distinct 進行去重
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 1, 2, 4, 2, 2);
numbers.stream()
.filter(i -> i % 2 == 0)
.distinct()
.forEach(System.out::println);
}
截斷
limit,做多返回前 n 個元素
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 1, 2, 4, 2, 2);
numbers.stream()
.limit(3)
.forEach(System.out::println);
}跳過元素
skip(4) 表示跳過前四個元素,并返回后面所有的元素;
由于代碼都差不多,這里不做過多演示
映射流
map
map 接收一個函數(shù)作為參數(shù),他將對集合中的每個元素應用該函數(shù),并返回該函數(shù)規(guī)定的值;
如下代碼使用 map 獲取了每個 dish 的名稱并返回它,由此生成了由 dishname 構成的列表
public static void main(String[] args) {
List<Dish> dishes = new ArrayList<>();
dishes.add(new Dish("apple", true, 120, Dish.Type.FRUIT));
dishes.add(new Dish("pork", false, 900, Dish.Type.MEAT));
dishes.add(new Dish("fish", false, 400, Dish.Type.FISH));
List<String> dishNames = dishes.stream()
.map(Dish::getName)
.toList();
dishes.forEach(System.out::println);
}flatMap
map 是將每個元素都映射成了一個流;
flatMap 是將每個元素都放如同一個流中!
以下代碼實現(xiàn):提取單詞表中出現(xiàn)的單詞;
Arrays.stream 可以將集合轉換成流的形式;
應當首先應用 map,將元素進行映射后,在使用 flatMap 把這些映射完畢的元素全部裝入一個統(tǒng)一的流里面!
public static void main(String[] args) {
// 創(chuàng)建單詞表
String[] words = {"goodbye", "hello", "night"};
// 將單詞表轉換成流的形式
Stream<String> swords = Arrays.stream(words);
// 首先使用map,將所有字母都一一分割來開
List<String> strings = swords.map(word -> word.split(""))
// 使用扁平map,將提取到的字母裝入一個流中
.flatMap(Arrays::stream)
// 字母去重
.distinct()
// 轉換成列表
.toList();
strings.forEach(System.out::println);
}匹配
anyMatch 能應答:流中是否有至少有一個元素能匹配所給定的謂詞(方法引用)
public static void main(String[] args) {
List<Dish> dishes = Menu.getMenu();
if(dishes.stream().anyMatch(Dish::isVegetarian)){
System.out.println("至少有一個素菜!");
}
}
全匹配與非全匹配
allMatch 方法檢查謂詞能否匹配所有元素;
noneMatch 方法作用與 allMatch 方法完全相反;
Optional
findAny
findAny 方法默認返回一個 Optional<T>
ifPresent 會在值存在的時候執(zhí)行后面的 lambda 函數(shù)
public static void main(String[] args) {
List<Dish> dishes = Menu.getMenu();
dishes.stream()
.filter(Dish::isVegetarian)
.findAny()
.ifPresent(d -> System.out.println(d.getName()));
}
findFirst
顧名思義,找到集合中的第一個元素
歸約
求和
下方展示了三種求和方式:
- 直接使用 arrays 函數(shù)自帶的 sum 方法求和;
- 使用 reduce,參數(shù)一表示初始值,參數(shù)二為對值的操作
- 同樣使用 reduce,但是引入了謂詞!
public static void main(String[] args) {
int[] nums = {1, 2, 3, 4, 5};
int sum = Arrays.stream(nums).sum();
int sum2 = Arrays.stream(nums)
.reduce(0, (a, b) -> a + b);
int sum3 = Arrays.stream(nums)
.reduce(0, Integer::sum);
}歸約相關闡發(fā)
map+reduce 常被作為一種形式來進行并行化;
使用 reduce 進行的迭代被內部抽象化掉了,所以有益于并行的執(zhí)行;
parallelStream 可以方便的進行并行操作,但是也帶來了同步不安全的隱患;
數(shù)值流
使用 mapToInt 返回特化的 IntStream
public static void main(String[] args) {
List<Dish> dishes = Menu.getMenu();
int sum = dishes.stream()
.mapToInt(Dish::getCalories)
.sum();
}boxed
將某個特化流轉換成一般流,可以使用 boxed 方法
IntStream is = dishes.stream().mapToInt(Dish::getCalories); Stream<Integer> sis = is.boxed();
range
針對特化流 IntStream 和 LongStream,他們均有 range 和 rangeClose 方法;
range:遍歷范圍內所有數(shù)字除了右邊界數(shù)字
rangeClose:遍歷包含右邊界的所有范圍數(shù)字
下面代碼展示了獲取 1-100 內所有偶數(shù)的個數(shù)
IntStream evenNumbers = IntStream.rangeClosed(1,100)
.filter(n->n%2==0);
System.out.println(evenNumbers.count());
構建流
創(chuàng)建流的三種方式
Stream.of(xxx) 通過數(shù)值直接構建;
Arrays.stream() 數(shù)組創(chuàng)建;
File.lines() 通過獲取的文件內容創(chuàng)建;
到此這篇關于Java流處理stream使用詳解的文章就介紹到這了,更多相關Java stream內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
jdbc連SQL?server顯示1433端口連接失敗圖文解決方法
這篇文章主要給大家介紹了關于jdbc連SQL?server顯示1433端口連接失敗的圖文解決方法,文中通過圖文介紹的非常詳細,對大家的學習或者工作具有一定的參考借鑒價值,需要的朋友可以參考下2024-06-06
Java并發(fā)volatile可見性的驗證實現(xiàn)
這篇文章主要介紹了Java并發(fā)volatile可見性的驗證實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-05-05

