31

I have this HashMap<String, ArrayList<Item>> , is there a way to count the total number of items in all the Lists in the Map without going through all Lists?

Or should I iterate through the Map and along all lists ?

8 Answers 8

30

As of Java 8 you accomplish that with an one-liner:

Integer sum = map.values().stream().mapToInt(List::size).sum();
Sign up to request clarification or add additional context in comments.

1 Comment

Beware of the Non-static method 'size' cannot be referenced from a static context error
16

Use the size() method defined for HashMap.

HashMap<String, ArrayList<Item>> hMap = new LinkedHashMap<String, ArrayList<Item>>();
int hSize;
/*
    put/remove operations

*/

hSize = hMap.size(); // Gives the total no. of elements of HashMap

4 Comments

According to the docs this is not correct. HashMap.size() "Returns the number of key-value mappings in this map."
This will only count the number of key-value pairs as @linqu mentioned. So using hMap.size () for the following key-values: ["key1", [Item1, Item2]], ["key2", [Item3, Item4]] would only return 2, instead we want 4 since there are 4 Item objects
@Navigatron huh? then you would just multiply map.size()*2, I don't understand.
@AlexanderMills If it was just a map with the value was not a list, you could multiply it by 2. But since the value is an arraylist, there could be any number of objects in that list. You need to count the amount of objects in each list, per key of the map. Using map.size()*2 will not work for the example: ["key1", [Item1, Item2]], ["key2", [Item3, Item4, Item5, Item6]], since the total number of values is 6.
11

You might want to see Google Guava and use Multimap instead of that. The Multimap.size() method will give the answer you want.

2 Comments

The program will still iterate through all elements (just in case the author asked his question out of performance reasons and not just laziness to code).
7

You'll need to iterate over the List<Item> values in your Map and count the total. The Map doesn't have any knowledge of what values you're putting into it, so it can't provide a facility to get you a total. The code you need is fairly simple:

int total = 0;
for (List<Item> list : map.values()) {
    total += list.size();
}

Comments

2

Since Map itself has no a priori knowledge about the values stored in it, except that they are Objects (thus can't be expected to perform any operations on them, other than calling toString(), equals() and/or hashCode()), there is no other way than iterating through its elements and calculating the sum manually.

Comments

2

Multimap sounds like the right choice however, you could do

public static <K, V> int count(Map<K, ? extends Collection<V>> map) {
    int count = 0;
    for (Collection<V> coll : map.values()) count += coll.size();
    return count;
}

BTW: You may want count to return a long ;)

2 Comments

Why ? no one is going to put that many items (2Billion+) into a map
Never say never. Using a long would mean you never need worry about it. ;)
-1

If Any one still looking out for answers

Here is the code posted

    Iterator<Map.Entry<Integer, ArrayList<ShortListedFlats>>> iter = rentShortListedFlats
            .entrySet().iterator();

    while (iter.hasNext()) {
        ArrayList<ShortListedFlats> shortLists = iter.next().getValue();

        counter = counter + shortLists.size();

    }

4 Comments

Answers were already given years ago. Furthermore a foreach loop is way better to read than this manual Iterator approach
I don't see any iterator answers given secondly i calculated the time
Iterators are faster than for each loops for simple reason that they work on entries which hash maps are made of so please think twice before downvoting an answer
A foreach loop uses a iterator: for(Map.Entry<Integer, ArrayList<ShortListedFlats>> entry : rentShortListedFlats.entrySet()) is equivalent but better readable than your code. @Peter Lawrey provided a superiour answer to yours.
-2

Yes, you need a for loop:

public static int countItems(HashMap<String, ArrayList<Item>> yourMap){
    int counter = 0;
    for(ArrayList<Item>> list: yourMap.values()){
        counter += list.size();
    }
    return counter;
}

4 Comments

ArrayList has size() so the second loop is unnecessary
-1 - this solution contains a number of errors. For a start, HashMap does not implement Iterable so the outer for loop is a compilation error.
First thanks for the critics. I just wrote that before I had to change the room and actually didn't test it. Will edit it of course.
more suggestion erikb: You don't need the cast because that's what generic is for. And moreover there is values() method in map

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.