Java Arraylist and Map - java

I don't have idea how to search this:
Random generator = new Random();
Map<Integer, ArrayList> mapOfprevOp = new HashMap<>();
ArrayList<Integer> listPrev = new ArrayList<>();
listPrev = mapOfprevOp.get(operacja);
System.out.println(listPrev); // it will show []
int rnd = generator.nextInt(op_cnt) + 1;
listPrev.add(rnd);
System.out.println(mapOfprevOp.get(operacja)); // it will show value of listPrev
Why second System.out print me on the screen value of listPrev?
It shouldn't still print [] ?
listPrev = mapOfprevOp.get(operacja);
This line works different than i could expect?

This would suggest that at your first System.out.println invocation the list is empty.
If you look here https://docs.oracle.com/javase/7/docs/api/java/util/AbstractCollection.html#toString%28%29. We can see that the toString method for a list returns the elements between square brackets. Thus [] is an empty list.
At the second call you have added an element which is why you see it. You need to bare in mind that in Java we pass objects by reference meaning that your listPrev references the SAME LIST as the one contained in the map.
If you want to just get the value, then I would suggest you change
listPrev = mapOfprevOp.get(operacja);
to be
listPrev.addAll(mapOfprevOp.get(operacja));
This will add all of the elements from mapOfprevOp.get(operacja) to listPrev without subsequent operations affecting the map which seems to be what you want.
Also, Map<Integer, ArrayList> mapOfprevOp = new HashMap<>(); Generally it is better to use interface types in delcarations like you have with Map. So I would consider switching ArrayList to be List.
The object that you use its self can still be an ArrayList, like this:
Map mapOfprevOp = new HashMap<>();
List listPrev = new ArrayList<>();
This means that if you wanted to change it to be a LinkedList, you would only change it in one place rather than 3. Note that with the exception of Arrays.asList lists all lists can be resized.

Related

Deleting a variable after adding it to a collection

In the following snippet, I want list to be a collection of maps. Instead of creating a new HashMap every time, I tried to clear and reuse the previous variable.
List<Map> list = new ArrayList<>();
Map<String,String> aMap = new HashMap<>();
aMap.put("fou","bar");
list.add(aMap);
aMap.clear();
aMap.put("big", "bang");
list.add(aMap);
System.out.println(list.toString());
I was surprised the value inside the list is affected by the "clear" operation on the variable aMap, the output is as following:
[{big=bang}, {big=bang}]
What's going on here ?
It's a tricky question :) Basically the list holds a reference to the object and not a copy of the object. So when you add aMap to the list you add a reference to that Map variable. Then you modify it (and by doing that you modify that reference that you hold in the list) and then you add the same variable to the list again. So now you have two references (or pointers if you prefer) of the same object. That's why you get such result.
Since you have already added aMap in the beginning to the list,aMap goes on getting added to the list instead rewrite the code as below:
List<Map> list = new ArrayList<>();
Map<String,String> aMap = new HashMap<>();
aMap.put("fou","bar");
list.add(aMap);
aMap.clear();
aMap.put("big", "bang");
// list.add(aMap);> --commented since u have already started adding map values to the array list.
System.out.println(list.toString());

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);
}

how can we add (long,String) in arraylist?

I need to create a list with values of type - (long,String)
like -
ArrayList a = new ArrayList();
a.add(1L,branchName);
How can I do this because if I use list It will accept only int,String.
You should note that ArrayList's add(int,String) adds the String element in the given int index (if the index is valid). The int parameter is not part of the contents of the ArrayList.
Perhaps an ArrayList is not the correct choice for you. If you wish to map Long keys to String values, use Map<Long,String>.
Map<Long,String> a = new HashMap<> ();
a.put(1L,branchName);
You can define a custom class, e.g.
class IndexAndBranchName {
long index;
String branchName;
}
and then add instances of this to the ArrayList:
ArrayList<IndexAndBranchName> a = new ArrayList<>();
a.add(new IndexAndBranchName(index, branchName));
Whether you use this approach or something like Eran's depends upon what you need to use the list for subsequently:
If you want to look "branches" up by index, use a Map; however, you can only store a single value per key; you could use a Guava Multimap or similar if you want multiple values per key.
If you simply want all of the index/branch name pairs, you can use this approach.
You can use the below code for your question.
HashMap is also a better option , but if you want only ArrayList then use it.
List<Map<Object, Object>> mylist = new ArrayList<Map<Object, Object>>();
Map map = new HashMap<>();
map.put(1L, "BranchName");
mylist.add(map);

