Return a value from Map - java

I have Map in Java
Map<String, List<String>> Collections;
String - a parents to ExpandtableList
List -a children to Expandtable List
Example Values
<"12" , "5,6,7,8">
<"15" , "4,6,2,8">
<"17" , "1,6,7,8">
<"8" , "5,6,6,8">
I'd like to get second parent and atribute to temporary String variable.(it is a "17") How can i refer to 2-nd parent and return value ?

There is no ordering in HashMap. If you want to focused on Order with Map you should use LinkedHashMap.

Use LinkedHashMap instead of HashSet. LinkedHashMap will maintain the insertion order.

Well, if you want "17" then you can just write map.get("17") to get the List.
Java doesnt keep track of the order here as it uses a Set to store the data. map.keySet() will return you a set you can iterate through.
You can HOPE that 17 falls under the natural ordering that Java does and do something like this.
HashMap<String, List<String>> map = new HashMap<>();
int count = 0;
for (String key : map.keySet()) {
count++;
if (count == 2)
return map.get(key);
}

If you want to retain an order in a Map, your usual choice would be a LinkedHashMap. With a linked hash map, you do however still not have direct access to an entry by its index. You would need to write a helper function:
static List<String> indexList(LinkedHashMap<String, List<String>> map, int index) {
int i = 0;
for(Map.Entry<String, List<String>> entry : map.entrySet()) {
if(i++ == index) {
return entry.getValue();
}
}
throw new IndexOutOfBoundException();
}
When using maps that point to a list, you might also be interested in using Guava's Multimap.

Related

How we can Sort ArryMap in Android

I am using ArrayMap in my Activity for storing my response.
ArrayMap<String, PublicSpotData> publicSpotData ArrayMap will store index as well as key-value pair. Now I have problem in sorting ArrayMap. I want to sort ArrayMap according to publicSpotData.getAt() (int).
I have already done this.
List<Map.Entry<String, PublicSpotData>> entries = new ArrayList<>();
for (Map.Entry<String, PublicSpotData> entry : publicSpotData.entrySet()) {
entries.add(entry);
}
Collections.sort(entries, new Comparator<Map.Entry<String, PublicSpotData>>() {
#Override
public int compare(Map.Entry<String, PublicSpotData> o1, Map.Entry<String, PublicSpotData> o2) {
return o2.getValue().getAt().compareTo(o1.getValue().getAt());
}
});
for (Map.Entry<String, PublicSpotData> entry : entries)
publicSpotData.put(entry.getKey(), entry.getValue());`
But this not solved my issue.
Any help would be appreciated.
you can use Collections#sort method
Collections.sort(new ArrayList<>(c), aComparator);
c is just a key set from the ArrayMap
and aComparator is a custom implemetation of comparator to sort the elemets in the map
You can sort any Java collection by providing a Comparator.
In other words: you have to create a class that knows how to compare two PublicSpotData objects; and then you use that with Collections.sort().
Meaning: as long as your "incoming" object implements one of the Java collection interfaces (and the Android ArrayMap is a Map, which is a collection); you can sort it using the default means of the java library.
But then, the problem is more complicated: you can only sort Lists. And your input data ... is represented as Map. So, lets go step by step:
List<PublicSpotData> dataObjects = ... coming from somewhere
Collections.sort(dataObjects, new Comparator<PublicSpotData>() { ...
here you put the comparator for that thing);
Now you got a list that is sorted for that criteria.
In that sense: the real problem is that your model doesn't support your needs. The essence of a Map is to provide that mapping functionality.
You need to:
extract a list of data objects
sort those
iterate the sorted list; and for each entry ... find the corresponding map key!
Firstly ArrayMap implements sorting implicitly for keys.
Baseline: You need to iterate the arrayMap to obtain Key by index. then call value by that key.
Here is an example of that. I list sorted outputs from unsorted inputs. then I sort the sort the keySet reversely.
ArrayMap<String, String> arrayMap = new ArrayMap<>();
arrayMap.put("AAA7", "BBB2");
arrayMap.put("AAA8", "BBB1");
arrayMap.put("AAA9", "BBB");
arrayMap.put("AAA9", "BBB");// will override previous call
String res = "";
for (int i = 0; i < arrayMap.size(); i++) {
String key = arrayMap.keyAt(i);
res += arrayMap.get(key) + ", ";
}
Log.d(TAG, "normal output: " + res);
// sorting array based on keys
List<String> list = new ArrayList<>(arrayMap.keySet());
java.util.Collections.reverse(list);//or you implement your own sort
String res2 = "";
for (String key : list) {
res2 += arrayMap.get(key) + ", ";
}
Log.d(TAG, "output of sorted collection in reverse based on keys: " + res2);
For more efficiency, you might use SimpleArrayMap if you don't need standard Java API like Iteration.

Merge duplicates in list

I have a list of some strings. I need to merge dublicates and add counter of duplicates. For example:
list1.add("Mom");
list1.add("Mom");
list1.add("Son");
list1.add("Son");
list1.add("Dad");
list1.add("Dad");
merge and add counter
and output needs to be like this:
Mom 2
Son 2
Dad 2
Also I need to sort this new list, but I think I can just use collections, to do that.
public static Map<String, Long> getValuesWithNumberOfOccurrences(
List<String> list) {
return list.stream()
.collect(
Collectors.groupingBy(i -> i, HashMap::new,
Collectors.counting()));
}
Use HashMap to keep duplicates:
HashMap<String, Integer> map = new HashMap<>();
for (int i = 0; i < list.size(); i++) {
String text = list.get(i);
if(map.get(text) == null) {
map.put(text, 1);
} else {
map.put(text, map.get(text) + 1);
}
}
for (String text : map.keySet()) {
System.out.println(text + " " + map.get(text));
}
I'm assuming that the output order needs to respect the order in which the keys were first encountered. Fortunately the clever Java bods designed an object for that: java.util.LinkedHashMap.
To set up your storage object use
java.util.Map<String, Integer> map = new java.util.LinkedHashMap<>()
Note the fancy diamond notation.
Then, with name as a string, write something like
if (map.containsKey(name)){
map.put(key, map.get(key) + 1);
} else {
map.put(key, 1);
}
This could be optimised a little: you could rely on the fact that map.get(key) will be null if key is not present. This obviates the need for the containsKey call.
Finally, to output your values use something on the lines of
for (java.util.Map.Entry<String, Integer> entry : map.entrySet()){
/*ToDo - use entry.getKey() and entry.getValue()*/
}
If you want your output to be sorted on the keys then use a java.util.TreeMap instead. If the order of output is of no consequence to you then use a java.util.HashMap.
I need to merge duplicates and add counter of duplicates.
When duplicate stuff comes to mind, think of Set to isolate. As and when you try to add an element to set and the add method returns false, print the data with 2 count.
But when the entries can occur more than twice, then you need to keep a track of each entry's count until the very end. So use a map instead with each String as key and its count as value. That basically means, while adding a string to map:
Get it from the map
- if not null, then get its value, increment 1 and set its value again.
- if null, then add it to map with value=1
At the end, you can iterate and find count.

Using a hashmap to iterate over a list of hashmaps

I am using a hashmap to add similar values for each aclLine processed
for (String aclLine : refinedFileContents){
if(Some condition)
{
staticVariablesMap.put("lineNumber", **lineNumber**);
staticVariablesMap.put("**srcHostName**", batchBean.getSourceIpAddress());
staticVariablesMap.put("batchBean", batchBean);
}
}
Later I want to iterate over these hashmaps for each line and perform some actions specific to a given key, value pair (e.g. get the srcHostName for that lineNumber) and use it to process next steps. How can I iterate over these collected hashmaps for each srcHostName entry in the hashmap? Should I use ArrayList/List to store each instance of the hashmap? Is this feasible?
Sounds to me like you should combine the attributes in your hashmaps into an object instead. Then you could just use one hash map.
public class AclLine {
private long lineNumber;
private String srcHostName;
private Object batchBean;
}
Map<AclLine> lines = new HashMap<AclLine>();
// Or maybe a List?
List<AclLine> lines = new ArrayList<AclLine>();
Or is there a reason you need these "parallel" map entries?
I didn't get your question completely like you are putting values in only one hash map & you want to iterate hashmaps
You can iterate hash map like this.
Iterator<Entry<String, Object>> it = hashMap.entrySet().iterator();
while (it.hasNext())
{
Map.Entry<String, Object> entry = (Map.Entry<String, Object>)it.next();
}

Get the last value in map

How can i get the last and first key/value of a Map?
For example:
Map<String,Integer> ret = new HashMap<String,Integer>();
And this is ret's value:
{33=1, 12=2, 21=2, 93=2, 48=9, 68=10}
You cannot do it with HashMap because keys are not ordered. Consider using LinkedHashMap
You can get last element using this method:
public <K,V> Map.Entry<K,V> getLast(LinkedHashMap<K,V> map) {
Iterator<Map.Entry<K,V>> iterator = map.entrySet().iterator();
Map.Entry<K, V> result = null;
while (iterator.hasNext()) {
result = iterator.next();
}
return result;
}
A HashMap is an unordered map, so it doesn't have any concept of 'first' or 'last.
If you want a map that retains things in insertion order, you can use a LinkedHashMap, and then iterate its entrySet() method to pick the first and last values.
You could also use the SortedMap interface (TreeMap impl.) which orders inserted entries by the natural ordering of keys (or a provided Comparator).
It isn't possible (or more like doesn't make sense) to differentiate between "first" and "last" when it comes to HashMap. If you want to preserve insertion order, you might want to use LinkedHashMap<K,V>. But then again, you should elaborate your question to let us know the exact use case demanding this.
since there is no defined order you will basically get a random element if you are unlucky.
else you could go the way HashMap -> getEntrySet -> toArray -> get(size-1)
Technically, you can get the first object from the map via:
Map.Entry<Integer,Integer> entry = map.entrySet().iterator().next();
And the last via:
Iterator<Map.Entry<Integer,Integer>> iter = map.entrySet().iterator();
Map.Entry<Integer,Integer> entry = null;
while(iter.hasNext()) {
entry = iter.next();
}
// now you have the "last" item in the map stored in 'entry'
But, as has been stated in other answers, this doesn't mean anything with a HashMap. Substitute it with a LinkedHashMap, however, and you can get the first and last inserted pairs out using the above code.
Unless you use a http://docs.oracle.com/javase/6/docs/api/java/util/SortedMap.html, in which case you could get the first and last key..

Using the keySet() method in HashMap

I have a method that goes through the possible states in a board and stores them in a HashMap
void up(String str){
int a = str.indexOf("0");
if(a>2){
String s = str.substring(0,a-3)+"0"+str.substring(a-2,a)+str.charAt(a-3)+str.substring(a+1);
add(s,map.get(str)+1);
if(s.equals("123456780")) {
System.out.println("The solution is on the level "+map.get(s)+" of the tree");
//If I get here, I need to know the keys on the map
// How can I store them and Iterate through them using
// map.keySet()?
}
}
}
I'm interested in the group of keys. What should I do to print them all?
HashSet t = map.keySet() is being rejected by the compiler as well as
LinkedHashSet t = map.keySet()
Use:
Set<MyGenericType> keySet = map.keySet();
Always try to specify the Interface type for collections returned by these methods. This way regardless of the actual implementation class of the Set returned by these methods (in your case map.keySet()) you would be ok. This way if the next release the jdk guys use a different implementation for the returned Set your code will still work.
map.keySet() returns a View on the Keys of the map. Making changes to this view results in changing the underlying map though those changes are limited. See the javadoc for Map:
http://java.sun.com/j2se/1.5.0/docs/api/java/util/Map.html#keySet%28%29
Map<String, String> someStrings = new HashMap<String, String>();
for(Map.Entry<String, String> entry : someStrings.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
}
This is how I like to iterate through Maps. If you specifically want just the keySet(), that answer is elsewhere on this page.
for ( String key : map.keySet() ) {
System.out.println( key );
}
Set t = map.ketSet()
The API does not specify what type of Set is returned.
You should try to declare variables as the interface rather than a particular implementation.
Just
Set t = map.keySet();
Unless you're using an older JDK, I think its a little cleaner to use generics when using the Collections classes.
So thats
Set<MyType> s = map.keySet();
And then if you just iterate through them, then you can use any kind of loop you'd like. But if you're going to be modifying the map based on this keySet, you you have to use the keySet's iterator.
All that's guaranteed from keySet() is something that implements the interface Set. And that could possibly be some undocumented class like SecretHashSetKeys$foo, so just program to the interface Set.
I ran into this trying to get a view on a TreeSet, the return type ended up being TreeSet$3 on close examination.
Map<String, Object> map = new HashMap<>();
map.put("name","jaemin");
map.put("gender", "male");
map.put("age", 30);
Set<String> set = map.keySet();
System.out.println("this is map : " + map);
System.out.println("this is set : " + set);
It puts the key values in the map into the set.
From Javadocs HashMap has several methods that can be used to manipulate and extract data from a hasmap.
public Set<K> keySet()
Returns a Set view of the keys contained in this map. The set is backed by the map, so changes to the map are reflected in the set, and vice-versa. If the map is modified while an iteration over the set is in progress (except through the iterator's own remove operation), the results of the iteration are undefined. The set supports element removal, which removes the corresponding mapping from the map, via the Iterator.remove, Set.remove, removeAll, retainAll, and clear operations. It does not support the add or addAll operations.
Specified by:
keySet in interface Map
Overrides:
keySet in class AbstractMap
Returns:
a set view of the keys contained in this map
so if you have a map myMap of any datatype , such that the map defined as map<T> , if you iterate it as follows:
for (T key : myMap.keySet() ) {
System.out.println(key); // which represent the value of datatype T
}
e.g if the map was defined as Map<Integer,Boolean>
Then for the above example we will have:
for (Integer key : myMap.keySet()){
System.out.println(key) // the key printed out will be of type Integer
}

Categories

Resources