Stream流的作用:
結合了Lambda表達式,簡化集合,數組的操作
Stream流的使用步驟:
1. 先得到一條Stream流(流水線),并把數據放上去
獲取方式 | 方法名 | 說明 |
---|---|---|
單列集合 | default Stream<E> stream() | Collection中的默認方法 |
雙列集合 | 無 | 無法直接使用stream流 |
數組 | public static <T> Stream<T> stream(T[] array) | Arrays工具類中的靜態方法 |
一堆零散數據 | public static<T> Stream<T> of(T... values) | Stream接口中的靜態方法 |
//1.單列集合獲取Stream流ArrayList<String> list = new ArrayList<>();Collections.addAll(list,"a","b","c","d","e","f","g","h");//獲取到一條流水線,并把集合中的數據放到流水線上Stream<String> stream = list.stream();//使用終結方法打印一下流水線上的所有數據stream.forEach(new Consumer<String>() {@Overridepublic void accept(String s) {//s表示流水線上的每一個數據System.out.println(s);}});//forEach方法中的參數類型是Consumer<? super T> ,而這個參數類型點到源碼會發現他是//一個函數式接口,因此也就可以使用lambda表達式簡化上述代碼。list.stream().forEach(s -> System.out.println(s));
//雙列集合 無法直接使用stream流//1.創建雙列集合HashMap<String, Integer> hm = new HashMap<>();//2.添加數據hm.put("aaa",111);hm.put("bbb",222);hm.put("ccc",333);hm.put("ddd",444);//3.第一種獲取stream流hm.keySet().stream().forEach(s -> System.out.println(s));//4.第二種獲取stream流hm.entrySet().stream().forEach(s -> System.out.println(s));
//一堆零散數據 public static<T> Stream<T> of(T... values) Stream接口中的靜態方法
Stream.of(1,2,3,4,5).forEach(s -> System.out.println(s));
Stream.of("a","b","c").forEach(s -> System.out.println(s));
注意:
Stream接口中靜態方法of的細節
方法的形參是一個可變參數,可以傳遞一堆零散的數據,也可以傳遞數組
但是數組必須是引用數據類型的,如果傳遞基本數據類型,是會把整個數組當作一個元素,存放到Stream當中。
2. 利用Stream流中的API進行各種操作
- 中間方法:方法調用完畢之后,還可以調用其他方法
Stream<T> filter (Predicate<?super T>predicate) | 過濾 |
---|---|
Stream<T> limit (long maxSize) | 獲取前幾個元素 |
Stream<T> skip (long n) | 跳過前幾個元素 |
Stream<T> distinct() | 元素去重,依賴(hashCode和equals方法) |
static<T>Stream<T> concat (Stream a,Streamb) | 合并a和b兩個流為一個流 |
Stream<R> map (Function<T,R> mapper) | 轉換流中的數據類型 |
注意一:中間方法,返回新的Stream流,原來的Stream流只能使用一次,建議使用鏈式編程。
注意二:修改Stream流中的數據,不會影響原來集合或者數組中的數據。
- 終結方法:最后一步,調用完之后,不能調用其他方法
名稱 | 說明 |
---|---|
void forEach(Consumer action) | 遍歷 |
long count() | 統計 |
toArray() | 收集流中的數據,放到數組中 |
collect(Collector collector) | 收集流中的數據,放到集合中(List(可以有重復元素) Set(沒有重復元素) Map) |
ArrayList<String> list = new ArrayList<>();Collections.addAll(list,"a","b","c");/*** IntFunction 的泛型:具體類型的數組* apply的形參:流中數據的個數,要跟數組的長度保持一致* apply的返回值:具體類型的數組* 方法體:就是創建數組** toArray方法的參數的作用:負責創建一個指定類型的數組* toArray方法的底層,會依次得到流里面的每一個數據,并把數據放到數組當中* toArray方法的返回值:是一個裝著流里面所有數據的數組**/String[] array = list.stream().toArray(new IntFunction<String[]>() {@Overridepublic String[] apply(int value) {return new String[value];}});System.out.println(Arrays.toString(array));String[] array1 = list.stream().toArray(value -> new String[value]);System.out.println(Arrays.toString(array1));
ArrayList<String> list = new ArrayList<>();Collections.addAll(list,"a-男-11","b-男-34","c-男-24","d-男-22","e-女-13","f-女-51","g-女-15");Map<String, Integer> collect = list.stream().filter(s -> "男".equals(s.split("-")[1]))/*** toMap:參數一表示鍵的生成規則* 參數二表示值的生成規則** 參數一:* Function泛型一:表示流中每一個數據的類型* 泛型二:表示Map集合中鍵的數據類型* 方法apply形參:依次表示流里面的每一個數據* 方法體:生成鍵的代碼* 返回值:已經生成的鍵** 參數二:* Function泛型一:表示流中每一個數據的類型* 泛型二:表示Map集合中值的數據類型* 方法apply形參:依次表示流里面的每一個數據* 方法體:生成值的代碼* 返回值:已經生成的值*/.collect(Collectors.toMap(new Function<String, String>() {@Overridepublic String apply(String s) {return s.split("-")[0];}},new Function<String, Integer>() {@Overridepublic Integer apply(String s) {return Integer.parseInt(s.split("-")[2]);}}));System.out.println(collect);Map<String, Integer> collect1 = list.stream().filter(s -> "男".equals(s.split("-")[1])).collect(Collectors.toMap(s -> s.split("-")[0],s -> Integer.parseInt(s.split("-")[2])));System.out.println(collect1);
注意:
如果我們要收集到Map集合當中,鍵不能重復,否則會報錯。