Java add variable to string array

I have a small code that includes citynames which will be displayed.
Now a want a user can add names with a scanner, I know the code for the scanner but not how to add the variable.
Code I have:
String[] cityNames = { "Tiel", "Culemborg", "Houten", "Geldermalsen", "Meteren", "Buren" };
System.out.println(Arrays.toString(cityNames));
No you cannot do it with a Array since the size is fixed , once it declared.
You are probably looking for Collections. Prefer to Use List interface with ArrayList implementation.
The reason is that the ArrayList is
Resizable-array implementation of the List interface.
List<String> cityNames = new ArrayList<>();
Now you have methods like add, remove, ... and many more useful methods on your cityNames List
You can use a List<String>, get the input value and add it:
List<String> cities = new ArrayList<>();
cities.add(userInput);
List is better to use than array as its length is modifiable.
Arrays have a fixed length. If the amount of Strings in your collection is variable, you´ll have to use a List.
You can add new element to array if index of new element less than the size of array.
arr[i]="some value" // to do this i < arr.length
If array is completely filled with elements when you assign new value to index previous value will override. You can't add more elements than the size of declared since array has fixed size.
Array is fixed size so you can't add the value to it if the size is already filled. For dynamic array use List instead of array.
Do like this
List<String> list = new ArrayList<String>(Arrays.asList("Tiel", "Culemborg", "Houten", "Geldermalsen", "Meteren", "Buren" ));
list.add("new value1");
list.add("new value2");
It's better to use there set, which excludes duplicate entries automatically:
Set<String> cities = new HashSet<String>();
cities.addAll(Arrays.asList("Tiel", "Culemborg", "Houten", "Geldermalsen", "Meteren", "Buren"));
then to add new city just call:
sities.add(newCity);
Scanner input = new Scanner(System.in);
List<String> cityNames = new ArrayList<String>();
//Add the city names to cityNames list...
cityNames.add(input.next());

For Loop doesnt add point to an array

I have the following for loop which looks through a string ArrayList of results, each item in the string is seperated by "::":
ArrayList<String> resultsArray = MyClass.results;
Integer numPoints = resultsArray.size();
for (int i =0;i<numPoints;i++){
String[] pointDetails = resultsArray.get(i).split("::");
String pointName = pointDetails[0];
String pointDescription = pointDetails[1];
String coordinates = pointDetails[2];
//Turn coordinates into geopoints
String coord[] = coords.split(",");
Integer lng= (int) (Double.valueOf(coord[0]) * 1000000);
Integer lat = (int)(Double.valueOf(coord[1])*1000000);
GeoPoint gPoint = new GeoPoint(lng,lat);
arrayPointName = new ArrayList <String>();
arrayPointDescription = new ArrayList <String>();
arrayPointCoords=new ArrayList<GeoPoint>();
arrayPointName.add(pointName);
arrayPointDescription.add(pointDescription);
arrayPointCoords.add(gPoint);
}
I know I have 20 points in the initial string ArrayList and have printed out its size to check this. However, when I print out the new arraylists, such as arrayPointName, they only contain one point. Any idea on why this is?
Look at this code:
arrayPointName = new ArrayList <String>();
arrayPointDescription = new ArrayList <String>();
arrayPointCoords=new ArrayList<GeoPoint>();
Those three statements - assigning new, empty ArrayList references to your variables - are being executed on every iteration of your loop.
They should come before your loop instead: you only want to initialize the variables once (creating the three lists) and then add a new item on each iteration.
As a side note, populating multiple collections like this is normally a bad idea. It's usually better to create a single type which encapsulates the related data (name, description, coordinates in this case) and then create a single collection of items of that type. That's usually a lot easier to work with.
you used coords as an ArrayList Without initiate it .Also you initiate for each iteration arrayPointName, arrayPointDescription and arrayPointCoords that's why they lost the value created in the previous iteration. they should be initiate juste one time before starting the loop
it will be easy to help you if you give us a sample of resultsArray strring.

Categories