public static HashMap<ArrayList<Integer>, String> map = new HashMap<ArrayList<Integer>, String>();
public static ArrayList<ArrayList<Integer>> keys = new ArrayList<>(map.keySet());
Then in main
map.put(key, "c");
(assume key is a valid ArrayList). But keys still has size 0 after that.
How can I make the relationship of keys stronger so that it will be actually tied to the HashMap and contain all its keys.
The copy constructor of ArrayList copies all the keys in the map to the ArrayList but if you change the map after that point it will not be reflected.
I can think of 3 options:
write your own map implementation that embeds an ArrayList and keeps it up to date
update the ArrayList manually everytime you update the map
don't use an ArrayList at all (keySet() is there when you need to access the keys so I'm not sure why you would need one)
You can't.
Map.keySet() returns the Map's current key set, which you then load into your list. Changes to the map after that have no effect on the contents of the list.
Most people would just re-get the key set if needed. Why don't you just do that?
Related
Is it a good practice to have a map key depending on value?
e.g.:
class MyClass {
private String key;
private Object value;
}
And then:
Map<String, MyClass> map = new LinkedHashMap<String, MyClass>();
MyClass a = new MyClass("key1", valueObject);
map.put(a.getKey(), a);
Is it ok? I am forced to have such a class as value, I thought about using Set but I need to get item based on index (geting by keySet index) and key (where values key == maps key). I also need fixed size with possibility of removing oldest element from this collection.
I think i should ensure that my key and values key field will be always the same. How can i achieve it?
Having the keys in the value entities is totally fine, this is how every database creates indices. A good practice would be to have MyClass to be immutable and wrap the whole thing in a new collection class hiding details and preventing inserting values to the wrong keys. This is the way to ensure that key == value.key
Your map store redundant data(double key).
You can put MyClass.key as map's key and MyClass.value as map's value into the map.
As you can see here a Map maps a key to its value.
So your attempt is a bit redundant, as long as you don't need the key for further operations inside MyClass.
Is there any way to replace a key using put() in a LinkedHashMap without losing the order that the key was originally inserted in?
You do not lose the order when putting a different value for the same key.
Example
Map<String, String> map = new LinkedHashMap<String, String>();
map.put("foo", "bar");
map.put("blah", "baz");
System.out.println(map);
map.put("foo", "foo");
System.out.println(map);
Output
{foo=bar, blah=baz}
{foo=foo, blah=baz}
Edit
"Replacing" a key for a given value would imply removing the key value pair, then putting the new key with the stored value.
As such, there is no direct way to do this with a LinkedHashMap, probably not even by inheriting and changing the behavior of remove and put.
If you used the LinkedHashMap, I don't think there is built-in method to achieve your goal. You may want to pick another (or design your own) data-structure.
If you have to do it on a linkedhashmap, you can create a new LinkedHashMap, iterate the old one and put into the new one, when your target entry comes, create a new entry with different key, put the new entry into the map.
In my code I am using a set of interleaved LinkedHashMaps inside each other as below. The code is fine and gives me the result I want except it automatically removes the duplicates. I couldnt find out how I can use TreeMap or Set in order to keep the duplicates.
LinkedHashMap<String, LinkedHashMap<Integer, LinkedHashMap<String, Vector<String>>>>
dataAll =new LinkedHashMap<String, LinkedHashMap<Integer, LinkedHashMap<String,
Vector<String>>>>();
LinkedHashMap is still a Map data structure. It maps a unique key to a value. If you assign two different values to a key the second value will simply replace the first value assigned to that key.
Also imagine why do you need a Map of duplicated key? The sole purpose of Map is to provide a one to one relationship between key/value pair. It does not handle one to many relationship.
If you have to map a key with a list of values, use something like:
LinkedHashMap<String, List<..>>
This allows you to have one key maps to a list of values.
Initially I put two entries with the same value into a hashmap. The value of the two entries is itself a map. These entries have different keys.
Now I want to put new values into the map (the value) of the first entry. The problem is that the map of the second entry (its value) is also changed as long as I change the first one. The two different keys somehow reference the same value (map).
What should I do in order to edit the values of the initially identical values separately from each other?
Basically, the issue is that you did not put two maps into your map, but rather put two references to the same map.
To have two independent versions of the inner map in the outer one, you need to make a copy of it before putting it in a second time.
You should be able to make a copy of a HashMap using its clone method. Note that while this does get you two different maps, the actual values in the two maps are the same. This means that if the copied map's contents are mutable and you change them, they will still change in both places.
To clarify:
HashMap<Object, Object> map1 = new HashMap<Object, Object>()// This is your original map.
map1.put("key", mutableObject)
HashMap<Object, Object> map2 = map1.clone();
map2.put("something", "something else");// map1 is unchanged
map2.get("key").change();// the mutable object is changed in both maps.
Good catch on putting the same reference under different keys. However for solving I wouldn't use clone method and rather would use explicit copying:
package com.au.psiu;
import java.util.HashMap;
import java.util.Map;
public class NoIdea {
public static void main(String... args) {
Map source = new HashMap();
//Insert value into source
Map copy1 = new HashMap();
copy1.putAll(source);
Map copy2 = new HashMap();
copy2.putAll(source);
Map mapOfMaps = new HashMap();
mapOfMaps.put("key1", copy1);
mapOfMaps.put("key2", copy2);
//...and you can update maps separately
}
}
Also you might want to take a look into google guava project - they have a lot useful APIs for collections.
What I'm doing is storing classes into an ArrayList and retrieve them by its index number. But are there any list classes in Java where I can retrieve a list element by, lets say, its name? Like this:
ArrayList<string> myArr = new ArrayList<string>();
myArr.add( "ID_name", "String to store" );
ands then retrieve it by:
myArr.get( "ID_name" );
Also, are there any other alternatives to ArrayList? I need a list class to be optimized for:
Random access
Only need to push items into the list
Never need to delete anything from the list
If all you want to store is key-value pairs, and don't care about iteration order, I think you might like the HashMap class:
Map<String, String> map = new HashMap<String, String>();
map.put("foo", "bar");
String bar = map.get("foo"); // bar is "bar"
You can use LinkedHashMap, so it will preserve the order, but you can extract elements by key as in regular map. Though you won't be able to extract entries by index.
An ArrayList is just that: an array. If you want to access values by something else than their indices, look for the various implementations of the Map interface (such as HashMap).
Use a Map<String, String>. In such structure, an element is added with a key. So you can get the element through the key:
Map<String, String> map = new HashMap<String, String>();
map.put("id", "string");
String s = map.get("id"); // s will be equals to "string".
As the other people have mentioned, a HashMap is probably what you want if you don't care about iteration order.
If you do, you can use a LinkedHashMap, which is really a HashMap bolted onto an LinkedList, giving you the best of both worlds: fast random access and preservation of iteration order.
Use a hashmap. You can add elements to a hashmap in much the same way as an arraylist. Also, you can create a set of keys ( 1 elements in the set per (key, value) pair)). You can then iterate over the set of keys.