I have question why I can't get this values
HashMap<String, P> users = new HashMap<String, P>();
users.put("john", new P("john"));
List<String> arenaUsers = new ArrayList<String>();
arenaUsers.add("john");
for (String user : arenaUsers) {
for (P p : users.get(user)) {
System.out.println(p.getName());
}
}
I got error:
Can only iterate over an array or an instance of java.lang.Iterable
But I can't iterate Map, How I can fix it?
here you class p does not implement Iterable so it can't be used inside the for loop. So to use it inside for loop you need to implement Iterable or use an existing collection which have already implemented Iterable i.e.
Map<String, List<String>> map = new HashMap<String, List<String>>();
List<String> l =new ArrayList<String>();l.add("stack");l.add("overflow");
map.put("trying", l);
for(String ss: map.get("trying")){
System.out.println(ss);
}
Here i have used List which implements Iterable and can be used in side the for loop.
In Map for one key you will get only one value, thats the cause of
"Can only iterate over an array or an instance of java.lang.Iterable"
this happens in the second for loop, which is useless as its only one value
for (P p : users.get(user))
Instead do as:
for (String user : arenaUsers) {
if(users.containsKey(user))
System.out.println(users.get(user).getName());
}
}
Related
I'm having issues sorting out the ArrayList found inside of the hashmap, or treemap. the goal is to have the program print out the key, along with the sorted arraylist. I tried using Collections, but it didnt work, any help is welcome :)
public static void main(String[] args) {
ArrayList<StudentCourse> List = new ArrayList<StudentCourse>();
List.add(new StudentCourse(2, "MATH210"));
List.add(new StudentCourse(2, "CS105"));
List.add(new StudentCourse(1, "S300"));
List.add(new StudentCourse(1, "CS200"));
HashMap<Integer, ArrayList<String>> HMap = new HashMap<>();
for (StudentCourse st : List) {
if (HMap.containsKey(st.getStudentID())) {
HMap.get(st.getStudentID()).add(st.getCourse());
} else {
HMap.put(st.getStudentID(), new ArrayList<>());
HMap.get(st.getStudentID()).add(st.getCourse());
}
}
Collections.sort(List);//this leads to an error.
Map<Integer, ArrayList<String>> TrMap = new TreeMap<Integer, ArrayList<String>>(HMap);
System.out.println(TrMap.toString());
}
the output is this :
{1=[S300, CS200], 2=[MATH210, CS105]}
while the intent is to have the the arraylist sorted,
so:
1=[cS200, S300], 2=[CS105, MATH210]
There is really not much to it. You just iterate all value entries and call some sort algorithm on it. For example the one provided by the Collections#sort (documentation) method. The method sorts inline so you don't have to re-add the values or anything, just call the method and your value entry will be sorted:
Probably the shortest code to realize this is
map.values().forEach(Collections::sort);
The values method returns a Set of all your values in the map. The forEach applies the given method to all entries.
If you are more familiar with regular loops:
for (ArrayList<String> value : map.values()) {
Collections.sort(value);
}
The approach you have posted in your comments works too:
for (Entry<Integer, ArrayList<String>> entry : map.entrySet()) {
Collections.sort(entry.getValue());
}
but it is unnecessary to pull the whole Entry (with key) out of the map, you only need the values. So consider using the map#values method instead of the map#entrySet.
I have written this:
HashMap<String, String> map1 = new HashMap<String, String>();
Map<String, ArrayList<String>> map2 = new HashMap<String, ArrayList<String>>();
i am trying to allow more then 1 value for each key in a hashmap. so if the first key is '1', i want to allow '1' to be paired with values '2' and '3'.
so it be like:
1 --> 2
|--> 3
but when I do:
map2.put(key, value);
it gives error that says "incompatible types" and it can not be converted to ArrayList and it says the error is at the value part of the line.
If you are using Java 8, you can do this quite easily:
String key = "someKey";
String value1 = "someValue1";
String value2 = "someValue2";
Map<String, List<String>> map2 = new HashMap<>();
map2.computeIfAbsent(key, k -> new ArrayList<>()).add(value1);
map2.computeIfAbsent(key, k -> new ArrayList<>()).add(value2);
System.out.println(map2);
The documentation for Map.computeIfAbsent(...) has pretty much this example.
In map2 you need to add ArrayList (you declared it as Map<String, ArrayList<String>> - the second one is the value type) only, that's why it gives you incompatible types.
You would need to do initialize the key with an ArrayList and add objects to it later:
if (!map2.containsKey(key)) {
map2.put(key, new ArrayList<String>());
}
map2.get(key).add(value);
Or you could use Multimap from guava, then you can just map2.put and it won't overwrite your values there but add to a list.
You are little bit away from what you are trying to do.
Map<String, ArrayList<String>> map2 = new HashMap<String, ArrayList<String>>();
this will allow only String as key and an ArrayList as value. So you have to try something like:
ArrayList<String> value=new ArrayList<String>();
value.add("2");
value.add("3");
map2.put("1", value);
When retrieving you also have to follow ans opposite procedure.
ArrayList<String> valueTemp=map2.get("1");
then you can iterate over this ArrayList to get those values ("2" and "3");
Try like this. //use list or set.. but set avoids duplicates
Map<String, Set<String>> map = new HashMap<>();
Set<String> list = new HashSet<>();
// add value to the map
Boolean b = map.containsKey(key);
if (b) {
map.get(key).addAll(list);
} else
map.put(key, list);
}
You can not add different values in same key in Map. Map is override the value in that key. You can do like this way.
Map<String, ArrayList<String>> map = new HashMap<String, ArrayList<String>>();
ArrayList<String> list=new ArrayList<String>();
list.add("2");
list.add("3");
map.put("1", list);
first add value in array list then put into map.
It is all because standard Map implementations in java stores only single pairs (oneKey, oneValue). The only way to store multiple values for a particular key in a java standard Map is to store "collection" as value, then you need to access this collection (from Map) by key, and then use this collection "value" as regular collection, in your example as ArrayList. So you do not put something directly by map.put (except from creating the empty collection), instead you take the whole collection by key and use this collection.
You need something like Multimap, for example:
public class Multimap<T,S> {
Map<T, ArrayList<S>> map2 = new HashMap<T, ArrayList<S>>();
public void add(T key, S value) {
ArrayList<T> currentValuesForGivenKey = get(key);
if (currentValuesForGivenKey == null) {
currentValuesForGivenKey = new ArrayList<T>();
map2.get(key, currentValuesForGivenKey);
}
currentValuesForGivenKey.add(value);
}
public ArrayList<S> get(T key) {
ArrayList<String> currentValuesForGivenKey = map2.get(key);
if (currentValuesForGivenKey == null) {
currentValuesForGivenKey = new ArrayList<S>();
map2.get(key, currentValuesForGivenKey);
}
return currentValuesForGivenKey;
}
}
then you can use it like this:
Multimap<String,String> map2 = new Multimap<String,String>();
map2.add("1","2");
map2.add("1","3");
map2.add("1","4");
for (String value: map2.get("1")) {
System.out.println(value);
}
will print:
2
3
4
it gives error that says "incompatible types" and it can not be converted to ArrayList and it says the error is at the value part of the line.
because, it won't automatically convert to ArrayList.
You should add both the values to list and then put that list in map.
I am trying to get subList from List<Object> this way,
My actual map data before doing sublist is this way,
Converted Map{Demography=[[D11,D22,D99]], Paper=[[[EEE,RRR,TTT],[QQQ,WWW,EEE],[UUU,III,OOO]]], Hunt=[[HUT,HUG,HUE]], Camp=[[COL,CIL,CPL]]
and my code is this,
public class PosTest {
HashMap<String, Object> uiMap = new HashMap<String, Object>();
public static void main(String[] args) {
PosTest mm = new PosTest();
mm.getSupplierInfo();
}
public void getSupplierInfo()
{
HashMap<String, Object> jsonMap = new HashMap<String, Object>();
jsonMap.put("Camp","[COL,CIL,CPL]");
jsonMap.put("Demography","[D11,D22,D99]");
jsonMap.put("Hunt","[HUT,HUG,HUE]");
jsonMap.put("Paper","[[EEE,RRR,TTT],[QQQ,WWW,EEE],[UUU,III,OOO]]");
Iterator<Entry<String, Object>> i = jsonMap.entrySet().iterator();
Entry<String, Object> e = null;
List<Object> eValue = null;
while (i.hasNext()) {
e = i.next();
eValue = Arrays.asList(e.getValue());
uiMap.put(e.getKey(), eValue.subList(0, 1));
}
System.out.println("Converted Map" + uiMap);
}
}
Then when i call uiMap.put(e.getKey(), eValue.subList(0, 1)); i should get only 0,1 of values from list, i.e,
Converted Map{Demography=[D11,D22], Paper=[[EEE,RRR,TTT],[QQQ,WWW,EEE]], Hunt=[HUT,HUG]], Camp=[COL,CIL]}
But My output from that code is Converted Map{Demography=[[D11,D22,D99]], Paper=[[[EEE,RRR,TTT],[QQQ,WWW,EEE],[UUU,III,OOO]]], Hunt=[[HUT,HUG,HUE]], Camp=[[COL,CIL,CPL]]}
Why all the list values are returned without sublist (0,1) and also one extra brace is added?
Can anyone help me in this issue?
Are you assuming that Java can interpret "[COL,CIL,CPL]" as a list? It cannot. It’s one object of type String.
When you call Arrays.asList(), because of varargs, Java produces first an array of one String element, then asList() converts that into a list of one element. The subList(0, 1) of this list is the same list. This is why you get the same thing out as you put in.
By this:
jsonMap.put("Hunt","[HUT,HUG,HUE]");
you don't put a list as a value, you put the only string. And this:
eValue = Arrays.asList(e.getValue());
doesn't magically parse "[COL,CIL,CPL]" to a list, it just creates one-item list containing that single string, which subList(0, 1) returns itself (as it has only one item).
So, first change the type of jsonMap to Map<String, List<String>>, and put items by:
jsonMap.put("Hunt", Arrays.asList("HUT", "HUG", "HUE"));
jsonMap.put("Hunt", Arrays.asList("D11", "D22", "D99"));
//...
then, to get a sublist, call:
uiMap.put(key, jsonMap.get(key).subList(0, 1));
NavigableMap<String, String> map; // this map contains e.g. 10 elements
MyObject foo = new MyObject("string as 1st parameter", "and as 2nd parameter");
Now I want to do something like this:
List<MyObject> objects = new ArrayList<>();
objects.addAll(forEach(map) {new MyObject(map.key, map.value)});
I know, I could iterate over the map:
for (String key : map.keySet()) {
objects.add(new MyObject(key, map.get(key)));
}
My question is, whether this is possible in some other more funky way :) (within JAVA 7)
If I have a type
ArrayList<HashMap<String,String>> keys = functionWhichReturnsThisType();
How can I iterate through so that I end up with all <1st string of hashmap> in a string array and likewise <2nd string of hashmap> into another string array.
I have tried to use the iterator but the hierarchy in the data type is confusing me.
appPrefs = new AppPreferences(context.getApplicationContext());
ArrayList<HashMap<String,String>> keys = appPrefs.getDownloadUrls();
ArrayList<String> urls = new ArrayList<String>();
ArrayList<String> filenames = new ArrayList<String>();
Iterator myIterator = keys.keySet().iterator();
while(myIterator.hasNext()) {
urls.add((String)myIterator.next());
filenames.add((String)keys.get(myIterator.next()));
}
If the order doesn't matter, you can try
for (HashMap<String, String> map : keys) {
urls.addAll(map.keys());
filenames.addAll(map.values());
}
If you want to keep the order, you can try
for (HashMap<String, String> map : keys) {
for (Map.Entry<String, String> entry : map.entrySet()) {
urls.add(entry.getKey());
filenames.add(entry.getValue());
}
}
OK, I'll walk through your sample code and show where you're running into issues, and suggest how you can get it to work.
ArrayList<HashMap<String,String>> keys = appPrefs.getDownloadUrls();
This (above) is fine - but remember keys is an ArrayList. It's a list of HashMap objects, but it's still a list
ArrayList<String> urls = new ArrayList<String>();
ArrayList<String> filenames = new ArrayList<String>();
These are good, but in typical Java, it would be better to have List<String> urls = new ArrayList<String>(); to try and keep your variables using interfaces instead of concrete implementations.
Iterator myIterator = keys.keySet().iterator();
while(myIterator.hasNext()) {
This won't work, because keys is an ArrayList, and a list does not have a keySet() you want to do:
Iterator<HashMap<String,String> listIterator = keys.iterator();
while(listIterator.hasNext()) {
HashMap<String,String> map = listIterator.next();
Iterator<String> myIterator = map.keySet().iterator();
while(myIterator.hasNext()) {
Or, even better would be to use the Java 1.5 for(each) loop:
for( Map<String,String> map : keys ) {
for( String url : map.keySet() ) {
--
urls.add((String)myIterator.next());
The above would work, once you get myIterator to be an iterator over the map, rather than the list.
filenames.add((String)keys.get(myIterator.next()));
But this won't for 2 reasons
Because keys is still a list.
If you call next on an iterator twice then you get 2 different objects.
You need to have:
String url = myIterator.next();
urls.add(url);
filenames.add(map.get(url));
Or, if you use the for(each) loop I suggested above, then you can skip that first line.
Hope that helps - if something's unclear please add a comment.
Note: solilo's solution is a lot simpler and is a good way to do it, my answer is here to help you see where you were running into trouble.
This method will work for you extract first and second strings
private void getFirstAndSecondStrings(ArrayList<HashMap<String,String>> keys){
ArrayList<String> firstStrings = new ArrayList<String>();
ArrayList<String> secondStrings = new ArrayList<String>();
for (HashMap<String, String> map : keys) {
Iterator iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry pairs = (Map.Entry)iterator.next();
firstStrings.add((String)pairs.getValue());
secondStrings.add((String)pairs.getKey());
}
}
}