Collections 如何组合列表元素并找到最大组合的价格
我有一个类,它保存特定项的详细信息,如下所示:Collections 如何组合列表元素并找到最大组合的价格,collections,java-8,java-stream,Collections,Java 8,Java Stream,我有一个类,它保存特定项的详细信息,如下所示: Detail.class Long detailsId; Integer price; List<Long> stackableDetails; /*getters and setters*/ DetailId Price StackableDetails ------------------------------------------ 1011 4$ 1012, 1014
Detail.class
Long detailsId;
Integer price;
List<Long> stackableDetails;
/*getters and setters*/
DetailId Price StackableDetails
------------------------------------------
1011 4$ 1012, 1014
1012 6$ 1011,1013
1013 10$ 1012
1014 8$ 1011
.mapToDouble(Double::parseDouble)
此数据集映射到列表sampleDetails。
现在,基于stackableDetails信息,我必须组合细节并从中选择具有最大价格的组合
For eg,
In the data set available, the possible combinations would be
1011,1012,1014 - 4+6+8 = 18$
1012,1011,1013 - 6+4+10 = 20$
1013,1012 - 10+6 = 16$
1014,1011 - 8+4 = 12$
现在,细节101210111013的组合产生20美元,所以我获取这个组合并将其添加到我的结果列表中。如何在java8中实现这一点
谢谢你的帮助。谢谢 首先,这有点误导。在您的问题中,您说
从中选择价格最低的组合
,但随后(以及您的评论)您实际提供了产生最大值
结果的示例
假设您需要最大结果,您可以使用:
long maxPrice = list
.stream()
.map(d -> Stream.concat(Stream.of(d.getDetailsId()), d.getStackableDetails().stream()))
.map(s -> s.reduce(0L, (left, right) -> left +
list.stream()
.filter(dt -> dt.getDetailsId().equals(right))
.findAny()
.get()
.getPrice()))
.max(Comparator.naturalOrder())
.orElse(0L);
System.out.println(maxPrice); // 20
编辑
您希望通过max price
进行比较,但输出set
生成此价格。我唯一能想到的就是把它们放在树状图中,但这不是很容易理解。此外,当您的条目发生冲突时,也会出现这种情况-它们具有相同的最高价格。本例仅以遭遇顺序中的最后一个为例
List<Long> highest = list
.stream()
.map(d -> Stream.concat(Stream.of(d.getDetailsId()), d.getStackableDetails().stream()).collect(Collectors.toList()))
.collect(Collectors.toMap(s -> s.stream().reduce(0L,
(left, right) -> left + list.stream().filter(dt -> dt.getDetailsId().equals(right)).findAny().get().getPrice()),
s -> s.stream().collect(Collectors.toList()),
(left, right) -> right,
TreeMap::new))
.lastEntry().getValue();
List highest=List
.stream()
.map(d->Stream.concat(Stream.of(d.getDetailsId()),d.getStackableDetails().Stream()).collect(Collectors.toList())
.collect(收集器).toMap(s->s.stream().reduce(0L,
(左,右)->left+list.stream().filter(dt->dt.getDetailsId().equals(右)).findAny().get().getPrice()),
s->s.stream().collect(收集器.toList()),
(左,右)->右,
树映射::新)
.lastEntry().getValue();
EDIT2
Map<List<Long>, Long> map = list
.stream()
.map(d -> Stream.concat(Stream.of(d.getDetailsId()), d.getStackableDetails().stream()).collect(Collectors.toList()))
.collect(Collectors.toMap(
s -> s.stream().collect(Collectors.toList()),
s -> s.stream().reduce(0L,
(left, right) -> left + list.stream().filter(dt -> dt.getDetailsId().equals(right)).findAny().get().getPrice()),
(left, right) -> right));
Map=list
.stream()
.map(d->Stream.concat(Stream.of(d.getDetailsId()),d.getStackableDetails().Stream()).collect(Collectors.toList())
.collect(collector.toMap)(
s->s.stream().collect(收集器.toList()),
s->s.stream().reduce(0升,
(左,右)->left+list.stream().filter(dt->dt.getDetailsId().equals(右)).findAny().get().getPrice()),
(左,右)->右);
看着尤金斯的答案,我觉得应该也能缩短一点时间。。。以下是另一个使用and和的变体:
我想知道,为什么你可能只总结细节和它的直接可堆叠的细节。对我来说,这听起来像是一个递归问题,但另一方面,你可能知道,你需要什么:-)
关于:您可能只想将转换步骤替换为以下步骤:
Detail.class
Long detailsId;
Integer price;
List<Long> stackableDetails;
/*getters and setters*/
DetailId Price StackableDetails
------------------------------------------
1011 4$ 1012, 1014
1012 6$ 1011,1013
1013 10$ 1012
1014 8$ 1011
.mapToDouble(Double::parseDouble)
请注意,您可以将double/mapToDouble
等交换到最适合您的位置<但是,code>sum()
仅适用于三个基本流:IntStream
、LongStream
和DoubleStream
您能否澄清如何进行组合以及如何选择“最佳”组合组合?组合将基于StackableDetails中的值,从价格值的最高和中选择最佳组合。您没有提供足够的信息来确定它是否是完美的副本,但是这些信息应该会对你有所帮助。我脑子里唯一的解决办法就是第一次通过,然后把所有的detailId和price存储在地图上。在第二步中,这一次遍历stackabledetails列表,并通过每次从映射中提取价格来生成总和。我不确定这是否有效,你那边有什么建议吗?你能详细解释一下你所说的完美复制是什么意思吗?谢谢你指出,我已经纠正了同样的问题。非常感谢这个解决方案,如果我得到相应的细节元素组合(并存储在结果列表中),而不是组合的总和。我该怎么做呢?@liksar你希望结果是101210111013
而不是20?我希望结果保存在列表中。因此,bestDetails将有3个与DetailID对应的Detail对象-10121011,1013@liksar让我们以四个细节为例。你到底想从中得到什么?价格为max
的单个详细信息,排序的详细信息列表?等你能说得更详细些吗?@liksar见EDIT2。这是我在这里做的最后一次编辑,请将您的问题作为新问题发布。你不仅可以把它说得更清楚,还可以帮助别人。