#java #java-8 #java-stream
#java #java-8 #java-stream
Вопрос:
У меня есть список, который я повторяю, и при некотором условии каждого элемента я добавляю каждый элемент списка в структуру данных в определенной позиции, ниже приведен код в Java 7.
Структура данных, в которую я добавляю каждый элемент из списка, является,
/* The data structure has two slots, one for parents and another for children */
MenuBar menuBar = new MenuBar();
Теперь фрагмент кода,
MenuBar menuBar = new MenuBar();
for (Menu menu : menuList) {
if (isParentMenu(menu.getId())) {
menuBar.addMenu(menu);
} else {
Menu parent = getMenuById(menu.getParentId());
menuBar.addChildMenu(parent, menu);
}
}
Теперь я изо всех сил пытаюсь создать код Java 8, эквивалентный тому же, ниже приведено то, что я пытаюсь,
// The following code is not complete , just trying
menuList.stream().filter(menu -> isParentMenu(menu.getId()))
.map(menu -> menuBar.addMenu(menu))
Комментарии:
1. Вам НЕ нужен java8, чтобы сделать это. Вместо этого используйте итеративный подход. Java8 — это НЕ серебряная пуля, которая решает все ваши проблемы.
2. и, согласно многим тестам, такой простой код с потоками работает медленнее, чем цикл for ….
Ответ №1:
Честно говоря, я не думаю, что ваш код нуждается в изменении. Как и сейчас, это достаточно ясно. Изменение его на streams может даже добавить некоторые накладные расходы, что сделает его менее производительным, чем цикл.
Действительно простым решением для потоков было бы:
MenuBar menuBar = new MenuBar();
menuList.stream().forEach(x -> {
if (isParentMenu(x.getId())) {
menuBar.addMenu(x);
} else {
Menu parent = getMenuById(x.getParentId());
menuBar.addChildMenu(parent, x);
}
});
В качестве альтернативы вы можете использовать partitioningBy
:
Map<Boolean, List<Menu>> map = menuList.stream().collect(Collectors.partitioningBy(x -> isParentMenu(x.getId())));
map.get(true).stream().forEach(menuBar::addMenu);
map.get(false).stream().forEach(x -> {
Menu parent = getMenuById(x.getParentId());
menuBar.addChildMenu(parent, x);
});
Ответ №2:
Если вы хотите использовать filter, вам нужно запустить forEach дважды, или вы пишете if-else внутри одного forEach . Что-то вроде этого:
menuList.stream().forEach(
menu -> {
if(isParentMenu(menu.getId()) {
menuBar.addMenu(menu);
} else {
Menu parent = getMenuById(menu.getParentId());
menuBar.addChildMenu(parent, menu);
}
}
);