1

I have the below method, in which I am extracting the value from the entity and then setting it in map as a value of that map but my point is that for each key I am setting the value explicitly so if the count of keys grows that method code will also grow , can I make a common method based on approach Map.computeIfPresent, please advise how can I achieve both the things

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

something like in this below approach I am thinking

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));
        }
    }
  • what are your "XX","RR" and "QQ" ? and which column is your primary key userId or ClientID? – Daniel_Kamel Sep 01 '19 at 14:23
  • The question is not clear. What is the 'setter' in your second block of code? The two blocks shown do very different things. – swpalmer Sep 01 '19 at 14:36
  • It's not very clear indeed. If you just want to avoid writing multiples `put`, then I think that this question a duplicate of [Java introspection object to map](https://stackoverflow.com/questions/6796187/java-introspection-object-to-map) – Arnaud Claudel Sep 01 '19 at 15:30

3 Answers3

1

If i understand correctly, what you want to do is iterate over all of the object's members, get their value, and set them to a map according to their name. If so, then what you're looking for is called Reflection.

Every object can give you an array of its fields or methods (even private ones!) and then you can manipulate them using the Field / Method object.

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

What you end up with here, is a "Map representation" of your AbcLoginDTO instance. from here you can do with it what you want... notice that i am "inspecting" the class itself in line 1, and then using the instance at line 6. this code is not complete, but it's a start, and this can also be adapted to work for ANY object.

Tom Elias
  • 751
  • 6
  • 15
1

but my point is that for each key I am setting the value explicitly so if the count of keys grows that method code will also grow

You need to populate the Map with different values from the DTO, so you don't have other choices.
The method is long because you don't have a mapping between the key to add in the Map and the value to retrieve from the DTO.

You could write your code with a function such as :

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

And use that :

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

But no real advantages.

Your second snippet has not at all relationship with the first one.

davidxxx
  • 125,838
  • 23
  • 214
  • 215
0

I don't know if I understood correctly, but if I did then that means all you need is a way to manually set different keys for the methods of your AbcLoginDTO class If so then that can be done easily, let's consider that your abcLoginDTO.getClientId() is always different for every AbcLoginDTO object:

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());
    }
Daniel_Kamel
  • 610
  • 8
  • 29
  • 1
    I agree that the question is not very clear, but I don't think that is what the OP needs. I think that he simply wants to avoid to call `put` for each field. – Arnaud Claudel Sep 01 '19 at 15:27