Java将类型对象的ArrayList转换为另一个类型对象的ArrayList

时间:2020-07-29 18:31:19

标签: java arraylist lambda java-stream

我有一个带有成员变量的类:

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循环。

2 个答案:

答案 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
}

现在,首先使用FilterFilterRes转换为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