作為一名java開發工程師,數組和集合在我的代碼中随處可見。我經常使用集合或數組來處理資料,如過濾和對象轉換。
我相信大家對數組的資料處理已經非常熟悉了。
On Java 中文版 進階卷 ¥66 購買
但是當資料處理比較複雜的時候,我們的代碼就會非常長,難以了解。
這個時候,我通常會把代碼拆成方法,并給出有意義的方法名稱,這樣可以解決一部分問題。然而,在java8之後,官方有了一個更有效、更友善的解決方案:Stream API。
Stream是Java8中處理集合的關鍵抽象。它可以指定你要對集合進行的操作,并且可以進行非常複雜的操作,如搜尋、過濾和映射資料。
使用Stream API對集合資料進行操作,類似于使用SQL進行資料庫查詢。
也可以使用Stream API來執行并行操作。簡而言之,Stream API提供了一種高效且易于使用的資料處理方式。
Stream具有以下特點:
- 它不是一個資料結構,不儲存資料。
- 懶惰評估,在流的中間處理過程中,隻記錄操作,不立即執行,直到執行終止操作才會進行實際計算。
今天我将分享一些工作中常用的、非常有用的API。
清單到地圖
在我們的工作中,經常會遇到清單或數組被轉換為地圖的場景。Collectors.toMap可以将List轉換成Map。
代碼如下:
public class ListToMap {
public static void main(String[] args) {
List<User> users = new ArrayList<>();
users.add(new User(1, "Bob", 10));
users.add(new User(2, "David", 22));
users.add(new User(3, "Lance", 28));
/**
* list to map
* (k1, k2) ->k1 indicates that if there is a duplicate key, the first key is retained and the second key is discarded
*/
Map<String, User> userMap = users.stream().collect(Collectors.toMap(User::getUsername, user -> user, (k1, k2) -> k1));
userMap.values().forEach(user->System.out.println(user.getUsername()));
}
}
同樣,還有Collectors.toList(),Collectors.toSet(),這意味着将相應的流轉換為一個List或Set。
使用groupingBy進行分組
分組在執行聚合資料操作時經常使用,比如按國籍對使用者進行分組。說到分組,相信大家都會想到SQL的group by。在Java8之前,我們可能需要這樣做:
List<User> users = Arrays.asList(new User(1, "Bob", 10,"America"),new User(2, "Daivd", 22,"America"),new User(3, "Lance", 28,"England"));
Map<String, List<User>> result = new HashMap<>();
for (User user : users) {
String country = user.getCountry();
List<User> userList = result.get(country);
if (userList == null) {
userList = new ArrayList<>();
result.put(country, userList);
}
userList.add(user);
}
如果你使用groupingBy,隻需要一行代碼就可以了:
Map<String, List<User>> result=users.stream.collect(Collectors.groupingBy(User::getCountry));
使用限制和跳過的記憶體分頁
有時我們在記憶體中聚合資料後,資料量可能太大,無法一次性将資料傳回到前端。這個時候,就需要分頁。Stream api提供了limit和skip來完美支援它。
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9);
List<Integer> pageableList=list.stream.skip(3).limit(5).collect(Collectors.toList());
使用filter()來過濾元素
從集合中過濾掉不符合标準的元素。
//Get all students older than 18
List<Student> studentNames = students.stream().filter(student->student.getAge()>18).collect(Collectors.toList());
使用 sorted+Comparator 進行排序
在集合操作中,排序絕對是一個高頻的操作。雖然有現成的集合工具進行排序,但Stream api整合了這一功能,形成了自己的功能生态,進一步提高了api的便利性。
List<User> users = Arrays.asList(new User(1, "Bob", 10,"America"),
new User(2, "Daivd", 22,"America"),new User(3, "Lance", 28,"England"));
List<User> sortedUsers = users.stream().sorted(Comparator.comparing(User::getAge))
.collect(Collectors.toList());
使用reduce進行聚合評估
Stream api也有一個非常有用的方法reduce()。使用reduce可以聚合集合中的所有元素,得到一個單一的值。最典型的情況是數組的總和。
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9);
Optional<Integer> sum=list.stream().reduce((a,b)->a+b);
當然,你也可以使用reduce來執行其他的聚合操作,比如尋找一個數組的平均值。
使用map來轉換類型
map操作是對流中的元素進行重新處理,形成一個新的流。這在開發中很有用,例如,我有一個使用者的集合,但我隻需要使用使用者的名字和年齡,使用map方法就可以做到這點。
List<User> users = Arrays.asList(new User(1, "Bob", 10,"America"),new User(2, "Daivd", 22,"America"),new User(3, "Lance", 28,"England"));
List<UserVo> userVoList = users.stream().map(user->{
UserVo userVo = new UserVo();
userVo.setUsername(user.getUsername());
userVo.setAge(user.getAge());
return userVo;
}).collect(Collectors.toList());
flatMap
flatMap操作可以将同一類型的多個流合并為一個流。
List<User> users = Arrays.asList(new User(1, "Bob", 10,"America"),new User(2, "Daivd", 22,"America"),new User(3, "Lance", 28,"England"));
List<User> userList = Arrays.asList(new User(4,"James",23,"America"));
List<List<User>> list = Arrays.asList(users,userList);
List<User> result = list.stream().flatMap(s->s.stream()).collect(Collectors.toList());
最後
流API以聲明的方式處理集合資料,可以極大地提高Java程式員的工作效率,使我們能夠寫出高效、幹淨、簡潔的代碼。
我希望每個人都能掌握Stream Api,寫出優雅的代碼。謝謝你的閱讀!
On Java 中文版 進階卷 ¥66 購買