I have a HashMap having key as my own object and key as ArrayList of String. Is there a way to get the key object from the map which is equal to another object without iterating the map. Please note that my object has implemented equals & hashcode. And it only uses 2 attribute of the class to compare. The another object which I am trying to find in the keys of the map has those 2 attribute equal but the other attributes may be different in the key of the map.
//The actual map
private HashMap<FileDetail, ArrayList<String>>开发者_如何学C; map = new HashMap<FileDetail, ArrayList<String>>();
//object to search in above map without iteration.
FileDetail file = some object;
I want to get the reference of the "file" object in the keys of the map.
No you can't do that. HashMap
are supposed to work the other way : you have the key, you're looking for the object.
If you have an object and you want to find the key, there's probably something wrong in your logic and your looking in a wrong direction to solve your problem.
If you don't want to iterate over the keySet, then you can use Guava's BiMap. A biMap has an inverse view which is another bimap containing reversed keys and values. This is how you would use it:
BiMap<FileDetail, ArrayList<String>> biMap = HashBiMap.create();
//object to search in above map without iteration.
FileDetail file = some object;
FileDetail key = biMap.inverse().get(biMap.get(file));
If you really need to do this without iteration over the keySet (e.g. because the map is very large), I suggest storing both the key and the list as values in the map. Either create some specific class encapsulating both, or use a simple pair class. The map would look like:
Map<FileDetail, Pair<FileDetail, List<String>>>
If you can't change the type of the map, you can use a second Map<FileDetail, FileDetail>
where key and value are always the same objects.
This question is five years old, but I had the same question just today, and found this page. I thought I'd share the solution I decided upon using, which is not described in any of the existing answers and avoids iterating over all the keys in the map. (Please be gentle; this is my first posting on SO. It's tough finding questions I can answer that don't already have answers. Moreover, every question I've had to date has already been asked on SO. I've been using SO for years, with no ability to comment or vote on answers.)
As has been stated already, maps are designed so that when you have a key, you look up a value. That being the case, the answer is to use the key also as the value, so that when you perform a lookup using an arbitrary key, which equals
your original key but is not necessarily ==
to it, you get back the original key. The issue then, is how to get what you originally intended to be the value.
My solution depends on having control of the class used for the key, and control of the map, with the ability to redefine them, which appears to be the case for the OP. In the OP's example, this would be control of the FileDetail
class and of the private map
variable. Assuming such control, the FileDetail
class would be modified to contain a member variable of type ArrayList<String>
, which for my sample code below I'll call list
, with associated setter and getter methods. For the private map
variable, it would be defined thusly:
private HashMap<FileDetail, FileDetail> map = new HashMap<>();
Now, when you want to put
a new ArrayList<String>
object in the map, assigned to a specific FileDetail
key, you assign the ArrayList<String>
object to the FileDetail
's ArrayList<String>
member variable instead, and then place the FileDetail
object in the map
.
public void putInMap(FileDetail fd, ArrayList<String> al) {
// Ignoring null conditions for simplicity...
fd.setList(al);
map.put(fd, fd);
}
Later, when you get some arbitrary FileDetail
object (one that equals
the key but isn't necessarily ==
to it), and you want the associated key, it's a matter of doing a normal lookup:
FileDetail otherFd = getArbitraryFileDetail();
FileDetail originalKeyFd = map.get(otherFd);
And to get the associated ArrayList<String>
after having performed the above:
ArrayList<String> al = originalKeyFd.getList();
Certainly this all hinges on the implementations of the equals
and hashCode
methods of the FileDetail
class, but the OP already had those methods defined as desired.
Hope this helps anyone who, like me, comes to this page with a similar situation.
You are likely looking for a Bidirectional Map, Apache Commons Collections includes this as part of the library (im sure there are other imeplementations as well.) A bidirectional map, just as the name implies, is a map but written so as to make looking up by key or by value efficient.
In Java, HashMap
associates a key with a value, not the other way around.
You can retrieve a Set
of all of the keys using HashMap.keySet()
, or alternatively iterate over all of the entries using HashMap.entrySet()
:
for (Entry <FileDetail, ArrayList<String>> entry : map.entrySet()) {
FileDetail key = entry.getKey();
if (shouldProcess(key)) {
ArrayList<String> list = entry.getValue();
processList(list);
}
}
We get the key object from Hashmap without iterating the keyset of HashMap by converting keyset to ArrayList. This is a simple example:
//Creating hashmap
HashMap<String, String> map = new HashMap<String, String>();
//Adding elements into the map
map.put("1", "Amit");
map.put("2", "Ananth");
map.put("3", "Sunil");
//Get the list from keyset
ArrayList myKeyList = new ArrayList(map.keySet());
//object to search in above map without iteration.
String myobj = "3";
System.out.println(myKeyList.get(myKeyList.indexOf(myobj)));
精彩评论