Home > Blockchain >  filter two hashMap and make one if there some diff throw exception
filter two hashMap and make one if there some diff throw exception

Time:10-07

I have quite strange situation maybe some one has the same and can help with this:

  1. i have a class:
public class TestMap {

    private Long firstId;
    private Long secondId;
}

I created list of TestMap.class and set value:

        List<TestMap> mapRecords = new ArrayList<>();


        mapRecords.add(new TestMap(1L, null));
        mapRecords.add(new TestMap(2L, null));
        mapRecords.add(new TestMap(3L, null));

  1. I have to maps
        Map<Long, Long> firstMap = new HashMap<>();
        firstMap.put(11L, 1L);
        firstMap.put(22L, 2L);
        firstMap.put(33L, 3L);

        Map<Long, Long> secondMap = new HashMap<>();
        secondMap.put(11L,111L);
        secondMap.put(22L,222L);


    Map<Long, Long> finalMap = secondMap.entrySet().stream()
                .filter(mapFilter -> firstMap.containsKey(mapFilter.getKey()))
                .collect(Collectors.toMap(mapFilter  -> firstMap.get(mapFilter.getKey()), Map.Entry::getValue));


        mapRecords.stream().forEach(contractParametersRecord ->
              finalMap.entrySet().stream()
                        .forEach(some -> {
            if (some.getKey().equals(contractParametersRecord.getFirstId())) {
                contractParametersRecord.setSecondId(some.getValue());
            }
        }));

I have two maps that have the same keys but different values, where the value of the first map corresponds to the first value "firstId" of the list mapRecords. I need to make one of the two maps where the value of the first map becomes the key and the value of the second map becomes the value that is set to the mapRecords list at the very end. I have done all this but if you notice the first map has three values. I need one of the two maps to throw an error when there is a mismatch. How can this be done using streams? Or do I just use the try cach block?

CodePudding user response:

First, check to see if the first and second maps have the same keys, and fail if they don't:

if (!firstMap.keySet().equals(secondMap.keySet())) {
  throw new IllegalArgumentException();
}

Then you can proceed to build a map by replacing the key in the second map with the corresponding value from the first map; no filter is needed because you already verified the keys are equivalent:

Map<Long, Long> finalMap = secondMap.entrySet().stream()
  .collect(Collectors.toMap(e -> firstMap.get(e.getKey()), Map.Entry::getValue));

Finally, rather than inefficiently iterating over the entries of the final map inside another loop (an approximately O(n2) operation), simply access it as a map:

for (TestMap contractParametersRecord : mapRecords) {
  Long val = finalMap.get(contractParametersRecord.getFirstId());
  if (val != null) {
    contractParametersRecord.setSecondId(val);
  }
}

CodePudding user response:

I think this will be good:

    Map<Long, Long> finalMap = firstMap.entrySet().stream()
                        .map(c -> secondMap.entrySet().stream()
                        .filter(entry -> entry.getKey().equals(c.getKey()))
                        .findFirst()
                        .orElseThrow(() -> new IllegalArgumentException(String.format("Error: ID %s was not found", c.getKey() ))))
                .collect(Collectors.toMap(mapFilter  -> firstMap.get(mapFilter.getKey()), Map.Entry::getValue));

If there are better way can some one write? :)

  • Related