Как вывести сообщение о том, что список ничего не нашел?

Рейтинг: -1Ответов: 1Опубликовано: 12.05.2023

У меня есть список, в виде словаря.

TreeMap<Product, Integer> listTree = new TreeMap; 

Product - принимает String name и int age; new SortProductByCost - Comparator, который сортирует возраст.

Мне нужно создать метод, который удаляет определенный элемент по имени, но метод принимает как параметр String name, при этом, если список ничего не найдет, то вывести сообщение, что товар не найден.

Мой пример:

public void deleteProduct(String name) {
    try {
        for (Map.Entry<Product, Integer> entry : listProductMap.entrySet()) {
            if (entry.getKey().getName().equals(name)) {
                listProductMap.remove(entry.getKey());
                System.out.println("Удален");
                return;
            }
        }
    } catch (Exception e) {
        System.out.println(e.getMessage());
    }
}

Ответы

▲ 0

У вас может быть несколько ключей Product, удовлетворяющих условию равенства поля name, поэтому достаточно использовать метод Collection::removeIf для набора ключей, который возвращает true, если хотя бы один ключ был удалён:

TreeMap<Product, Integer> listProductMap = new TreeMap<>();

public void deleteProductsByName(String name) {
    if (listProductMap.keySet().removeIf(pKey -> name.equals(pKey.getName())) {
        System.out.println("Ключи удалены");
    } else {
        System.out.println("Товары не найдены");
    }
}

Аналогично, можно отфильтровать ключи по заданному признаку/признакам, а затем удалить их, используя стандартный метод Collection::removeAll, который также возвращает true, если сет ключей изменился после удаления.
В таком случае удобнее выполнить дополнительные операции над множеством ключей, удаляемых из мапы:

public void deleteProductsByName(String name) {
    Set<Product> prodsToDelete = listProductMap.keySet()
        .stream()
        .filter(productKey -> name.equals(productKey.getName()))
        .collect(Collectors.toSet());

    if (listProductMap.keySet().removeAll(prodsToDelete)) {
        System.out.println("Удалённые ключи: " + prodsToDelete);
    } else {
        System.out.println("Товары не найдены");
    }
}

Если же нужно удалить только первый ключ, удовлетворяющий условию, как показано в коде, приведённом в вопросе, то достаточно вывести соответствующее сообщение после цикла, как посоветовали в комментариях к вопросу:

public void deleteFirstProductByName(String name) {
    for (Product key : listProductMap.keySet()) {
        if (name.equals(key.getName()) 
            && listProductMap.keySet().remove(key)) {
            System.out.println("Удалённый товар: " + key);
            return; // избегаем ConcurrentModificationException
        }
    }
    System.out.println("Товар не найден: " + name);
}

Аналогично с использованием Stream API Stream::findFirst + Optional::ifPresentOrElse:

public void deleteFirstProductByName(String name) {
    listProductMap.keySet()
        .stream()
        .filter(key -> name.equals(key.getName())
        .findFirst() // Optional<Product>
        .ifPresentOrElse(key -> {
                listProductMap.keySet().remove(key);
                System.out.println("Удалённый товар: " + key);
            }, 
            () -> System.out.println("Товар не найден: " + name)
        );
}