Remove last element from HashMap - java

I am trying to remove last element from
Map<String, List<String>> map = new HashMap<String, List<String>>();
My code is
StringTokenizer stheader = new StringTokenizer(value.toString(),",");
while (stheader.hasMoreTokens()){
String tmp = stheader.nextToken();
header.add(tmp);
System.out.println("tmp"+header);
map.put(tmp, new ArrayList<String>());
}
System.out.println(map.size());
Output:
tmp[Sepal_Length, Sepal_Width, Petal_Length, Petal_Width, Class]
map{Petal_Width=[], Class=[], Petal_Length=[], Sepal_Length=[], Sepal_Width=[]}
I want to remove the key Class[] from map or tmp.
I tried using .remove() but nothing is reflecting.

There is no order in HashMap, so, you can't remove the last item. Use LinkedHashMap to have the order of insertion.

You have two collections effectively, so if you want the "Class" element removed, you need to do it in both. If always removing the last element of tmp in both collections is what you care about, and assuming header is a List<String>, you should do something like this:
String keyToRemove = header.remove(header.size()-1);
map.remove(keyToRemove);

#Unmesha SreeVeni : Use LinkedHashMap to delete last element because HashMap does not maintain order of insertion of the elements.

HashMap doesn't arrange it's elements according to an index, but you can retrieve only the element according to it's key, so if you have to use a HashMap you have to add an incremental index to it's key, so when you put a new element that index incremented with one and put with the key in the HashMap, like this :
Map<Map<int,String>, List<String>> map = new HashMap<Map<int,String>, List<String>>();
int index = 0;
StringTokenizer stheader = new StringTokenizer(value.toString(),",");
while (stheader.hasMoreTokens()){
String tmp = stheader.nextToken();
header.add(tmp);
System.out.println("tmp"+header);
Map<int, String> temp_map = new HashMap<int, String>();
temp_map.put(index, tmp);
index ++;
map.put(temp_map, new ArrayList<String>());
}
and then you can check the value of index in the end and that will be the index of the last element.

Related

Merging n number of list into a Map based on a value in List

