Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more Map.replace and .replaceAll methods (also for Multimap) #1600

Closed
danieldietrich opened this issue Oct 2, 2016 · 5 comments
Closed

Comments

@danieldietrich
Copy link
Contributor

From the Java 8 API docs:

// Replaces the entry for the specified key only if it is currently mapped to some value.
Map<K, V> replace(K key, V value)

// Replaces the entry for the specified key only if currently mapped to the specified value.
Map<K, V> replace(K key, V oldValue, V newValue)

// Replaces each entry's value with the result of invoking the given function on that entry until all entries have been processed or the function throws an exception.
Map<K, V> replaceAll(BiFunction<? super K,? super V,? extends V> function)

Offtopic: Interface and implementation popularity of Java mutable collections (presented on JavaOne 2016). It shows that Map is very popular.

interface-popularity

implementation-popularity

@danieldietrich danieldietrich added this to the 2.1.0 milestone Oct 2, 2016
@benoitheinrich
Copy link

As discussed in gitter, here is an add-on for the requirements.

We would like to have the following function:

Map<K, V> replace(K key, Function1<Option<V>, V> f);

This way we could do stuff like:

Map<K, V> map = ...;
map.replace(key, old -> Match(old).of(
                Case(Some($()), some -> ...), // Here you can add some functional code which modify the value
                Case(None(), () -> ...) // Here you can add some functional code which provide a default value
        ));

A basic implementation could be something like that:

    Map<K, V> replace(K key, Function1<Option<V>, V> f) {
        return put(key, get(key)
                .map(v -> f.apply(Option.some(v)))
                .getOrElse(() -> f.apply(Option.none()))
        );
    }

Thanks.

@danieldietrich
Copy link
Contributor Author

Regarding the gitter discussion @benoitheinrich mentioned I came to the conclusion that we already have to more general method:

<U extends V> Map<K, V> put(K key, U value, BiFunction<? super V, ? super U, ? extends V> merge);

There could be the following variations:

<U extends V> Map<K, V> put(K key, Supplier<U> value, BiFunction<? super V, ? super U, ? extends V> merge);
Map<K, V> put(K key, Supplier<? extends V> value, Function<? super V, ? extends V> merge);
Map<K, V> put(K key, V value, Function<? super V, ? extends V> merge);

But adding these variations blows up the API. The existing put(K, U, BiFunction<V, U, V>) should be sufficient for now.

@danieldietrich danieldietrich changed the title Add more Map.replace and .replaceAll methods Add more Map.replace and .replaceAll methods (also for Multimap) Nov 11, 2016
@danieldietrich
Copy link
Contributor Author

@mduesterhoeft Great to have you onboard! This issue focuses only on the three additional methods mentioned in the first comment. (The other suggestions are in fact covered already by put.)

We have a Map hierarchy and a Multimap hierarchy. The impls of the existing replace* methods delegate to the internal Maps helpers.

Many thanks :)

@mduesterhoeft
Copy link
Contributor

@danieldietrich think this could be closed?!

@danieldietrich
Copy link
Contributor Author

@mduesterhoeft That's right - thanks :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants