Use List#contains:
if (Server.get(o).contains(value)) {
//...
}
Answer from Luiggi Mendoza on Stack OverflowUse List#contains:
if (Server.get(o).contains(value)) {
//...
}
When you iterate over a Map, if you need both the key and the value it's better to iterate over the entrySet rather than the keySet.
public static String getKeyFromValue(String value) {
for (Map.Entry<String, List<String>> e : Server.entrySet()) {
if (e.getValue().contains(value)) {
return e.getKey();
}
}
return null;
}
This should work, but there are 3 things I don't like about it (apart from Server beginning with a capital letter).
containsfor manyListimplementations (includingArrayListandLinkedList) is slow, because it is a linear search. It may better to useHashSetinstead.- If the
valueoccurs in more than one list in the map, the returned key could be any of multiple answers. It may be better for the name of the method to indicate this (e.g.getAnyKeyForValue). - It may be preferable to return an
Optional<String>rather than usingnullto mean that the value was not found.
A Java 8 solution, taking all of these points into consideration and taking advantage of parallelism would be
public static Optional<String> getAnyKeyForValue(String value) {
return Server.entrySet()
.parallelStream()
.filter(e->e.getValue().contains(value))
.map(Map.Entry::getKey)
.findAny();
}
First remake the List variable to include the types of the map. This will make the .entrySet() return the correct formatting of the entry Map<String,Integer>
List<Map<String, Integer>> items = new ArrayList<>();
for (int i = 0; i < items.size(); i++) {
String key = null;
int value = 0;
for (Map.Entry<String, Integer> entry: items.get(i).entrySet()) {
if (value == (entry.getValue())) {
key = (String) entry.getKey();
break;
}
}
}
You can try this
First add the generic part <String, Integer> to the Map of List as below:
List<Map<String, Integer>> Items= new ArrayList<>();
And then:
for (Map<String, Integer> item : Items) {
for (Map.Entry<String, Integer> entry: items.get(i).entrySet()) {
// do what you want with the entry
}
}
If I understand you correctly, you want to obtain the key given one of the value in the list stored as the corresponding value? Of course, you can always get all these lists using the values() method of the Map interface and then iterate over those. However, how about having a second map where you use your tags as keys and store a list of all the entries carrying this tag? For large data sets, this will probably perform better.
for (Entry<String, List<String>> entry : map.entrySet()) {
if (entry.getValue().contains(animalYouSearch)) {
System.out.println(animalYouSearch + " is in " + entry.getKey());
}
}
Output if you search for "mammal":
mammal is in cat
mammal is in dog
for each entry in map check if values contains you keyword
String value = "ibm";
Optional<String> key = map.entrySet().stream()
.filter(e -> e.getValue().contains(value))
.map(Entry::getKey)
.findFirst();
System.out.println(key.get());
If you'd like to be fancy, you could use Guava's BiMap.
Here's an example taken from baeldung:
@Test
public void givenBiMap_whenQueryByValue_shouldReturnKey() {
BiMap<String, String> capitalCountryBiMap = HashBiMap.create();
capitalCountryBiMap.put("New Delhi", "India");
capitalCountryBiMap.put("Washington, D.C.", "USA");
capitalCountryBiMap.put("Moscow", "Russia");
String keyFromBiMap = capitalCountryBiMap.inverse().get("Russia");
String valueFromBiMap = capitalCountryBiMap.get("Washington, D.C.");
assertEquals("Moscow", keyFromBiMap);
assertEquals("USA", valueFromBiMap);
}
Create a Pair class, that holds both the Integer and the String and then add multiple Pair objects to a List, which will be shuffled.
public class Pair {
private Integer integer;
private String string;
//accessors
}
Then:
List<Pair> list = new ArrayList<Pair>();
//...add some Pair objects to the list
Collections.shuffle(list);
You can keep the Map. The Map is designed to be looked up by key so I suggest you have a list of shuffled keys.
public Map<Integer, String> getQuestionOptionsMap() {
Map<Integer, String> map = new HashMap<>();
String[] answers = {null, answer1, answer2, answer3, answer4};
for (int i = 1; i < answers.length; i++)
if (answers[i] != null)
map.put(i, answers[i]);
List<Integer> order = new ArrayList<>(map.keySet());
Collections.shuffle(order);
Map<Integer, String> shuffled = new LinkedHashMap<>();
for (Integer key : order)
shuffled.put(key, map.get(key));
return shuffled;
}
If your data structure has many-to-one mapping between keys and values you should iterate over entries and pick all suitable keys:
public static <T, E> Set<T> getKeysByValue(Map<T, E> map, E value) {
Set<T> keys = new HashSet<T>();
for (Entry<T, E> entry : map.entrySet()) {
if (Objects.equals(value, entry.getValue())) {
keys.add(entry.getKey());
}
}
return keys;
}
In case of one-to-one relationship, you can return the first matched key:
public static <T, E> T getKeyByValue(Map<T, E> map, E value) {
for (Entry<T, E> entry : map.entrySet()) {
if (Objects.equals(value, entry.getValue())) {
return entry.getKey();
}
}
return null;
}
In Java 8:
public static <T, E> Set<T> getKeysByValue(Map<T, E> map, E value) {
return map.entrySet()
.stream()
.filter(entry -> Objects.equals(entry.getValue(), value))
.map(Map.Entry::getKey)
.collect(Collectors.toSet());
}
Also, for Guava users, BiMap may be useful. For example:
BiMap<Token, Character> tokenToChar =
ImmutableBiMap.of(Token.LEFT_BRACKET, '[', Token.LEFT_PARENTHESIS, '(');
Token token = tokenToChar.inverse().get('(');
Character c = tokenToChar.get(token);
If you choose to use the Commons Collections library instead of the standard Java Collections framework, you can achieve this with ease.
The BidiMap interface in the Collections library is a bi-directional map, allowing you to map a key to a value (like normal maps), and also to map a value to a key, thus allowing you to perform lookups in both directions. Obtaining a key for a value is supported by the getKey() method.
There is a caveat though, bidi maps cannot have multiple values mapped to keys, and hence unless your data set has 1:1 mappings between keys and values, you cannot use bidi maps.
If you want to rely on the Java Collections API, you will have to ensure the 1:1 relationship between keys and values at the time of inserting the value into the map. This is easier said than done.
Once you can ensure that, use the entrySet() method to obtain the set of entries (mappings) in the Map. Once you have obtained the set whose type is Map.Entry, iterate through the entries, comparing the stored value against the expected, and obtain the corresponding key.
Support for bidi maps with generics can be found in Google Guava and the refactored Commons-Collections libraries (the latter is not an Apache project). Thanks to Esko for pointing out the missing generic support in Apache Commons Collections. Using collections with generics makes more maintainable code.
Since version 4.0 the official Apache Commons Collections™ library supports generics.
See the summary page of the "org.apache.commons.collections4.bidimap" package for the list of available implementations of the BidiMap, OrderedBidiMap and SortedBidiMap interfaces that now support Java generics.
This should help.
Map<String, Integer> ohm = new HashMap<String, Integer>();
List<HashMap<String,Integer>> test = new ArrayList<HashMap<String, Integer>>();
ohm.put("one", 1);
ohm.put("two", 2);
test.add((HashMap)ohm);
int number = test.get(0).get("two");
System.out.println(number);
If your HashMap contains, --String, Object-- and NOT --String, Integer-- the following should help.
Map<String, Object> ohm = new HashMap<String, Object>();
List<HashMap<String,Object>> test = new ArrayList<HashMap<String, Object>>();
ohm.put("one", 1);
ohm.put("two", 2);
test.add((HashMap)ohm);
int number = (Integer)test.get(0).get("one");
System.out.println(number);
You have to iterate over your list and look for the map that contains the key I guess:
Object value = null;
for(Map<String,Object> map : test) {
if(map.containsKey("key1")) {
value = map.get("key1");
break;
}
}
You do that :
List list = new ArrayList(map.entrySet());
You could use generics in your list and then iterate on the Entry of the list after your sorted it:
List<Entry<Integer, Integer>> list = new ArrayList(map.entrySet());
...
// your sort the list
..
// you iterate on key-value
for (Entry<Integer, Integer> entry : list){
Integer key = entry.getKey();
Integer value = entry.getValue();
}
Your list actually contains elements of type Map.Entry<Integer, Integer>, so you can retrieve the each Entry as shown below:
Map<Integer, Integer> map = new HashMap<>();
//add the values to map here
//Always prefer to use generic types shown below (instead of raw List)
List<Map.Entry<Integer, Integer>> list = new ArrayList<>(map.entrySet());
Collections.sort(list, new Comparator<Map.Entry<Integer, Integer>>() {
@Override
public int compare(Map.Entry<Integer, Integer> a,
Map.Entry<Integer, Integer> b){
return a.getValue() - b.getValue();
}
});
//loop over the list to retrieve the list elements
for(Map.Entry<Integer, Integer> entry : list) {
System.out.println(entry.getValue());
}