<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div dir="ltr" class="">Dear all,<div class=""><br class=""></div><div class="">I just stumbled about some frequent uses of collections as filters and mapping functions, and I am wondering whether it's possible to enhance the core collection interfaces <font face="monospace" class="">Map</font>, <font face="monospace" class="">List</font>, and <font face="monospace" class="">Set</font>:</div><div class=""><br class=""></div><div class="">(please forgive lousy syntax hereinafter)</div><div class=""><br class=""></div><div class=""><font face="monospace" class="">interface Map<K, V> extends Function<K, V> {</font></div><div class=""><font face="monospace" class="">    default V apply(K k) {return get(k);}</font></div><div class=""><font face="monospace" class="">}</font></div><div class=""><font face="monospace" class=""><br class=""></font></div><div class=""><font face="monospace" class="">interface List<T> extends IntFunction<T> {</font></div><div class=""><font face="monospace" class="">   default T apply(int index) { return get(I);}</font></div><div class=""><font face="monospace" class="">}</font></div><div class=""><font face="monospace" class=""><br class=""></font></div><div class=""><font face="monospace" class="">interface Set<T> extends Predicate<T> {</font></div><div class=""><font face="monospace" class="">   default boolean test(T t) {return contains(t);}</font></div><div class=""><font face="monospace" class="">}</font></div><div class=""><br class=""></div><div class="">The cost of extending existing interfaces in widespread use may be prohibitive, plus you may find the value proposition not very convincing.</div><div class=""><br class=""></div><div class="">The interpretation of a Map as a Function feels very natural, although the use of the given map in a stream is also straightforward:</div><div class=""><br class=""></div><div class=""><font face="monospace" class="">Stream.of(1, 2).map(Map.of(1, "One", 2, "Two")::get).toList(); // ["One", "Two"]</font></div><div class=""><br class=""></div><div class="">Assigning the map to a function variable is a little more demanding:</div><div class=""><br class=""></div><div class=""><font face="monospace" class="">// var m = Map.of(...)::get; compiler error</font></div><div class=""><font face="monospace" class="">Function<Integer, String> m = Map.of(1, "One")::get; // WORKS</font></div><div class=""><br class=""></div><div class="">Since we enjoy the pleasures of local variable type inference, this is a little awkward.</div><div class=""><br class=""></div><div class=""><div class="">If a map were a function, then we might write instead:</div><div class=""><br class=""></div><div class=""><font face="monospace" class="">var m = Map.of(1, "One", 2, "Two");</font></div><div class=""><div class=""><font face="monospace" class="">Stream.of(1, 2).map(m).toList(); // ["One", "Two"]</font></div><div class=""></div></div></div><div class=""><br class=""></div><div class="">The interpretation of a list as a function of an index may seem a little more far-fetched:</div><div class=""><br class=""></div><div class=""><font face="monospace" class="">var l = List.of("One", "Two", "Three");</font></div><div class=""><font face="monospace" class="">IntStream.range(0, l.size()).filter(i -> i%2==0).mapToObj(l::get).toList(); // ["One", "Three"];</font></div><div class=""><br class=""></div><div class="">The test for inclusion in a set is a common operation and is therefore a frequent candidate for filters in stream operations.</div><div class=""><br class=""></div><div class=""><font face="monospace" class="">var primes = Set.of(2, 3, 5, 7);</font></div><div class=""><font face="monospace" class="">IntStream.range(5, 10).filter(primes::contains).toArray(); // [5, 7]</font></div><div class=""><br class=""></div><div class="">With Set implementing Predicate and List implementing IntFunction we may write:</div><div class=""><br class=""></div><div class=""><div class=""><font face="monospace" class="">var primes = Set.of(2, 3, 5, 7);</font></div><div class=""><font face="monospace" class="">var elems = List.of("One", "Two", "Three", "Four");</font></div><div class=""><font face="monospace" class="">IntStream.range(0, 5).filter(primes).mapToObj(elems).toList(); // ["Three", "Four"]</font></div><div class=""><br class=""></div></div><div class="">Arguably, </div><div class=""><br class=""></div><div class=""><span style="font-family: monospace;" class="">IntStream.range(0, 5).filter(primes::contains).mapToObj(elems::get).toList();</span></div><div class=""><br class=""></div><div class="">is not too bad as well…</div><div class=""><br class=""></div><div class="">Just an idea...</div><div class=""><br class=""></div><div class="">Thanks for reading!</div><div class="">- Ralf</div></div>
</body></html>