我有一个带有成员变量的类:
class Filter{
private String key;
private String operator;
private Object value;
}
以及类型过滤器列表如下:
[
{
key: status,
operator:equal,
value: active
},
{
key: status,
operator:equal,
value: inactive
},
{
key: name,
operator:equal,
value: jhon
},
{
key: id,
operator:equal,
value: 123
}
]
我想将上面的List
转换成新的List
,如下所示,如果密钥相同,key: status
那么在新列表中,列表类型为value: [active, inactive]
的值只有一个条目
并且运算符将为IN
[
{
key: status,
operator:in,
value: [active, inactive]
},
{
key: name,
operator:equal,
value: jhon
},
{
key: id,
operator:equal,
value: 123
}
]
最好使用Java 8流和lambda来实现此解决方案的最佳和有效方法是什么? 想要避免传统的for循环。
答案 0 :(得分:2)
您可以根据过滤器的键是否为Collectors.partitioningBy
,使用List
将"status"
分为两部分。 Demo
final Map<Boolean, List<Filter>> parts = list.stream()
.collect(Collectors.partitioningBy(f -> "status".equals(f.getKey())));
final Object[] statuses = parts.get(true).stream().map(Filter::getValue).toArray();
final List<Filter> result = parts.get(false);
if (statuses.length != 0) {
result.add(0, new Filter("status", "in", statuses));
}
对于多个键,可以使用Collectors.groupingBy
。 Demo
final Map<String, List<Filter>> map = list.stream().collect(Collectors.groupingBy(Filter::getKey, LinkedHashMap::new, Collectors.toList()));
final List<Filter> result = map.entrySet().stream()
.map(e -> e.getValue().size() > 1
? new Filter(e.getKey(), "in", e.getValue().stream().map(Filter::getValue).toArray())
: e.getValue().get(0))
.collect(Collectors.toList());
答案 1 :(得分:2)
首先,使用列表value
class FilterRes{
private String key;
private String operator;
private List<Object> values;
// getter setter constractor
}
现在,首先使用Filter
将FilterRes
转换为map()
,然后使用Collectors.toMap
收集为地图并在合并功能中合并组。然后在ArrayList中获取值
Map<Integer, FilterRes> resMap = list.stream()
.map(s -> new FilterRes(s.getKey(), s.getOperator(),
new ArrayList<>(Arrays.asList(s.getValue()))))
.collect(Collectors.toMap(FilterRes::getKey, e -> e,
(a, b) -> new FilterRes(a.getKey(), "in",
Stream.concat(a.getValue().stream(),
b.getValue().stream())
.collect(Collectors.toList()))));
List<FilterRes> resList= new ArrayList(resMap.values()); // Create list from map values