Effective Java~46. 优先选择Stream 中无副作用的函数
純函數(shù)(pure function)的結(jié)果僅取決于其輸入:它不依賴于任何可變狀態(tài),也不更新任何狀態(tài)。
壞味道
// Uses the streams API but not the paradigm--Don't do this! Map<String, Long> freq = new HashMap<>(); try (Stream<String> words = new Scanner(file).tokens()) {words.forEach(word -> {freq.merge(word.toLowerCase(), 1L, Long::sum);}); }forEach 操作應(yīng)僅用于報(bào)告流計(jì)算的結(jié)果,而不是用于執(zhí)行計(jì)算
// Proper use of streams to initialize a frequency table Map<String, Long> freq; try (Stream<String> words = new Scanner(file).tokens()) {freq = words.collect(groupingBy(String::toLowerCase, counting())); }Collectors有三個這樣的收集器: toList() 、toSet() 和toCollection(collectionFactory) 。它們分別返回集合、列表和程序員指定的集合類型
// Pipeline to get a top-ten list of words from a frequency table List<String> topTen = freq.keySet().stream().sorted(comparing(freq::get).reversed()).limit(10).collect(toList());????????toMap(keyMapper、valueMapper)最簡單的映射收集器?,它接受兩個函數(shù),一個將流元素映射到鍵,另一個映射到值
// Using a toMap collector to make a map from string to enum private static final Map<String, Operation> stringToEnum =Stream.of(values()).collect(toMap(Object::toString, e -> e));????????如果流中的每個元素都映射到唯一鍵,則這種簡單的 toMap 形式是完美的。 如果多個流元素映射到同一個鍵,則管道將以 IllegalStateException 終止。
????????toMap 的三個參數(shù)形式對于從鍵到與該鍵關(guān)聯(lián)的選定元素的映射也很有用。例如,假設(shè)我們有一系列不同藝術(shù)家(artists)的唱片集(albums),我們想要一張從唱片藝術(shù)家到最暢銷專輯的 map。這個收集器將完成這項(xiàng)工作。
public class Apple implements Serializable {/*** 顏色.*/private String color;/*** 總量.*/private Integer weight;//get/set... } final Map<String, Apple> singleMap = list.stream().collect(Collectors.toMap(Apple::getColor, it -> it, BinaryOperator.maxBy(Comparator.comparing(Apple::getWeight))));????????請注意,比較器使用靜態(tài)工廠方法 maxBy ,它是從 BinaryOperator 靜態(tài)導(dǎo)入的。 此方法將 Comparator<T>轉(zhuǎn)換為 BinaryOperator<T> ,用于計(jì)算指定比較器隱含的最大值。
????????toMap 的三個參數(shù)形式的另一個用途是產(chǎn)生一個收集器,當(dāng)發(fā)生沖突時(shí)強(qiáng)制執(zhí)行 last-write-wins 策略。 對于許多流,結(jié)果是不確定的,但如果映射函數(shù)可能與鍵關(guān)聯(lián)的所有值都相同,或者它們都是可接受的,則此收集器的行為可能正是您想要的:
// Collector to impose last-write-wins policy final Map<String, Apple> singleMap = list.stream().collect(Collectors.toMap(Apple::getColor, it -> it, (oldVal, newVal) -> newVal));????????toMap 的第三個也是最后一個版本采用第四個參數(shù),它是一個 map 工廠,用于指定特定的 map 實(shí)現(xiàn),例如EnumMap 或 TreeMap 。
????????groupingBy 方法,該方法返回收集器以生成基于分類器函數(shù)(classifier function) 將元素分組到類別中的 map。 分類器函數(shù)接受一個元素并返回它所屬的類別。 此類別來用作元素的 map 的鍵。
Map<String, Long> freq = words.collect(groupingBy(String::toLowerCase, counting()));????????join ,它僅對 CharSequence 實(shí)例(如字符串)的流進(jìn)行操作。 在其無參數(shù)形式中,它返回一個簡單地連接元素的收集器。?
List<String> items =Arrays.asList("apple", "apple", "banana"); final String str = items.stream().collect(Collectors.joining(",", "[", "]"));//[apple,apple,banana]總結(jié)
以上是生活随笔為你收集整理的Effective Java~46. 优先选择Stream 中无副作用的函数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Decompose Conditiona
- 下一篇: 所谓高情商就是会说话--总结