Stream流的中間方法詳解
Stream流的中間方法指那些返回新Stream的操作,允許鏈式調用。這些方法通常用于數據過濾、映射、排序等操作,不會觸發最終計算。
filter方法
filter用于篩選滿足條件的元素,接受一個Predicate函數式接口參數。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> evenNumbers = numbers.stream().filter(n -> n % 2 == 0).collect(Collectors.toList());
// 輸出: [2,4]
map方法
map用于元素轉換,接受Function接口參數,將元素映射為另一種形式。
List<String> names = Arrays.asList("Alice", "Bob");
List<Integer> nameLengths = names.stream().map(String::length).collect(Collectors.toList());
// 輸出: [5,3]
flatMap方法
flatMap用于將嵌套結構扁平化,每個元素轉換為新的Stream后合并。
List<List<Integer>> nestedNumbers = Arrays.asList(Arrays.asList(1,2),Arrays.asList(3,4));
List<Integer> flattened = nestedNumbers.stream().flatMap(List::stream).collect(Collectors.toList());
// 輸出: [1,2,3,4]
distinct方法
distinct去除重復元素,依賴元素的equals方法。
List<Integer> duplicates = Arrays.asList(1,2,2,3);
List<Integer> unique = duplicates.stream().distinct().collect(Collectors.toList());
// 輸出: [1,2,3]
sorted方法
sorted用于排序,可自然排序或提供Comparator。
List<String> unsorted = Arrays.asList("Bob", "Alice");
List<String> sorted = unsorted.stream().sorted().collect(Collectors.toList());
// 輸出: ["Alice","Bob"]List<Integer> numbers = Arrays.asList(3,1,2);
List<Integer> customSorted = numbers.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
// 輸出: [3,2,1]
limit方法
limit截取前N個元素。
List<Integer> numbers = Arrays.asList(1,2,3,4,5);
List<Integer> firstThree = numbers.stream().limit(3).collect(Collectors.toList());
// 輸出: [1,2,3]
skip方法
skip跳過前N個元素。
List<Integer> numbers = Arrays.asList(1,2,3,4,5);
List<Integer> afterTwo = numbers.stream().skip(2).collect(Collectors.toList());
// 輸出: [3,4,5]
peek方法
peek用于調試,允許查看流經的元素但不修改。
List<String> names = Arrays.asList("Alice", "Bob");
List<String> result = names.stream().peek(System.out::println).map(String::toUpperCase).collect(Collectors.toList());
// 輸出調試信息: Alice Bob
// 最終結果: ["ALICE","BOB"]
實例一:
public class StreamDemo6 {public static void main(String[] args) {/*filter 過濾limit 獲取前幾個元素skip 跳過前幾個元素注意1:中間方法,返回新的Stream流,原來的Stream流只能使用一次,建議使用鏈式編程注意2:修改Stream流中的數據,不會影響原來集合或者數組中的數據*/ArrayList<String> list = new ArrayList<>();Collections.addAll(list, "張無忌", "周芷若", "趙敏", "張強", "張三豐", "張翠山", "張良", "王二麻子", "謝廣坤");//filter 過濾 把張開頭的留下,其余數據過濾不要/*list.stream().filter(new Predicate<String>() {@Overridepublic boolean test(String s) {//如果返回值為true,表示當前數據留下//如果返回值為false,表示當前數據舍棄不要return s.startsWith("張");}}).forEach(s -> System.out.println(s));list.stream().filter(s -> s.startsWith("張")).filter(s -> s.length() == 3).forEach(s -> System.out.println(s));System.out.println("====================================");System.out.println(list);*//* limit 獲取前幾個元素skip 跳過前幾個元素*///"張無忌", "周芷若", "趙敏", "張強", "張三豐", "張翠山", "張良", "王二麻子", "謝廣坤"//list.stream().limit(3).forEach(s -> System.out.println(s));//list.stream().skip(4) .forEach(s -> System.out.println(s));//課堂練習://"張強", "張三豐", "張翠山"//第一種思路://先獲取前面6個元素:"張無忌", "周芷若", "趙敏", "張強", "張三豐", "張翠山",//然后跳過前面3個元素//list.stream().limit(6).skip(3).forEach(s -> System.out.println(s));//第二種思路://先跳過3個元素:"張強", "張三豐", "張翠山", "張良", "王二麻子", "謝廣坤"//然后再獲取前面3個元素:"張強", "張三豐", "張翠山"//list.stream().skip(3).limit(3).forEach(s -> System.out.println(s));}
}
實例二:
public class StreamDemo7 {public static void main(String[] args) {/*distinct 元素去重,依賴(hashCode和equals方法)concat 合并a和b兩個流為一個流注意1:中間方法,返回新的Stream流,原來的Stream流只能使用一次,建議使用鏈式編程注意2:修改Stream流中的數據,不會影響原來集合或者數組中的數據*/ArrayList<String> list1 = new ArrayList<>();Collections.addAll(list1, "張無忌","張無忌","張無忌", "張強", "張三豐", "張翠山", "張良", "王二麻子", "謝廣坤");ArrayList<String> list2 = new ArrayList<>();Collections.addAll(list2, "周芷若", "趙敏");// distinct 元素去重,依賴(hashCode和equals方法)//list1.stream().distinct().forEach(s -> System.out.println(s));Stream.concat(list1.stream(),list2.stream()).forEach(s -> System.out.println(s));}
}
實例三:
public class StreamDemo8 {public static void main(String[] args) {/*map 轉換流中的數據類型注意1:中間方法,返回新的Stream流,原來的Stream流只能使用一次,建議使用鏈式編程注意2:修改Stream流中的數據,不會影響原來集合或者數組中的數據*/ArrayList<String> list = new ArrayList<>();Collections.addAll(list, "張無忌-15", "周芷若-14", "趙敏-13", "張強-20", "張三豐-100", "張翠山-40", "張良-35", "王二麻子-37", "謝廣坤-41");//需求:只獲取里面的年齡并進行打印//String->int//第一個類型:流中原本的數據類型//第二個類型:要轉成之后的類型//apply的形參s:依次表示流里面的每一個數據//返回值:表示轉換之后的數據//當map方法執行完畢之后,流上的數據就變成了整數//所以在下面forEach當中,s依次表示流里面的每一個數據,這個數據現在就是整數了list.stream().map(new Function<String, Integer>() {@Overridepublic Integer apply(String s) {String[] arr = s.split("-");String ageString = arr[1];int age = Integer.parseInt(ageString);return age;}}).forEach(s-> System.out.println(s));System.out.println("------------------------");list.stream().map(s-> Integer.parseInt(s.split("-")[1])).forEach(s-> System.out.println(s));}
}
注意:中間操作具有延遲特性,只有遇到終端操作時才會執行。多個中間操作可以組合形成處理流水線。