【发布时间】:2020-10-22 17:59:13
【问题描述】:
我们需要获取所有具有特定操作的项目的列表。我知道我没有使用正确的高阶函数方法。需要了解如何使用高阶函数改进第三种解决方案,以及为什么这会花费太多时间。
解决方案 1:在没有任何 java 8 函数式编程的情况下使用深度优先搜索递归
花费时间 0.07 毫秒
getitemsDFS(ItemRef po)
{
List<ItemRef> items = new ArrayList<>();
for(Item child : po.getItem())
{
items.addAll(getAdditemsRec(child));
}
return items;
}
private List<ItemRef> getAdditemsRec(ItemRef child) {
List<ItemRef> items = new ArrayList<>();
if(SOME_ACTION.equals(child.getAction()))
{
items.add(child);
}
for(ItemRef childOI: child.getItem())
{
items.addAll(getAdditemsRec(childOI));
}
return items;
}
解决方案 2:在没有任何 java 8 函数式编程的情况下使用广度优先搜索
花费时间 0.05 毫秒
private List<ItemRef> getAddOrderItemBFS(Item po) {
List<ItemRef> items = new ArrayList<>();
Deque<ItemRef> oIDeque = new ArrayDeque<>();
oIDeque.addAll(po.getItem());
while(!oIDequ
e.isEmpty())
{
ItemRef currentOI = oIDeque.removeFirst();
if(ADD_ACTION.equals(currentOI.getAction()))
items.add(currentOI);
if(!CollectionUtils.isEmpty(currentOI.getItem()))
oIDeque.addAll(currentOI.getItem());
}
return items;
}
解决方案 3:使用函数式编程和 Lambda 表达式 11.50 毫秒
这是大约。比 1 和 2 多 200 倍,我们需要对此进行优化。 它也不是纯函数式编程,因为它涉及 ArrayList 创建和分配代码和命令式代码(事情如何 完成,而不仅仅是需要做的事情)。没有收获正确 高阶函数的好处。
private List<ItemRef> getAdditemsFunctional(ItemRef po)
{
return po
.getItem()
.stream()
.map(oi->getitemsFunctionalRec(oi))
.flatMap(List::stream)
.collect(Collectors.toList());
}
private List<ItemRef> getitemsFunctionalRec(ItemRef oi) {
List<ItemRef> listOIs = new ArrayList<>();
if(ADD_ACTION.equals(oi.getAction()))
{
listOIs.add(oi);
}
listOIs.addAll(oi.getItem()
.stream()
.map(childOI->getitemsFunctionalRec(childOI))
.flatMap(List::stream)
.collect(Collectors.toList()));
return listOIs;
}
【问题讨论】:
-
所以你有一个递归数据结构(像一棵树)并且想要将它展平并从中过滤掉一些数据?我是否正确理解了这个问题?
-
是的,@Amongalen。准确地说是过滤一些数据。
-
ItemRef和Item有什么区别?这些是完全相同的类吗? -
是的,一样。它们是相同的类,这是一个错字。
-
你可以edit你的问题来修正错别字。
标签: java java-8 functional-programming