Поместите в карту, если ключ существует и значение не равно нулю, иначе выведите исключение - PullRequest
2 голосов
/ 27 марта 2020
void addToMapIfKeyExists(String k, String v) {
    if (!map.containsKey(k)) {
        throw new NoSuchElementException(k + " does not exist in the map");
    }

    // else ignore
    if (v != null) {
        map.put(k, v);
    }
}

Могу ли я написать это лучше Java 8? Можно ли каким-то образом объединить его в одно выражение?

Ответы [ 3 ]

3 голосов
/ 27 марта 2020

Вы можете в одном выражении:

public void overwrite(String k, String v) {
    map.compute(k, (key, value) -> {
        if (value == null) throw new NoSuchElementException(key + " does not exist in the map");
        return v == null ? value : v;
    });
}

Выше указано:

[1], если ключ отсутствует на карте или сопоставлен с нулем, он выбрасывает NoSuchElementException.

[2] В противном случае ничего не будет сделано, если вы попытаетесь установить null.

[3], в противном случае установите ключ на новое значение

Что, очевидно, и нужно, но это странное сочетание требований.

2 голосов
/ 27 марта 2020

В простейшей форме, которая читается, вам могут соответствовать следующие:

static void addToMapIfKeyExists(String k, String v) {
    if (v != null && map.containsKey(k)) { // if key exists and value is not null
        map.put(k, v); // Put in the map 
    } else { // else throw exception
        throw new IllegalArgumentException("Else throwing exception.");
    }
}

Отказ от ответственности : Решите, прежде чем выбрать это. Я бы НЕ рекомендовал это как практику, основанную на задействованных API.

static void addToMapIfKeyExistsOneLiner(String k, String v) {
    map.put(k, Optional.ofNullable(v)
            .filter(ignore -> map.containsKey(k))
            .orElseThrow(IllegalArgumentException::new));
}

, и я мог бы сравнить поведение обоих этих методов одинаково, используя следующие тесты:

static Map<String, String> map = new HashMap<>();

private static void comparativeTest() {
    map.put("a", "trying");
    map.put("b", "crying");

    addToMapIfKeyExists("a", "works");
    System.out.println(map.get("a").equals("works"));

    addToMapIfKeyExistsOneLiner("a", "works");
    System.out.println(map.get("a").equals("works"));


    addToMapIfKeyExists("b", null); // null value throw exception
    addToMapIfKeyExists("e", "new key throws exception");

    addToMapIfKeyExistsOneLiner("b", null); // null value throw exception
    addToMapIfKeyExistsOneLiner("e", "new key throws exception");
}
1 голос
/ 27 марта 2020

Помните, требование:

Поместить в карту, если ключ существует или значение не равно нулю, иначе выдается исключение

Какой означает:

  • Если ключ не существует, выбросить исключение
  • Если значение равно нулю, выбросить исключение
  • Вставить в карту

Сначала следует выполнить проверку на ноль, затем использовать метод replace(K key, V value) и проверить возвращаемое значение, поэтому поиск по карте выполняется только один раз.

void addToMapIfKeyExists(String k, String v) {
    if (v == null)
        throw new IllegalArgumentException("Value is null");
    if (map.replace(k, v) == null)
        throw new NoSuchElementException("Key doesn't exist: " + k);
}
...