为了账号安全,请及时绑定邮箱和手机立即绑定

Java通用方法来验证对象参数中的空值

Java通用方法来验证对象参数中的空值

慕慕森 2021-07-22 14:02:23
我正在尝试实现一个逻辑,其中我有一个具有 7 个属性的 POJO 类。我已将这些 POJO 类添加到地图中,具体取决于属性的值。下面是实现Map<String,List<PriceClass>> map = new HashMap();for (PriceClass price : prices) {  if (price.getAttribute1() !=null) {      if (map.get("attribute1") !=null) {             map.get("attribute1").add(price);      } else {           map.set("attibute1",Collections.singletonList(price))      }   } else if(price.getAttribute2()!=null) {       if (map.get("attribute12") !=null) {             map.get("attribute2").add(price);       } else {           map.set("attibute2",Collections.singletonList(price))       }   } else if (price.getAttribute3() !=null) {     .     .     .   } else if (price.getAttribute7() !=null) {       //update the map   }}我的问题是,如果循环是否有任何泛化实现,我可以在这里尝试,而不是写这么多。
查看完整描述

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))

因此,您可以使用我上面发布的方式。


查看完整回答
反对 回复 2021-07-29
?
一只萌萌小番薯

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())));


查看完整回答
反对 回复 2021-07-29
?
狐的传说

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;

            }

        }

    }


查看完整回答
反对 回复 2021-07-29
  • 3 回答
  • 0 关注
  • 265 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信