使用 Java Streams 的 12 種常見方法
來源:Dev.to Java Streams API 首次出現在 Java 8 中。其目的是提供一種更緊湊的方式來對物件集合執行常見操作。此外,Java Streams API 可用於實作複雜的演算法。在本文中,我們將討論 Java Streams 的常見用例。 首先,讓我們澄清一些基礎知識:-
Stream() - 從集合中建立一個流。
-
collect() - 將流收集到物件中。物件可以是集合、基元或自訂類別。
-
Collectors是一個提供(許多)靜態方法來收集流的類別。
1. 過濾
-
用於根據條件從集合中刪除值。
-
若要根據條件過濾集合元素,請使用filter()方法。僅儲存符合的元素。
List<Integer> evenNumbers = originalList.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
2. 預處理
-
當集合中的每個值都需要就地更改時很有用。
-
map()方法用於將函數應用於集合的每個元素並傳回計算值的新集合。
List<Integer> squares = originalList.stream()
.map(n -> n * n)
.collect(Collectors.toList());
3. 轉換
-
當我們想要將一個集合轉換為另一個集合時很有用。
-
有多種方法可以實現這一目標。
範例 1:從清單建立地圖。
將字串列表轉換為字串和長度的映射。Map<String, Integer> wordLengths = words.stream()
.collect(Collectors.toMap(
word -> word,
word -> word.length()));
範例 2. 將清單轉換為集合。
這是刪除重複項的常見用例。此外,如果我們想要將元素放回清單中,我們可以使用兩次stream()和collect()方法。例如,讓我們將字串清單轉換為唯一字串清單:// if we want to collect to a set
Set<String> uniqueWords = words.stream()
.collect(Collectors.toSet());
// OR
// if we want to start and end as a list
List<String> uniqueWords = words.stream()
.collect(Collectors.toSet()).stream().collect(Collectors.toList());
範例 3. 將產品清單轉換為其名稱清單。(展平 - 對齊)
List<String> productNames = products.stream()
.map(product -> product.getName())
.collect(Collectors.toList());
4. 減少
-
將 Collection 減少為單一值。
-
reduce()方法用於將函數應用於集合的每個元素並傳回單一值。
int sum = numbers.stream()
.reduce(0, (a, b) -> a + b);
5. 分組
-
根據給定條件對集合的元素進行分組。
-
若要依條件將 Collection 元素分組,請使用Collectors.groupingBy()方法。
Map<String, List<Product>> productsByCategory = products.stream()
.collect(Collectors.groupingBy(product -> product.getCategory()));
6. 尋找
-
搜尋與條件相符的第一個或任何 Collection 元素。
-
findFirst()和findAny()方法用於搜尋。
Optional<String> firstLongWord = words.stream()
.filter(word -> word.length() > 5)
.findFirst();
// Note that findFirst() and findAny() methods return Optional<T> objects.
7. 排序
-
將集合的元素進行排序。
-
Sorted()方法用於排序。
List<Integer> topK = numbers.stream()
.sorted()
.limit(k)
.collect(Collectors.toList());
8. 分區
-
根據給定條件分隔集合的元素。
-
Collectors.partitioningBy()方法用來分隔元素。
Map<Boolean, List<Student>> passingFailing = students
.stream()
.collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));
9. 計數
-
計算符合條件的元素數量。
-
count()方法用於計算符合條件的元素數量。
long count = words.stream()
.filter(word -> word.length() > 5)
.count();
10. 範圍
-
建立一系列值。
-
若要建立值範圍,請使用range()方法。
int[] numbers = IntStream.range(0, 10).toArray();
11. 匹配
-
將集合的元素與謂詞(條件)配對。
-
諸如anyMatch()、allMatch()和noneMatch()之類的方法用於將集合元素與謂詞進行匹配並傳回布林值。
// true when all elements match the predicate
boolean allMatch = products.stream()
.allMatch(product -> product.getPrice() > 10);
// true when any element matches the predicate
boolean anyMatch = products.stream()
.anyMatch(product -> product.getPrice() > 10);
// true when no elements match the predicate
boolean noneMatch = products.stream()
.noneMatch(product -> product.getPrice() > 10);
12. 加入
-
將集合的元素連接成字串。
-
若要將集合元素連接到字串中,請使用Collectors.joining()方法。
String joinedWords = words.stream()
.collect(Collectors.joining(" "));
對於一般場景來說就是這樣。您也可以自行探索其他不太常見的場景:
- 並行流;
- 統計數據;
- 客製化收藏家。
線程的好處
-
更緊湊的程式碼 - 減少處理集合所需的程式碼量。
-
更少的中間變數。介入變數可能會導致錯誤發生。越少,就越容易避免意外的錯誤。
-
直觀的代碼。一些開發人員不同意線程比其他方法更直觀。然而,一旦我們習慣了它們,它們就會變得比其他方法直觀得多。
如何在 Java 中評估物件的記憶體分配
來源:DZone 本文展示了在 Java 中評估物件記憶體分配的三種最著名的方法。使用 Profiler 進行記憶體評估
估計某些物件的記憶體最簡單的方法是使用分析器(例如Visual VM)直接查看 JVM 記憶體。 這種方法的問題是您需要連接到正在運行的 JVM,由於安全原因,這在生產環境中可能無法實現。使用儀器進行記憶評估
估計給定物件分配的記憶體的另一種方法是使用 Instruments。簡單來說,我們需要建立一個類別並將其編譯成 JAR。建立 JAR 後,我們必須與該 JAR 一起執行 JVM。您可以在此處了解有關此方法的更多資訊。這裡的缺點是需要將特定的 jar 檔案添加到 JVM,由於安全或相關問題,這可能不適合生產。使用 JOL 庫評估內存
作為另一種選擇,我們可以使用JOL Library。這是一個非常強大的函式庫,可以提供物件權重和物件實例分配的記憶體的詳細估計。要使用該庫,我們需要新增依賴項:<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.16</version>
</dependency>
之後我們可以像這樣使用它:
out.println(GraphLayout.parseInstance(myObject).totalSize() / 1024000d + " MB")
Twitter 檔案中的 ObjectSizeCalculator
Twitter 的公共GitHub儲存庫有一個名為 ObjectSizeCalculator 的工具類,可以估計給定物件實例分配的記憶體。使用時不需要太多記憶體或時間。即使對於大型物體,評估過程也需要幾秒鐘。使用這個類別非常簡單:ObjectSizeCalculator.getObjectSize(address)
我推薦這種方法,但請記住,它僅由 Java Hotspot、OpenJDK 和 TwitterJDK 支援。
GO TO FULL VERSION