【问题标题】:Optimising the java code for approach of Map computeIfPresent优化 Map computeIfPresent 方法的 java 代码
【发布时间】:2019-09-01 14:18:50
【问题描述】:

我有以下方法,我从实体中提取值,然后将其设置为映射中的值作为该映射的值,但我的观点是,对于每个键,我都明确设置值,因此如果密钥增长,方法代码也会增长,我可以根据方法 Map.computeIfPresent 制作一个通用方法,请告知我如何才能实现这两个目标

   private void setMap(AbcLoginDTO abcLoginDTO, Map<String, Object> getMap) {
        getMap.put("XXNAME", abcLoginDTO.getUsername());
        getMap.put("XX_ID", abcLoginDTO.getClientId());
        getMap.put("RR_ID", abcLoginDTO.getUserId());
        getMap.put("QQ_TIME", abcuserLoginDTO.getLocktime());
    }

我在想下面这种方法

static <E> void setIfPresent(Map<String, Object> map, String key, Consumer<E> setter, Function<Object, E> mapper) {
        Object value = map.get(key);
        if (value != null) {
            setter.accept(mapper.apply(value));
        }
    }

【问题讨论】:

  • 你的“XX”、“RR”和“QQ”是什么?哪一列是您的主键 userId 或 ClientID?
  • 问题不清楚。您的第二个代码块中的“二传手”是什么?显示的两个块做了非常不同的事情。
  • 确实不是很清楚。如果你只是想避免写多个put,那么我认为这个问题与Java introspection object to map重复

标签: java


【解决方案1】:

但我的意思是,对于每个键,我都明确地设置了值,所以 如果键的数量增加,那么方法代码也会增加

您需要使用来自 DTO 的不同值填充 Map,因此您没有其他选择。
该方法很长,因为您没有要在 Map 中添加的键和要从 DTO 检索的值之间的映射。

您可以使用以下函数编写代码:

static void setValueInMap(Map<String, Object> map, String key, Supplier<Object> mapper) {
    map.put(key, mapper.get());
}

然后使用它:

Map<String, Object> map = ...;
AbcLoginDTO dto = ...;
setIfPresent(map, "keyUserName", dto::getUserName);
// and so for 

但没有真正的优势。

您的第二个 sn-p 与第一个完全没有关系。

【讨论】:

    【解决方案2】:

    如果我理解正确,您要做的是遍历对象的所有成员,获取它们的值,然后根据它们的名称将它们设置为映射。如果是这样,那么您正在寻找的就是反射。

    每个对象都可以为您提供其字段或方法的数组(甚至是私有的!),然后您可以使用字段/方法对象来操作它们。

    Field[] members = AbcLoginDTO.class.getDeclaredFields();
    Map<String, Object> values = new HashMap<>();
    
    for(Field member : members) {
        member.setAccessible(true);
        values.put(member.getName(), member.get(abcLoginDTO));
    }
    

    您最终得到的是 AbcLoginDTO 实例的“地图表示”。从这里你可以用它做你想做的事...... 请注意,我在第 1 行“检查”类本身,然后在第 6 行使用实例。 这段代码并不完整,但它是一个开始,这也可以适用于任何对象。

    【讨论】:

      【解决方案3】:

      我不知道我是否理解正确,但如果我理解了,那意味着您需要的只是一种为AbcLoginDTO class 的方法手动设置不同键的方法 如果是这样,那么这很容易做到, 让我们考虑您的 abcLoginDTO.getClientId() 对于每个 AbcLoginDTO 对象总是不同的:

      private void setMap(AbcLoginDTO abcLoginDTO, Map<String, Object> getMap) {
              getMap.put(Integer.toString(abcLoginDTO.getClientId())+"_NAME", abcLoginDTO.getUsername());
              getMap.put(Integer.toString(abcLoginDTO.getClientId())+"_ID", abcLoginDTO.getClientId());
              getMap.put(Integer.toString(abcLoginDTO.getClientId())+"_ID", abcLoginDTO.getUserId());
              getMap.put(Integer.toString(abcLoginDTO.getClientId())+"_TIME", abcuserLoginDTO.getLocktime());
          }
      

      【讨论】:

      • 我同意这个问题不是很清楚,但我认为这不是 OP 需要的。我认为他只是想避免为每个字段调用put
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-30
      • 1970-01-01
      相关资源
      最近更新 更多