I defined a hashmap as follows
HashMap<String, List<String>> hashmap = new HashMap<String, List<String>>();
I can get its content out by doing
Set<Map.Entry<String, List<String>>> keys = hashmap.entrySet();
for (Map.Entry<String,List<String>> entry : hashmap.entrySet()) {
String key = entry.getKey();
List<String> thing = entry.getValue();
System.out.println (key);
System.out.println (thing);
}
However, I would like to know:
How could I retrieve its content to an ordinary string?
Is it possible to access the strings on the fly? (without doing (1)) I mean, the same way you do string[0], etc
Where is the length of the list stored?
Assuming that String key = "str"; exists in the map. You can:
int mapSize = hashmap.size(); // get the map's size
List<String> list = hashmap.get("str"); // get a list for a key
String first = hashmap.get("str").get(0); // get a string in a list
int listSize = hashmap.get("str").size(); // get the size of a list
char ch = hashmap.get("str").get(0).charAt(0); // get a char of a string in a list in the map
Instead of manually getting the set of keys, how about using the keySet() method on the HashMap object from Java?
Use of keySet() looks like:
Set<String> keys = hashmap.keySet();
For the third bullet, see the size() method.
Related
Is there a data structure in Java where the values in one ArrayList can be used to reference the values in another? For example:
DataStructure<ArrayList<String>, ArrayList<String>> ds = new DataStructure<ArrayList<String>, ArrayList<String>>();
The purpose would be that I could iterate through the data structure later and get both values. For example:
for(int i=0; i<ds.size(); i++) {
String val1 = ds.get(i).getIndex1().getArrayListValueAt(i);
String val2 = ds.get(i).getIndex2().getArrayListValueAt(i);
}
I know this looks odd, but it's hard for me to picture.
P.S. Would it be easier to make sure the indexes are the same in both array lists and just loop through one, and as one is grabbed reference the same index in the other. For instance:
int i = 0;
for(String value : values) {
String val1 = value;
String val2 = list2.get(i);
i++;
}
Thanks.
I think for your purpose, the Map structure would be better suited. It's a dictionary, so one value is the key and the other is its mapped value.
Map<String, String> ds = new HashMap<>();
Then to loop and access the values, you can use its keySet() method like so...
for (String k : ds.keySet()) {
String key = k;
String value = ds.get(k);
}
And to add new key/value pairs to the data structure, you use the put(k, v) method.
ds.put("thisIsAKey", "thisIsTheValue");
Not sure if I understand correctly, it sounds like you wanna have a list which each element in the list would hold pair of values. Would below solution help?
// A class which holds two values...
class MyPair {
String val1;
String val2;
}
// And then you list would be ..
List<MyPair> myList = new ArrayList();
// When you looping your list... it would be like something below
for(MyPair mypair : myList) {
String val1 = mypair.val1;
String val2 = mypair.val2;
}
You can use e.g. Map for your problem, because you can storage all needed collection in one place
Map<String, List<String>> map = new HashMap<>();
or e.g.:
Map<List<String>, List<String>> map = new HashMap<>();
And then you can e.g. String as key and e.g. List<T> as value
Very important thing is which object do you use as key, because it must have equals/hashCode (if is your object it must be #Override) and next, great when this object is immutable
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.
iterate with max key value so that it will replace max string value. first My code is
HashMap<String, String> mapp=new HashMap<String, String>();
mapp.put("ab","blue");
mapp.put("abc","black");
mapp.put("abcd","pink");
for (Iterator it = alltyp.iterator(); it.hasNext();) {
String finalstring = (String) it.next();
Iterator it1=mapp.entrySet().iterator();
while(it1.hasNext())
{
Map.Entry pairs = (Map.Entry) it1.next();
String key_ = (String) pairs.getKey();
String value_ = (String) pairs.getValue();
finalstring = finalstring.replaceAll(key_, value_);
}
}
I want to iterate with max key value means key value "abcd" should iterate first then "abc" then "ab".
Here is an example using Collections.max(). You can also pass a comparator if you want a custom ordering.
HashMap<String, String> mapp=new HashMap<String, String>();
mapp.put("ab","blue");
mapp.put("abc","black");
mapp.put("abcd","pink");
// find max key alphabetically
String maxKey = Collections.max(mapp.keySet());
Comparator<String> strLenCmp = new Comparator<String>() {
#Override
public int compare(String o1, String o2) {
return Integer.compare(o1.length(), o2.length());
}
};
// find max key by key length
String longKey = Collections.max(mapp.keySet(), strLenCmp);
Edit: added example with custom Comparator
Use Generics, get rid of the casting. That will tidy up your code a lot.
You will need a custom comparator to do the sorting.
Once you have the comparator you have two choices:
Option 1:
Create an ArrayList, dump all the keys from the map into it.
Sort the ArrayList, iterate over the sorted ArrayList.
Option 2:
Use a TreeMap to store the data.
Try using the TreeMap instead of HashMap it has the method for getting the last entry which will give you the entry which has the highest value of key. Even in TreeMap if you pass your custom Comparator then it will be sorted in a way that you will get the key with max value first so you don't have to worry about it.
TreeMap - lastEntry
Refer this link, and lastEntry method.
I have following LinkedHashMap declaration.
LinkedHashMap<String, ArrayList<String>> test1
my point is how can i iterate through this hash map.
I want to do this following, for each key get the corresponding arraylist and print the values of the arraylist one by one against the key.
I tried this but get only returns string,
String key = iterator.next().toString();
ArrayList<String> value = (ArrayList<String> )test1.get(key)
for (Map.Entry<String, ArrayList<String>> entry : test1.entrySet()) {
String key = entry.getKey();
ArrayList<String> value = entry.getValue();
// now work with key and value...
}
By the way, you should really declare your variables as the interface type instead, such as Map<String, List<String>>.
I'm assuming you have a typo in your get statement and that it should be test1.get(key). If so, I'm not sure why it is not returning an ArrayList unless you are not putting in the correct type in the map in the first place.
This should work:
// populate the map
Map<String, List<String>> test1 = new LinkedHashMap<String, List<String>>();
test1.put("key1", new ArrayList<String>());
test1.put("key2", new ArrayList<String>());
// loop over the set using an entry set
for( Map.Entry<String,List<String>> entry : test1.entrySet()){
String key = entry.getKey();
List<String>value = entry.getValue();
// ...
}
or you can use
// second alternative - loop over the keys and get the value per key
for( String key : test1.keySet() ){
List<String>value = test1.get(key);
// ...
}
You should use the interface names when declaring your vars (and in your generic params) unless you have a very specific reason why you are defining using the implementation.
In Java 8:
Map<String, List<String>> test1 = new LinkedHashMap<String, List<String>>();
test1.forEach((key,value) -> {
System.out.println(key + " -> " + value);
});
You can use the entry set and iterate over the entries which allows you to access both, key and value, directly.
for (Entry<String, ArrayList<String>> entry : test1.entrySet()) {
System.out.println(entry.getKey() + "/" + entry.getValue());
}
I tried this but get only returns string
Why do you think so? The method get returns the type E for which the generic type parameter was chosen, in your case ArrayList<String>.
// iterate over the map
for(Entry<String, ArrayList<String>> entry : test1.entrySet()){
// iterate over each entry
for(String item : entry.getValue()){
// print the map's key with each value in the ArrayList
System.out.println(entry.getKey() + ": " + item);
}
}
I have a Hashtable in Java and want to iterate over all the values in the table and delete a particular key-value pair while iterating.
How may this be done?
You need to use an explicit java.util.Iterator to iterate over the Map's entry set rather than being able to use the enhanced For-loop syntax available in Java 6. The following example iterates over a Map of Integer, String pairs, removing any entry whose Integer key is null or equals 0.
Map<Integer, String> map = ...
Iterator<Map.Entry<Integer, String>> it = map.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<Integer, String> entry = it.next();
// Remove entry if key is null or equals 0.
if (entry.getKey() == null || entry.getKey() == 0) {
it.remove();
}
}
You can use Enumeration:
Hashtable<Integer, String> table = ...
Enumeration<Integer> enumKey = table.keys();
while(enumKey.hasMoreElements()) {
Integer key = enumKey.nextElement();
String val = table.get(key);
if(key==0 && val.equals("0"))
table.remove(key);
}
You can use a temporary deletion list:
List<String> keyList = new ArrayList<String>;
for(Map.Entry<String,String> entry : hashTable){
if(entry.getValue().equals("delete")) // replace with your own check
keyList.add(entry.getKey());
}
for(String key : keyList){
hashTable.remove(key);
}
You can find more information about Hashtable methods in the Java API
So you know the key, value pair that you want to delete in advance? It's just much clearer to do this, then:
table.delete(key);
for (K key: table.keySet()) {
// do whatever you need to do with the rest of the keys
}