3 回答
TA贡献1820条经验 获得超10个赞
一个可能的最佳解决方案将类似于一个我已经在今天早些时候建议。
使用 将已检查属性Map<String, Optional<?>>的Optional值与未来输出映射键的键一起存储。
Map<String, Optional<?>> options = new HashMap<>();
options.put("attribute1", Optional.ofNullable(price.getAttribute1()));
// ...
options.put("attribute3", Optional.ofNullable(price.getAttribute2()));
// ...
使用索引的迭代可以让您执行地图的更新。
Map<String,List<Price>> map = new HashMap();
for (int i=1; i<7; i++) { // attributes 1..7
String attribute = "attribute" + i; // attribute1...attribute7
options.get(attribute).ifPresent(any -> // for non-nulls
map.put( // put to the map
attribute, // attribute as key remains
Optional.ofNullable(map.get(attribute)) // gets the existing list
.orElse(new ArrayList<>()) // or creates empty
.add(price))); // adds the current Price
}
此外,我敢打赌你的意图有点不同。没有方法Map::set
map.set("attibute1",Collections.singletonList(price))
你不是想把List<Price>一个项目放在同一个键上吗?
map.put("attibute1", Collections.singletonList(price))
因此,您可以使用我上面发布的方式。
TA贡献1795条经验 获得超7个赞
您可以使用
Map<String,List<PriceClass>> map = new HashMap<>();
for(PriceClass price: prices) {
HashMap<String,Object> options = new HashMap<>();
options.put("attibute1", price.getAttribute1());
options.put("attibute2", price.getAttribute2());
options.put("attibute3", price.getAttribute3());
options.put("attibute4", price.getAttribute4());
options.put("attibute5", price.getAttribute5());
options.put("attibute6", price.getAttribute6());
options.put("attibute7", price.getAttribute7());
options.values().removeIf(Objects::isNull);
options.keySet().forEach(attr -> map.computeIfAbsent(attr, x -> new ArrayList<>())
.add(price));
}
或概括过程:
一次准备一个不可修改的地图
static final Map<String, Function<PriceClass,Object>> ATTR;
static {
Map<String, Function<PriceClass,Object>> a = new HashMap<>();
a.put("attibute1", PriceClass::getAttribute1);
a.put("attibute2", PriceClass::getAttribute2);
a.put("attibute3", PriceClass::getAttribute3);
a.put("attibute4", PriceClass::getAttribute4);
a.put("attibute5", PriceClass::getAttribute5);
a.put("attibute6", PriceClass::getAttribute6);
a.put("attibute7", PriceClass::getAttribute7);
ATTR = Collections.unmodifiableMap(a);
}
并使用
Map<String,List<PriceClass>> map = new HashMap<>();
for(PriceClass price: prices) {
HashMap<String,Object> options = new HashMap<>();
ATTR.forEach((attr,func) -> options.put(attr, func.apply(price)));
options.values().removeIf(Objects::isNull);
options.keySet().forEach(attr -> map.computeIfAbsent(attr, x -> new ArrayList<>())
.add(price));
}
要么
Map<String,List<PriceClass>> map = prices.stream()
.flatMap(price -> ATTR.entrySet().stream()
.filter(e -> e.getValue().apply(price) != null)
.map(e -> new AbstractMap.SimpleEntry<>(e.getKey(), price)))
.collect(Collectors.groupingBy(Map.Entry::getKey,
Collectors.mapping(Map.Entry::getValue, Collectors.toList())));
TA贡献1804条经验 获得超3个赞
如何使用 egEnum定义 7 个不同的对象,每个对象负责具体属性:
// this is client code, looks pretty easy
Map<String, List<PriceClass>> map = new HashMap<>();
for (PriceClass price : prices)
PriceAttribute.add(map, price);
// all logic is hidden within special Enum
enum PriceAttribute {
ATTRIBUTE1("attribute1", PriceClass::getAttribute1),
ATTRIBUTE2("attribute2", PriceClass::getAttribute2),
ATTRIBUTE3("attribute3", PriceClass::getAttribute3),
ATTRIBUTE4("attribute4", PriceClass::getAttribute4),
ATTRIBUTE5("attribute5", PriceClass::getAttribute5),
ATTRIBUTE6("attribute6", PriceClass::getAttribute6),
ATTRIBUTE7("attribute7", PriceClass::getAttribute7);
private final String key;
private final Function<PriceClass, ?> get;
PriceAttribute(String key, Function<PriceClass, ?> get) {
this.key = key;
this.get = get;
}
public static void add(Map<String, List<PriceClass>> map, PriceClass price) {
for (PriceAttribute attribute : values()) {
if (attribute.get.apply(price) != null) {
map.computeIfAbsent(attribute.key, key -> new ArrayList<>()).add(price);
break;
}
}
}
}
添加回答
举报