java1.8的stream_JDK1.8新特性(一):stream
搜索熱詞
一.什么是stream?
1.概述
Java 8 API添加了一個新的抽象稱為流Stream,可以讓你以一種聲明的方式處理數據。
這種風格將要處理的元素集合看作一種流, 流在管道中傳輸, 并且可以在管道的節點上進行處理, 比如篩選, 排序,聚合等。
元素流在管道中經過中間操作的處理,最后由最終操作得到前面處理的結果。
簡單描述一下大概是這樣:
二. 舉個例子?
現在有一個字符串集合,我們需要過濾掉集合里頭長度小于2的字符串:
public static void main( String[] args ) {
List strings = Arrays.asList("ab","","bc","cd","abcd","jkl");
List stringList = new ArrayList<>();
for (String str : strings){
//如果長度大于2
if (str.length() >= 2){
//將字符串添加至新集合
stringList.add(str);
}
}
strings = stringList;
}
如果使用stream實現一模一樣的效果:
public static void main( String[] args ) {
List strings = Arrays.asList("ab","jkl");
//通過stream操作集合
strings = strings.stream()
//去掉長度小于2的字符串
.filter(s -> s.length() >= 2)
//轉回集合
.collect(Collectors.toList());
}
可見,使用streamAPI可以輕松寫出更高效,更簡潔,可讀性更強的代碼
三. 如何使用stream?
簡單的說,分兩步:生成流,操作流
1. 生成流
Stream 的創建需要指定一個數據源,比如 java.util.Collection的子類,List或者Set, 不支持Map
1.1 Collection接口的stream()或parallelStream()方法
//將Set或List集合直接轉換為stream對象
List personList = new ArrayList<>();
Set set = new HashSet<>();
Stream personStream1 = personList.stream();//生成串行流
Stream personStream2 = set.parallelStream();//生成并行流
1.2 Stream.of(),Arrays.stream,Stream.empty()方法
String[] strArr = {"a","a","a"};
//Stream.empty()
Stream integerStream = Stream.empty();
//Stream.of() (方法內部調用的還是Arrays.stream)
Stream stringStream = Stream.of(strArr);
//Arrays.stream
Stream stringStream2 = Arrays.stream(strArr);
1.3 Stream.concat()方法
//已有的對象
Stream integerStream = Stream.empty();
Stream stringStream = Stream.of(strArr);
Stream stringStream2 = Arrays.stream(strArr);
//合并兩個流
Stream conStream1 = Stream.concat(stringStream,integerStream);
Stream conStream2 = Stream.concat(stringStream,stringStream2);
1.4 靜態的Files.lines(path)
File file = new File("D://test.txt");
Stream lines = Files.lines(file);
2. 操作流
Stream 操作分為中間操作或者最終操作兩種,最終操作返回一特定類型的計算結果,而中間操作返回Stream本身,可以在后頭跟上其他中間操作
//接下來的示例代碼基于此集合
List strings = Arrays.asList("ab","jkl");
2.1 filter(Predicate:將結果為false的元素過濾掉
//去掉長度小于2的字符串
strings = strings.stream()
.filter(s -> s.length() >= 2)
//返回集合
.collect(Collectors.toList());
System.out.println(strings);
//打印strings
[ab,bc,cd,abcd,jkl]
2.2 map(fun):轉換元素的值,可以引用方法或者直接用lambda表達式
strings = strings.stream()
//為每個字符串加上“???”
.map(s -> s += "???")
//返回集合
.collect(Collectors.toList());
System.out.println(strings);
//打印strings
[ab???,???,bc???,cd???,abcd???,jkl???]
2.3 limit(n):保留前n個元素
strings = strings.stream()
//保留前3個
.limit(3)
//返回集合
.collect(Collectors.toList());
System.out.println(strings);
//打印strings
[ab,bc]
2.4 skip(n):跳過前n個元素
strings = strings.stream()
//跳過前2個
.skip(2)
//返回集合
.collect(Collectors.toList());
System.out.println(strings);
//打印strings
[bc,jkl]
2.5 distinct():剔除重復元素
strings = strings.stream()
//過濾重復元素
.distinct()
//返回集合
.collect(Collectors.toList());
System.out.println(strings);
//打印strings(過濾掉了一個空字符串)
[ab,jkl]
2.6 sorted():通過Comparable對元素排序
strings = strings.stream()
//按字符串長度排序
.sorted(
//比較字符串長度
Comparator.comparing(s -> s.length())
)
//返回集合
.collect(Collectors.toList());
System.out.println(strings);
//打印strings(過濾掉了一個空字符串)
[,ab,jkl,abcd]
2.7 peek(fun):流不變,但會把每個元素傳入fun執行,可以用作調試
strings = strings.stream()
//為字符串增加“???”
.peek(s -> s += "???")
//返回集合
.collect(Collectors.toList());
System.out.println(strings);
//打印strings,和map對比,實際并沒有改變集合
[ab,jkl]
2.8 flatMap(fun):若元素是流,將流攤平為正常元素,再進行元素轉換
//將具有多重嵌套結構的集合扁平化
//獲取一個兩重集合
List strings = Arrays.asList("ab","jkl");
List strings2 = Arrays.asList("asd","bzxasdc","cddsdsd","adsdsg","jvcbl");
List> lists = new ArrayList<>();
lists.add(strings);
lists.add(strings2);
//獲取將兩重集合壓成一層
List stringList = lists.stream()
//將兩重集合的子元素,即集合strings和strings2轉成流再平攤
.flatMap(Collection::stream)
//返回集合
.collect(Collectors.toList());
System.out.println(stringList);
//打印stringList
[ab,asd,bzxasdc,cddsdsd,adsdsg,jvcbl]
2.9 anyMatch(fun),allMatch(fun):判斷流中的元素是否匹配 【最終操作】
//allMatch
Boolean isAllMatch = strings.stream()
//判斷元素中是否有匹配“ab”的字符串,返回true或fals
//判斷元素中的字符串是否都與“ab”匹配,返回true或fals
.allMatch(str -> str.equals("ab"));
System.out.println(isMatch);
//anyMatch
Boolean isAnyMatch = strings.stream()
//判斷元素中是否有匹配“ab”的字符串,返回true或fals
.anyMatch(str -> str.equals("ab"));
System.out.println("isAnyMatch:" + isAnyMatch);
System.out.println("isAllMatch:" + isAllMatch);
//打印結果
isAnyMatch:true
isAllMatch:false
2.10 forEach(fun): 迭代流中的每個數據 【最終操作】
strings.stream()
//遍歷每一個元素
.forEach(s -> System.out.print(s + "; "));
2.11 collect():返回結果集 【最終操作】
strings = strings.stream()
//返回集合
.collect(Collectors.toList());
四. 使用IntSummaryStatistics類處理數據
1. IntSummaryStatistics類
IntSummaryStatistics類,在 java8中配合Stream使用,是用于收集統計信息(例如計數,最小值,最大值,總和和*平均值)的狀態對象。
這個類長這樣:
public class IntSummaryStatistics implements IntConsumer {
private long count;
private long sum;
private int min = Integer.MAX_VALUE;
private int max = Integer.MIN_VALUE;
public IntSummaryStatistics() { }
@Override
public void accept(int value) {
++count;
sum += value;
min = Math.min(min,value);
max = Math.max(max,value);
}
public void combine(IntSummaryStatistics other) {
count += other.count;
sum += other.sum;
min = Math.min(min,other.min);
max = Math.max(max,other.max);
}
public final long getCount() {
return count;
}
public final long getSum() {
return sum;
}
public final int getMin() {
return min;
}
public final int getMax() {
return max;
}
public final double getAverage() {
return getCount() > 0 ? (double) getSum() / getCount() : 0.0d;
}
@Override
public String toString() {
return String.format(
"%s{count=%d,sum=%d,min=%d,average=%f,max=%d}",this.getClass().getSimpleName(),getCount(),getSum(),getMin(),getAverage(),getMax());
}
}
2.使用
這個類的理解起來很簡單,內部有這幾個方法:
2.1 獲取總條數:getCount(),
2.2 獲取和:getSum(),
2.3 獲取最小值:getMin(),
2.4 獲取最大值:getMax(),
2.5 獲取平均值:getAverage()
示例如下:
public static void main( String[] args ) {
List integerList = Arrays.asList(3,4,22,31,75,32,54);
IntSummaryStatistics sta = integerList
.stream()
//將元素映射為對應的數據類型(int,double,long)
.mapToInt(i -> i)
//轉換為summaryStatistics類
.summaryStatistics();
System.out.println("總共有 : "+ sta.getCount());
System.out.println("列表中最大的數 : " + sta.getMax());
System.out.println("列表中最小的數 : " + sta.getMin());
System.out.println("所有數之和 : " + sta.getSum());
System.out.println("平均數 : " + sta.getAverage());
}
//打印結果
總共有 : 7
列表中最大的數 : 75
列表中最小的數 : 3
所有數之和 : 221
平均數 : 31.571428571428573
相關文章
總結
如果覺得編程之家網站內容還不錯,歡迎將編程之家網站推薦給程序員好友。
本圖文內容來源于網友網絡收集整理提供,作為學習參考使用,版權屬于原作者。
如您喜歡交流學習經驗,點擊鏈接加入交流1群:1065694478(已滿)交流2群:163560250
總結
以上是生活随笔為你收集整理的java1.8的stream_JDK1.8新特性(一):stream的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java中vi是什么意思_java中的p
- 下一篇: 怎么使用iphone苹果手机来练习弹钢琴