1

I need to sum the value in same key not just to replace? Thanks.

    LinkedHashMap<String, LinkedHashMap<String, Integer>> users = new LinkedHashMap<>();
    for (int i = 0; i < n; i++) {
        String[] input = scanner.readLine().split("\\s+");
        String ip = input[0];
        String name = input[1];
        int duration = Integer.parseInt(input[2]);
        if (!users.containsKey(name)) {
            users.put(name, new LinkedHashMap<>());
            users.get(name).put(ip,duration);
        } else {
            users.get(name).put(ip,duration);
        }
    }
2
  • 3
    Use a Map<String, YourClass>, where YourClass has a name, an ip, and a cumulatedDuration. Add an addDuration(int duration) method to the class to add a duration to the cumulated duration. Java is an OO language. Use classes. This will make your code much clearer (and faster, too). Commented Dec 29, 2017 at 15:56
  • Thanks for your advice but the aim is to solve without classes and I am trying :) Commented Dec 29, 2017 at 16:02

5 Answers 5

3

You can do it by using Map.computeIfAbsent in the outer map, along with Map.merge in the inner maps:

Map<String, Map<String, Integer>> users = new LinkedHashMap<>();

for (int i = 0; i < n; i++) {
    String[] input = scanner.readLine().split("\\s+");
    String ip = input[0];
    String name = input[1];
    int duration = Integer.parseInt(input[2]);

    users.computeIfAbsent(name, k -> new LinkedHashMap<>())
        .merge(ip, duration, Integer::sum);
}
Sign up to request clarification or add additional context in comments.

1 Comment

You are god, I was waiting exactly about this answer. Simply I wanna sum by names not IP because one user can in by different IPs. Big thanks!
2

I believe it'd be your answer Try this:

for (int i = 0; i < n; i++) {
        String[] input = scanner.readLine().split("\\s+");
        String ip = input[0];
        String name = input[1];
        int duration = Integer.parseInt(input[2]);
        if (!users.containsKey(name)) {
            users.put(name, new LinkedHashMap<>());
            users.get(name).put(ip, duration);
        } else {
            LinkedHashMap<String, Integer> user = users.get(name);
            Integer userDuration = user.get(ip);
            user.put(ip, userDuration + duration);
        }
    }

3 Comments

Not sure of the setup here but if there is ever the same name and different ip this will throw a null pointer
Yes you are right "Exception in thread "main" java.lang.NullPointerException"
I have an answer above that should work for you in this case
2
LinkedHashMap<String, LinkedHashMap<String, Integer>> users = new LinkedHashMap<>();
    for (int i = 0; i < n; i++) {
        String[] input = scanner.readLine().split("\\s+");
        String ip = input[0];
        String name = input[1];
        int duration = Integer.parseInt(input[2]);
        LinkedHashMap<String, Integer> ipDurations= users.get(name);
        
        if (ipDurations== null) {
            ipDurations= new LinkedHashMap<>();
            ipDurations.put(ip, duration);
            users.put(name, ipDurations);
        } else {
            Integer cummulativeDuration = ipDurations.get(ip);
            if (cummulativeDuration == null) {
               cuumulativeDuration = 0;
               ipDurations.put(ip, cummulativeDuration);
            }
            cummulativeDuration += duration;
          }
     }

Comments

1

Unfortunately I cannot add full snippet due I type from phone, but I beleive all you need is stream and collect with merge if you need initial map later, or just merge instead put if you dont

Comments

0
int oldDuration = users.get(name).get(ip);
int totalDuration = oldDuration + duration;
users.get(name).put(ip, totalDuration);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.