2015-03-12 2 views
-1

У меня есть набор объектов, с использованием следующего вида:Java 8 Стрят API Фильтрация

{ 
    String action_name; //add or delete 
    long action_time; 
    String action_target; 
} 

нужен, чтобы получить последнюю слитую операцию на каждом action_target

ввод образца данные:

[add|1001|item1, add|1002|item2, delete|1003|item1, add|1004|item1] 

Ожидаемый результат:

[add|1002|item2, add|1004|item1] 

Пример входных данных:

[add|1001|item1, add|1002|item2, delete|1003|item1] 

Ожидаемый результат:

[add|1002|item2] 

Пример входных данных:

[delete|1001|item1, add|1002|item2, add|1003|item1] 

Ожидаемый результат:

[add|1002|item2, add|1003|item1] 

Является ли это доступным с помощью Java8 потоковых API? Благодарю.

+3

Пожалуйста, используйте правый формат «Markdown». См. Справочные документы StackOverflow. – Turtle

+0

спасибо за переформатирование – heyu

ответ

2

Вы хотите группе один критериев (action_target) в сочетании с сокращения групп к максимальной их action_time значений:

Map<String,Item> map=items.stream().collect(
    Collectors.groupingBy(item->item.action_target, 
     Collectors.collectingAndThen(
      Collectors.maxBy(Comparator.comparing(item->item.action_time)), 
      Optional::get))); 

Это возвращает Map<String,Item>, но, конечно же, вы можете позвонить values(), чтобы получить коллекцию предметов.

украшено static import с, код выглядит следующим образом:

Map<String,Item> map=items.stream().collect(groupingBy(item->item.action_target, 
    collectingAndThen(maxBy(comparing(item->item.action_time)), Optional::get))); 

Ваш дополнительный запрос заботиться о идемпотенту "add" и последующие "delete" действия могут быть упрощены, чтобы «удалить элементы, для которых последнее действие "delete" ", который может быть реализован только после этого с помощью измененной карты:

HashMap<String,Item> map=items.stream().collect(groupingBy(
    item->item.action_target, HashMap::new, 
    collectingAndThen(maxBy(comparing(item->item.action_time)), Optional::get))); 
map.values().removeIf(item->item.action_name.equals("delete")); 
+0

Спасибо за подробные шаги, однако, это не поможет слить часть действия - если на входе есть одно добавление, за которым следует одно удаление на том же элементе, вывод не должен включать этот элемент вообще, вместо того, чтобы показывать последнее удаление. Добавляя к этому, поскольку операция является идемпотентной, список может быть добавлен, добавлен, удален в том же элементе, результат должен все равно отфильтровать этот элемент. Это самая сложная часть проблемы. Есть идеи? Благодарю. – heyu

+1

Ваш вопрос не содержит этой информации. – Holger

+0

Извините, я не дал понять, что это невозможно решить, просто удалив последнее удаление, например. Для определенного элемента, если последовательность действий: del add add add del, мы все равно хотим включить последний del; если добавить del add, ничего не показывать; если он добавляет add del add, покажите последнее добавление. Не уверен, что это прояснит проблему. Еще раз спасибо за помощь. – heyu

Смежные вопросы