简体   繁体   中英

Get all values if Keys contain same substring in Java HashMap

I am trying to get all Values from Keys that contain the same substring. For example:

If a Key's string is "AAABBB' and another Key's string is 'XXXBBB' I want to get the Value from both of those Keys. (Since BBB matches)


The relationship of the substring match should be 3 characters in length. The prefix is from index 0-3 and the suffix index is from 3-6.

For example: AAABBB (AAA is the suffix and BBB is the prefix.)

(The relationship AABBBA is ignored because AAB and BBA do not match.)

I'm trying to avoid using nested for loops because my algorithm will run very slow at O(N^2). I'm working on finding a solution with 1 HashMap and 1 for loop.

HashMap a = new HashMap();

    map.put("AAABBB", 1);
    map.put("CCCPPP", 2);
    map.put("XXXBBB", 3);
    map.put("AAAOOO",4);



    for (Entry<String, String> entry : a.entrySet()) {
         String prefix = entry.getKey().substring(0,3);
         String suffix = entry.getKey().substring(3,6);

            if(map.contains("ANY_SUBSTRING" + suffix){
                System.out.println(map.get("ANY_SUBSTRING" + suffix);
                }

             }

Output: (1,3)

AAABBB => 1 XXXBBB => 3

I have following approach with streams.

  • Define a function to extract the suffix or prefix of each key of your map
  • Stream your maps entryset and group by prefix/suffix
  • filter those out which have no prefix/suffix incommon

Using your example map and assuming each key length is = 6

Map<String,Integer> map = new HashMap<>();
map.put("AAABBB", 1);
map.put("CCCPPP", 2);
map.put("XXXBBB", 3);
map.put("AAAOOO",4);

Function<Entry<String, Integer>,String> prefix = e -> e.getKey().substring(0,3);
Function<Entry<String, Integer>,String> suffix = e -> e.getKey().substring(3);

Map<String,List<Integer>> resultBySuffix = 
        map.entrySet().stream()
             .collect(Collectors.groupingBy( suffix , 
                        Collectors.mapping(Entry::getValue, Collectors.toList())
            )).entrySet().stream()
                    .filter(e -> e.getValue().size() > 1)
                    .collect(Collectors.toMap(Entry::getKey, Entry::getValue));

System.out.println(resultBySuffix);

Map<String,List<Integer>> resultByPrefix = 
       map.entrySet().stream()
            .collect(Collectors.groupingBy( prefix , 
                            Collectors.mapping(Entry::getValue, Collectors.toList())
            )).entrySet().stream()
                    .filter(e -> e.getValue().size() > 1)
                    .collect(Collectors.toMap(Entry::getKey, Entry::getValue));

System.out.println(resultByPrefix); 

No idea what the time complexity of the above example is like. But I think you can see what is going on (in terms of readability)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM