Метод переопределения для использования Java 8 Map.computeIfAbsent() с заброшенным исключением

Я пытаюсь переработать некоторые из моих методов, чтобы сделать их более краткими, используя Java 8, чьи новые функции я пытаюсь медленно поглощать.

Это метод с целью добавления value в Map<Key, Set<Value>>. Есть три возможности:

  • Ключ не существует: он добавляется, и с ним связан новый набор, содержащий значение.
  • Ключ существует: значение добавляется к существующему набору. Обратите внимание, что набор никогда не будет null, потому что у меня есть некоторые предварительные условия, чтобы справиться с этим.
  • Ключ существует, и значение уже содержится в наборе: IllegalArgumentException.

Код, реализующий это поведение, следующий: он не использует функции Java 8:

public void addValue(Key key, Value value) {
    // irrelevant preconditions...

    Set<Value> valuesForKey = myMap.get(key);
    if (valuesForKey != null && valuesForKey.contains(value))
        throw new IllegalArgumentException("Association exists already");

    if (valuesForKey == null)
        myMap.put(key, new HashSet<Value>(Arrays.asList(value)));
    else
        valuesForKey.add(value);
}

Я хотел бы сократить этот код с помощью методов Java 8, таких как computeIfAbsent.

Я мог бы суммировать последний блок if-else, но я не могу обойти избыточность значения, установленного на карту key, чтобы быть уже извлеченным при выполнении предварительных проверок.

public void addValue(Key key, Value value) {
    // irrelevant preconditions...

    Set<Value> valuesForKey = myMap.get(key);
    if (valuesForKey != null && valuesForKey.contains(value))
        throw new IllegalArgumentException("Association exists already");

    myMap.computeIfAbsent(key, v -> new HashSet<Value>()).add(value);
}

В любом случае, я мог бы объединить все это в одну инструкцию?

Ответ 1

Вы можете воспользоваться тем фактом, что метод add(element) вернет true, если набор не содержит указанный элемент. Если этот вызов возвращает false, это означает, что элемент не был добавлен, потому что он уже присутствовал. Поэтому вы можете использовать:

public void addValue(Key key, Value value) {
    boolean added = myMap.computeIfAbsent(key, k -> new HashSet<>()).add(value);
    if (!added) {
        throw new IllegalArgumentException("Association exists already");
    }
}