I have the following objects in an ArrayList and a value in this object is illustrated as the numbers at the beginning, which are Id of something.
I need to create a Map object, whose key should be the id of objects and whose values should be the objects with id. At the end of the day, I would like to have a Map something like that.
I have already solved this problem with two for loops and lots of if statements but it seems very ugly to me.
Any cleaner solution would be appreciated.
Map<Integer, List<Foo>> result = list.stream().collect(Collectors.groupingBy(Foo::getId));
Edited to fit the question edit, it is as simple as this:
ArrayList<Element> list = ...;
HashMap<Integer, List<Element>> map = new HashMap<Integer, List<Element>>();
for(Element e : list) {
ArrayList<Element> auxList;
if(map.contains(e.getId()) {
auxList = map.get(e.getId());
} else {
auxList = new ArrayList<Element>();
map.put(e.getId(), auxList);
}
auxList.add(e);
}
Just iterate over the starting list and add the elements to the map. If the map already contains the id, add it to the list. If not, create a new list.

How to create a map of character and dynamic ArrayList in Java

I want to create a hashmap defined as HashMap<Character,ArrayList<String>>.
What I am trying to do is to read a set of strings which I am reading into a list.
From this list I want to generate this hashmap.
So if strings are something like this
Andy,Aman,Rocky,Ravi,Nick etc.
Map should be like
A->[Andy,Aman]
R->[Rocky,Ravi]
N->Nick
What I have tried is something like this
ArrayList<String> xlist= new ArrayList<String>();
ArrayList<String> list = new ArrayList<String>();
HashMap<Character,ArrayList<String>> h = new HashMap<Character,ArrayList<String>>();
Scanner s = new Scanner(System.in);
for(String sin : list){
Character x =sin.charAt(0);
//System.out.println(sin.charAt(0));
if(h.containsKey(x)){
h.get(x).add(sin);
//xlist.clear();
//xlist = h.get(x);
//xlist.add(sin);
//h.put(x,xlist.clone());
}
else{
xlist.clear();
xlist.add(sin);
h.put(x,xlist);
}
}
When I print the hashmap, I get this
{A=[Ravi, Rocky], R=[Ravi, Rocky], N=[Ravi, Rocky]}
I understand , that all the lists in values are being reflected from same copy of list, but I don't know , how to resolve it.
If you don't want to rewrite the loop, you can just change your last line within the else block so you won't change content of map on every iteration:
h.put(x,new ArrayList<String>(Arrays.asList(sin)));
You can also do it using Java 8 Streams which makes it much shorter:
Map<Character, List<String>> map = list.stream().collect(Collectors.groupingBy(d -> d.charAt(0)));
If you want to preserve the order of keys you can use it with LinkedHashMap:
Map<Character, List<String>> map = list.stream().collect(Collectors.groupingBy(d->d.charAt(0), LinkedHashMap::new, Collectors.toList()));
xlist is always the same list, even after you've put it in your hashmap. Whenever you hit a new letter, you clear every list in your hashmap, and add the current word to every list, because they're all the same list.
I'd rewrite your loop as:
for(String sin : list){
Character x =sin.charAt(0);
if(!h.containsKey(x)){
h.put(x, new ArrayList<String>());
}
h.get(x).add(sin);
}

Complex Hashmap ArrayList Generator

Here's some code:
ArrayList<String> List = new ArrayList<>();
Map<String, List<String> > map = new HashMap<String, List<String>>();
List.add("stringA");
List.add("stringB");
List.add("stringC");
for(int i = 0; i<List.size();i++){
String key = List.get(i);
List<String> value = new ArrayList<String>();
map.put(key, value);
}
This code takes whatever is in the ArrayList, loops through it, adds it to the Map, and then creates an empty ArrayList with each string name as the variable name. Now, this works, but there's one problem, unless I'm overlooking something. At some point, I will need to access the new empty ArrayLists that are in the map. However, I won't know what the titles of these ArrayLists are, without printing them out, which I don't want to do. Basically, I'm thinking I need a map method or class and then an additional map key method or class. I'm not sure how to implement it but maybe something like this:
public class MapKey {
public MapKey(int count, String header){
}
}
Map<MapKey, List<String> > map = new HashMap<MapKey, List<String>>();
Another option I've considered is to somehow loop through the map array and add Strings to each ArrayList, but I'm very new to maps and looping through them. Especially ones that contain ArrayLists as their values.
There're multiple ways to access keys and values of your HashMap:
for (Map.Entry<String,ArrayList<String>> entry : map.entrySet()) {
String key = entry.getKey();
ArrayList<String> value = entry.getValue();
// do your work
}
or
Set<String> keys = map.keySet();
for(String key : keys){
ArrayList<String> value = map.get(key);
}
Read the java HashMap api Java HashMap Link
Edit:
you dont need to loop through your outside ArrayList objects when you add all of its elements to another, just simply invoke addAll(), it will append all elements of an arraylist to another.
ArrayList<String> aList = map.get("stringA");
assume your first outside ArrayList is called outListOne;
aList.addAll(outListOne);
Appends to corresponding lists:
//assume number of outside lists are equal to number of map elements
String[] keysArr = {"stringA", "stringB", "stringC"};
ArrayList[] outLists = {outListOne, outListTwo, outListThree};
// adds outside lists to corresponding map ArrayList lists
for(int i = 0; i < keysArr.length; i++){
list = map.get(keysArr[i]); // you ArrayList in a map, get it by key name
list.addAll(outLists[i]); // append elements from out list to corresponding list
}
Not exactly sure what you mean by "titles of these ArrayLists." But here are a few code snippets that might give you a better idea of how to work with your map:
// add string x to the list for "stringA"
map.get("stringA").add(x);
// print all the values in the list for "stringC"
for (String s: map.get("stringC")) {
System.out.println(s);
}
// print the names of the lists that contain "xyzzy"
for (String key: map.keySet()) {
if (map.get(key).contains("xyzzy")) {
System.out.println(key);
}
}
// remove "foo" wherever it appears in any of the lists
for (List<String> list: map.values()) {
while (list.remove("foo")){}
}

Tree Data Structure in HashMap

I'm trying to create a tree structure based on a result set I get from a query. The below block of code works only if the result set has two columns. The first column is the parent and the second column is the child. Problem I'm running into is trying to re-engineer this so that it can incorporate multiple different levels (each column representing a level). Only way for me to do it now is to duplicate the code, check the number of levels and hard-coding to add in a new level. I'm processing the result set by row then column. (e.g. get the first row, then get the first column and store that value.)
Any idea on how I can re-engineer this functionality to be flexible on the number of levels it can go? Ultimately, the root gets passed into a HashTable and processed to a JSON file. FYI, I'm doing the JSON formatting in the second part of the code by traversing through the HashMap and formatting it to fit what I need for the JSON.
HashMap<String, HashSet<String>> level1TwoColumn = new HashMap<String, HashSet<String>>();
Object[] listElementCalcColumnNumber = list.get(0);
Hashtable allHash = new Hashtable();
//this will store all of the values in a hashmap and hashset
for(int i=0; i<list.size(); i++){
Object[] listElement = list.get(i);
//the reason we added ""+ between (String) and listElement is because listElement can be something other than a String (e.g. double, integer, etc)
//by adding "" to it, it becomes a String value automatically so then we can cast double/integer/etc into a String
String currentLevel1 = (String) ""+listElement[0];
currentLevel1 = currentLevel1.replace("\"", "");
//this prevents variables from duplicating. if the new element does not exist in hashmap, a new record in the hashmap will be created.
if((level1TwoColumn.get(currentLevel1) = null)){
HashSet<String> level2 = new HashSet<String>();
level1TwoColumn.put(currentLevel1, level2);
}
//stores all of the lowest level into a hashset because they're all going to be unique. no need to check to see if they exist in the hashset.
String currentLevel2 = (String) ""+listElement[1];
currentLevel2 = currentLevel2.replace("\"", "");
level1TwoColumn.get(currentLevel1).add(currentLevel2);
}
HashSet completeTree = new HashSet();
//now that the structure of the data is complete. iterate through level1 to get and store keys as values and "name" as key
for(String key1 : level1TwoColumn.keySet()){
HashSet levelOneSet = new HashSet();
HashMap levelOne = new HashMap();
levelOne.put("name", key1);
levelOneSet.add(levelOne);
//this for-statement does the same thing as previous for-statement; stores the unique values and give them "name" and then put them in hashset and give the set a "children" key
for(String key2 : level1TwoColumn.get(key1)){
HashSet levelTwoSet = new HashSet();
HashMap levelTwo = new HashMap();
levelTwo.put("name", key2);
levelTwoSet.add(levelTwo);
levelOne.put("children", levelTwoSet);
}
//once it loops through once, all level 2 items will be stored under a unique level 1. then it gets added into our dendrogram one by one until all level 1 elements are added.
completeTree.add(levelOne);
}
//this is assigning what our first node is, which is "VA"
allHash.put("name", "VA");
//put everything under "VA" node
allHash.put("children", completeTree);

How to use collection in Java

I want to use Java collection to find the words in the list that begin with the startup letter:
example:
TreeMap<String, Double> tm = new TreeMap<String, Double>();
// Put elements to the map
tm.put("Zara", new Double(3434.34));
tm.put("Mahnaz", new Double(123.22));
tm.put("Ayan", new Double(1378.00));
tm.put("Daisy", new Double(99.22));
tm.put("Qadir", new Double(-19.08));
Toast.makeText(getApplicationContext(), ""+tm.get("Zar"),Toast.LENGTH_SHORT).show();
in this case it will show null. But what i want to do is to show all the words that start with that letter. How can i do this? Thanks in advance
Since TreeMap is a NavigableMap, it is computationally cheap to iterate the map starting from a given key:
String prefix = "Zar";
for (String person::tm.tailMap(prefix).keySet()) {
if (person.startsWith(prefix)) {...}
}
There are a few choices:
If you always go from the first three characters then do a multimap - Map<String, List<Data>> Where Data contains String name and double double and the key is the first three letters of all the names.
You can scan through the TreeMap and because it is sorted at least you know you can stop once you get past Zar - but this will still be inefficient.
You can use a database (embed a Derby Database for example) and use the indexing/search/query functionality of the database.
You can build your own tree structure branching on each character in the word. Then root->z->a->r would then give you every word beginning with zar. root->b->o would give you every word beginning with bo, etc.
TreeMap<String, Double> tm = new TreeMap<String, Double>();
//...add values.
//get all keys
Set<String> keys = tm.keySet();
Set<String> result = new HashSet<String>();
for(String key : keys){
//check the beginning of the keys
if(key.startsWith("Zar"){
result.put(key);
}
}
//get the values for your collected keys
for(String key : result){
double value = tm.get(key);
}
Just reading when to use what collection will only help you if you run across the exact same situation in your code. If you don't understand the roots of why a given data structure is good for a problem, you won't be able to apply this to your own code.
this link may help you
You only have to Iterate over the list and check if the key starts with the given String.
Example:
for (String elem : tm.keySet()) {
if(elem.startsWith("Zar")) {
System.out.println(elem);
}
}
output:
Zara
and if you want to ignore the case:
if(elem.toLowerCase().startsWith("zar".toLowerCase()))
So How can you achieve this?
First find all the keys of HashMap by
tm.keySet()
then use iterator on keys and match with the string.See example below
String abc = "Zar";
HashMap s = new HashMap();
s.put("Zara", new Double(1.0));
Set x =s.keySet();
Iterator iter = x.iterator();
while (iter.hasNext()) {
String key = iter.next().toString();
if(key.startsWith(abc)){
System.out.println(s.get(key));
}
}

Categories