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}]

6
  • 2
    Shouldn't it be adminValues.add(entry.getKey()); or something like that? You can't put a List<String> into a container that's expecting a String Commented May 5, 2016 at 6:19
  • That's if i want the keys. But i want only the Values of all keys Commented May 5, 2016 at 6:20
  • 1
    Then why do you declare adminValues as being of type List<String> instead of List< List<String> >? Commented May 5, 2016 at 6:21
  • Ah ha! I see you got a point there! thanks :) Commented May 5, 2016 at 6:22
  • 1
    I'll be posting my comment as an answer if it works for you then Commented May 5, 2016 at 6:23

6 Answers 6

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); } 
Sign up to request clarification or add additional context in comments.

6 Comments

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<String>, i.e. the declaration is not List< List<String> > adminValues
@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<String>.
Maybe it's because I'm up late, but adminValues is expecting Strings to be added, yet the value variable is not a String, it's a List<String>, which is what makes this look odd to me.
@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<String> and pass to it another List<String>.
|
9

In Java8, you can use functional to do that:

adminErrorMap.values().forEach(adminValues::addAll); 

Comments

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()); 

Comments

5

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 

Comments

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); 

Comments

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.

3 Comments

Your code is much too long. Since Java 1.5, the Iterator class is only used in very special situations, and this isn’t one of them.
This code is unnecessarily long/verbose for what's actually needed, and its time complexity is not great either.
but if we are getting the expected output then its ok to go with this code, I think..

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.