Удаление одной коллекции из другой
Суть. удалить из коллекции элементы значение value которых > 300, создал отдельную коллекцию, где храню элементы > 300, не могу найти способ как удалить одну коллекцию из другой.
public static HashMap<String, Integer> magSort(HashMap<String, Integer> shopCart) {
HashMap <String, Integer> delete = new HashMap<>();
for (Map.Entry<String, Integer> item:shopCart.entrySet()){
if (item.getValue() > 300) {
delete.put(item.getKey(), item.getValue());
}
}
return shopCart;
}
P.s очень пытался найти решение сам к сожалению не смог, думал можно как то с помощью RemoveAll или stream, но не получалось реализовать.
Ответы (2 шт):
Создавать дополнительную коллекцию для того, чтобы удалить одну из другой, вовсе не обязательно. Можно воспользоваться, например, дефолтным методом removeIf(), который определён в интерфейсе Collection начиная с версии Java 8.
Однако применяется он не к самой "мапе", а к множеству её записей, которое можно получить методом entrySet(). Вот пример, как можно произвести удаление записей, значение в которых больше 300, с использованием метода removeIf():
HashMap<String, Integer> source = new HashMap<>(Map.of("1", 300, "2", 100, "3", 450,
"4", 50, "5", 500, "6", 142, "7", 301));
source.entrySet().removeIf(entry -> entry.getValue() > 300);
System.out.println(source);
В результате получаем:
{1=300, 2=100, 4=50, 6=142}
Хотел бы дополнить ответ @Byb в том плане, что операции по удалению можно применить и к набору ключей, который возвращается методом Map::keySet, и к коллекции значений, возвращаемой методом Map::values.
Следует также заметить, что метод magSort, возвращающий мапу, подразумевает, что входная мапа не должна меняться, то есть следовало бы создать новую мапу, что легко выполняется при помощи Stream API (условие в фильтре должно тогда быть противоположным -- в новой мапе остаются элементы, чьи значения меньше или равны 300):
public static Map<String, Integer> magSort(Map<String, Integer> shopCart) {
return shopCart.entrySet().stream()
.filter(e -> e.getValue() <= 300)
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
Пример использования removeAll для множества значений при помощи метода, модифицирующего входной параметр и потому имеющего тип void:
public static void remAllOver300(Map<String, Integer> shopCart) {
Set<Integer> over300 = shopCart.values().stream()
.filter(n -> n > 300)
.collect(Collectors.toSet());
shopCart.values().removeAll(over300);
}
Тесты:
var data = new HashMap<>(Map.of(
"1", 300, "2", 100, "3", 450,
"4", 50, "5", 500, "6", 142, "7", 301
));
var filtered = magSort(data);
System.out.println("magSort: " + filtered);
var data2 = new HashMap<>(data);
var data3 = new HashMap<>(data);
System.out.println("input: " + data);
Predicate<Integer> over300 = v -> v > 300;
data.values().removeIf(over300);
System.out.println("values: " + data);
//
Predicate<String> valOver300 = k -> data2.get(k) > 300;
data2.keySet().removeIf(valOver300);
System.out.println("keys: " + data2);
remAllOver300(data3);
System.out.println("remAll: " + data3);
Результат:
magSort: {1=300, 2=100, 4=50, 6=142}
input: {1=300, 2=100, 3=450, 4=50, 5=450, 6=142, 7=301}
values: {1=300, 2=100, 4=50, 6=142}
keys: {1=300, 2=100, 4=50, 6=142}
remAll: {1=300, 2=100, 4=50, 6=142}