From ralf.spoeth at gmail.com Thu Sep 15 15:19:35 2022 From: ralf.spoeth at gmail.com (=?utf-8?Q?Ralf_Sp=C3=B6th?=) Date: Thu, 15 Sep 2022 17:19:35 +0200 Subject: Enhance Map, List, and Set such that these interfaces extend Function, IntFunction, and Predicate, respectively Message-ID: <266971CB-8C96-4E7F-9BDA-1371C5D8D866@gmail.com> Dear all, 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 Map, List, and Set: (please forgive lousy syntax hereinafter) interface Map extends Function { default V apply(K k) {return get(k);} } interface List extends IntFunction { default T apply(int index) { return get(I);} } interface Set extends Predicate { default boolean test(T t) {return contains(t);} } The cost of extending existing interfaces in widespread use may be prohibitive, plus you may find the value proposition not very convincing. The interpretation of a Map as a Function feels very natural, although the use of the given map in a stream is also straightforward: Stream.of(1, 2).map(Map.of(1, "One", 2, "Two")::get).toList(); // ["One", "Two"] Assigning the map to a function variable is a little more demanding: // var m = Map.of(...)::get; compiler error Function m = Map.of(1, "One")::get; // WORKS Since we enjoy the pleasures of local variable type inference, this is a little awkward. If a map were a function, then we might write instead: var m = Map.of(1, "One", 2, "Two"); Stream.of(1, 2).map(m).toList(); // ["One", "Two"] The interpretation of a list as a function of an index may seem a little more far-fetched: var l = List.of("One", "Two", "Three"); IntStream.range(0, l.size()).filter(i -> i%2==0).mapToObj(l::get).toList(); // ["One", "Three"]; The test for inclusion in a set is a common operation and is therefore a frequent candidate for filters in stream operations. var primes = Set.of(2, 3, 5, 7); IntStream.range(5, 10).filter(primes::contains).toArray(); // [5, 7] With Set implementing Predicate and List implementing IntFunction we may write: var primes = Set.of(2, 3, 5, 7); var elems = List.of("One", "Two", "Three", "Four"); IntStream.range(0, 5).filter(primes).mapToObj(elems).toList(); // ["Three", "Four"] Arguably, IntStream.range(0, 5).filter(primes::contains).mapToObj(elems::get).toList(); is not too bad as well? Just an idea... Thanks for reading! - Ralf -------------- next part -------------- An HTML attachment was scrubbed... URL: From brian.goetz at oracle.com Thu Sep 15 15:34:15 2022 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 15 Sep 2022 11:34:15 -0400 Subject: Enhance Map, List, and Set such that these interfaces extend Function, IntFunction, and Predicate, respectively In-Reply-To: <266971CB-8C96-4E7F-9BDA-1371C5D8D866@gmail.com> References: <266971CB-8C96-4E7F-9BDA-1371C5D8D866@gmail.com> Message-ID: On 9/15/2022 11:19 AM, Ralf Sp?th wrote: > Dear all, > > 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 Map, List, and Set: > > (please forgive lousy syntax hereinafter) > > interface Map extends Function { > ? ? default V apply(K k) {return get(k);} > } > > interface List extends IntFunction { > ? ?default T apply(int index) { return get(I);} > } > > interface Set extends Predicate { > ? ?default boolean test(T t) {return contains(t);} > } These were considered during JSR 335.? They are conceptually sensible, but we decided against it for two reasons: ?- Adding these methods to highly general interfaces with many implementations extant could introduce conflicts, where someone's `MySet` could have an incompatible "test" method; ?- The functionality you want is easy accessed via method references: map::get converts to Function (and map::contains to Predicate); list::get conversions to IntFunction; set::contains to Predicate. From ralf.spoeth at gmail.com Thu Sep 15 16:16:58 2022 From: ralf.spoeth at gmail.com (=?utf-8?Q?Ralf_Sp=C3=B6th?=) Date: Thu, 15 Sep 2022 18:16:58 +0200 Subject: Enhance Map, List, and Set such that these interfaces extend Function, IntFunction, and Predicate, respectively In-Reply-To: References: <266971CB-8C96-4E7F-9BDA-1371C5D8D866@gmail.com> Message-ID: <62F4D221-54CF-48C5-8F5C-9E5E2AF0B5C4@gmail.com> Thanks for answering that quickly! Regards Ralf > Am 15.09.2022 um 17:34 schrieb Brian Goetz : > > > > On 9/15/2022 11:19 AM, Ralf Sp?th wrote: >> Dear all, >> >> 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 Map, List, and Set: >> >> (please forgive lousy syntax hereinafter) >> >> interface Map extends Function { >> default V apply(K k) {return get(k);} >> } >> >> interface List extends IntFunction { >> default T apply(int index) { return get(I);} >> } >> >> interface Set extends Predicate { >> default boolean test(T t) {return contains(t);} >> } > > These were considered during JSR 335. They are conceptually sensible, but we decided against it for two reasons: > > - Adding these methods to highly general interfaces with many implementations extant could introduce conflicts, where someone's `MySet` could have an incompatible "test" method; > > - The functionality you want is easy accessed via method references: map::get converts to Function (and map::contains to Predicate); list::get conversions to IntFunction; set::contains to Predicate. > >