9

I have a Hashmap of type

Map<String, List<String>> adminErrorMap = new HashMap<>();

I want to be able to iterate thru the entire hashmap and get all the values to a single List<String>. The Keys are irrelevant.

I have done something like this:

List<String> adminValues = new ArrayList<>();

for (Map.Entry<String, List<String>> entry : adminErrorMap.entrySet()) {                
         adminValues.add(entry.getValue().toString());
    }
System.out.println(adminValues);

Output

[[{description=File Path, value=PurchaseOrder.plsql}, {description=Component, value=PURCH}, {description=Commit Date, value=Thu May 05 00:32:01 IST 2016}],[{description=File Path, value=CustomerOrder.plsql}, {description=Component, value=COMP}, {description=Commit Date, value=Thu June 05 00:32:01 IST 2016}]]

As you can see, there are [] inside a main [].

How to have all values inside one []. Like shown below;

Or is there any other way to implement this?

[{description=File Path, value=PurchaseOrder.plsql}, {description=Component, value=PURCH}, {description=Commit Date, value=Thu May 05 00:32:01 IST 2016},{description=File Path, value=CustomerOrder.plsql}, {description=Component, value=COMP}, {description=Commit Date, value=Thu June 05 00:32:01 IST 2016}]

wishman
  • 774
  • 4
  • 14
  • 31

6 Answers6

11

Use addAll instead of add, in order to add all the Strings of all the List<String>s to a single List<String> :

for (List<String> value : adminErrorMap.values())   
{                
     adminValues.addAll(value);
}
Eran
  • 387,369
  • 54
  • 702
  • 768
  • I think this code is incorrect. It seems none of the up-voters for this answer noticed that `adminValues` is a container for `String` objects, *not* a container for `List`, i.e. the declaration is not `List< List > adminValues` – code_dredd May 05 '16 at 06:37
  • @ray It is correct. addAll accepts a Collection and adds all the elements of that Collection to the List. Therefore, you call `adminValues.addAll(value);` to add all the Strings of the `value` List to the output `List`. – Eran May 05 '16 at 06:40
  • Maybe it's because I'm up late, but `adminValues` is expecting `String`s to be added, yet the `value` variable is not a `String`, it's a `List`, which is what makes this look odd to me. – code_dredd May 05 '16 at 06:49
  • @ray Note that I'm using addAll, not add. addAll expects a Collection of the same element type as the List to which you are adding the elements. Therefore you can call `addAll` for a `List` and pass to it another `List`. – Eran May 05 '16 at 06:51
  • @ray Here's [the JavaDoc for same](https://docs.oracle.com/javase/7/docs/api/java/util/List.html#addAll(java.util.Collection)) – anotherdave May 05 '16 at 06:55
  • Very well. I'll go take my pills now -_- – code_dredd May 05 '16 at 06:55
9

In Java8, you can use functional to do that:

adminErrorMap.values().forEach(adminValues::addAll);
chengpohi
  • 14,064
  • 1
  • 24
  • 42
8

A simple way would be:

new ArrayList<>(map.values());

For JDK 8 and above this can also be done as:

map.values().stream().collect(Collectors.toList());
Saikat
  • 14,222
  • 20
  • 104
  • 125
4

You just need to flatten the collection. In Java8:

    final Map<String, List<String>> adminErrorMap = ImmutableMap.of(
            "a", Lists.newArrayList("first", "second"),
            "b", Lists.newArrayList("third")
    );

    final List<String> results = adminErrorMap.values().stream()
            .flatMap(Collection::stream)
            .collect(Collectors.toList());

    results.forEach(System.out::println);

It prints:

first
second
third
g-t
  • 1,455
  • 12
  • 17
1

There seems to be an issue in your declaration types:

Map<String, List<String>> adminErrorMap = new HashMap<>();
List<String> adminValues = new ArrayList<>();

Your adminValues is expecting String objects to be added, but you're trying to add objects of type List<String> into it:

for (Map.Entry<String, List<String>> entry : adminErrorMap.entrySet())               
    adminValues.add(entry.getValue().toString());

The entry.getValue(), based on the declaration of adminErrorMap, does not return an object of type String. Instead, it returns another List<String>, which is not at all what's expected. You're simply calling toString() on that List<String> object, which is probably not what you really wanted to do.

Since you can't put a List<String>-typed object into a container that is expecting String-typed objects, you should be using entry.getKey() instead:

adminValues.add(entry.getKey());

Perhaps the following might be more useful, if I recall my Java correctly:

for (String key : adminErrorMap.keySet())
    adminValues.add(key);

Edit for this comment:

i want only the Values of all keys

Since each key can have multiple values associated with it, given that they're of type List<String>, then you should consider something closer what Eran proposed:

for (List<String> values : adminErrorMap.values())               
    adminValues.addAll(values);
Community
  • 1
  • 1
code_dredd
  • 5,915
  • 1
  • 25
  • 53
1

Why aint we doing this

Map<String, List<String>> mapKeyList = new HashMap<String, List<String>>();
List<String> finalList = new ArrayList<String>();

        Iterator it = mapKeyList.entrySet().iterator();

        while(it.hasNext()){
            Map.Entry pair = (Map.Entry)it.next();
            List<String> strList = (List<String>) pair.getValue();

            Iterator<String> strIt= strList.iterator();
            while(strIt.hasNext()){
                String str = strIt.next();
                finalList.add(str);
            }

        }

I know complexity is going to be in order of n*n but we are getting the expecting output.

viveksinghggits
  • 661
  • 14
  • 35