Hello I have to add elements to my list and I notice if I Use the method add I just add the reference to my list but I would like to add the elements and not the reference:
ArrayList ArrayListIdle = new ArrayList();
List<State> arrayState = new ArrayList<State>();
while(rs.next){
state = new State();
state.updateStateArray(arrayState);//This function mods the elements of (arrayState);//This
state.setArrayStates(arrayState);//add a list of arrayState to the object state
//I have a array and I want to add the element state with his arraylist(not the reference to)
ArrayListIdle.addAll(state);
// I tried with add , but in the next iteration the arrayState change.
}
You are adding the same ArrayState object every time. You should create a new ArrayState object every time in the while loop to avoid it getting changed every time. This is because by default objects are always passed by reference in Java.
Try doing this:
ArrayList arrayListIdle = new ArrayList();
while(rs.next){
state = new State();
List<State> arrayState = new ArrayList<State>();
state.updateStateArray(arrayState);//This function mods the elements of (arrayState);//This
state.setArrayStates(arrayState);//add a list of arrayState to the object state
arrayListIdle.addAll(state);
}
The problem here is that you have one "arrayState" object and all of the state objects reference the same one.
One way to solve that here is to move the object creation inside loop so that a different object is created every time.
while(rs.next) {
List<State> arrayState = new ArrayList<State>();
...
}
Related
List<Cars> allValues = new ArrayList<Cars>();
Cars obj = new Cars();
obj.setKey("merc");
obj.setValue("true");
allValues.add(policyOrg1);
obj.setKey("audi");
obj.setValue("true");
allValues.add(obj);
I have this case where I have to insert two values to my list and I am using the same object and then resetting the value once the previously set key and value have been inserted to the list. But, when the object is reassigned I see that the value inserted in the list earlier gets updated to the latest assigned value. Any way to solve this problem other than creating a new Object and assigning.
The result of the above insertion is that the list ends up having two entries with key audi and value true as it the last value inserted.
just edit your code like this:
List<Cars> allValues = new ArrayList<Cars>();
Cars obj = new Cars();
obj.setKey("merc");
obj.setValue("true");
allValues.add(obj);
obj = new Cars(); // you need to create a new object here
obj.setKey("audi");
obj.setValue("true");
allValues.add(obj);
What you're doing is add an object to a list, then update the same object instead of create a new one.
I think that the best approach is to modify your Cars class constructor and pass values for object through constructor. And than you can simply create new object in .add() method.
public Cars(String key,String value){
//make your stuff here
}
var allValues = new ArrayList<Cars>();//if you have Java 11 or higher use var
allValues.add(new Cars("merc","true"));
This should work fine :)
I am passing Arraylist of ParseObject, and then i am putting one one foreach loop to extract the items with a condition when user object is not equals to null. There are two problems which i am facing.
1. If i am doing the following lines of code by passing different data to another list and then pass that list in my adapter, i am getting random data with numbers for example: If on item # 1 the name is "MAC" then it is showing in item 3.
ArrayList<ParseObject> checkRequestedNetArrayList = new ArrayList<ParseObject>();
requestedNetArrayList = (ArrayList<ParseObject>) objects;
MyResponsibilitesActivity.requestedNetArrayList = requestedNetArrayList;
adapterRequest = new GenericAdapter<ParseObject>(
getApplicationContext(),
requestedNetArrayList,
R.layout.requested_trust_net_list_item,
requestedDataBinder);
requestListView.setAdapter(adapterRequest);
requestedNetArrayList = (ArrayList<ParseObject>) objects;
for(ParseObject object: objects){
System.out.println(object);
object.getParseObject("user");
if(object.has("user")){
checkRequestedNetArrayList.add(object);
}else{
checkRequestedNetArrayList.remove(object);
}
}
adapterRequest = new GenericAdapter<ParseObject>(
getApplicationContext(),
checkRequestedNetArrayList,
R.layout.requested_trust_net_list_item,
requestedDataBinder);
requestListView.setAdapter(adapterRequest);
If i am doing the following line of code to just direct giving the items in the same list, i am getting the java.util.ConcurrentModificationException
for(ParseObject object: objects){
if(object.has("user")){
requestedNetArrayList.add(object);
}
}
else{
requestedNetArrayList.remove(object);
}
adapterRequest = new GenericAdapter<ParseObject>(
getApplicationContext(),
requestedNetArrayList,
R.layout.requested_trust_net_list_item,
requestedDataBinder);
requestListView.setAdapter(adapterRequest);
}
Please help me out here.
You can not remove an element from list while accessing it.
You have to use Iterator.
Where ever you are removing the object, use it.remove();
Iterator<ParseObject> it = objects.iterator();
while(it.hasNext()){
Object object = it.next();
//your stuff
it.remove();
}
I think you might want to check this article about deep copy also.
UPDATE
Since you want to add elements to the list it is not directly possible with iterator. Now you are facing problem because you are directly assigning objects to requestedNetArrayList instead of that do it in the following way :
ArrayList<ParseObject> requestedNetArrayList = new ArrayList<>(objects);
Then iterate over objects as you are doing now, and remove from or add to
requestedNetArrayList (which you are pretty much already doing).
When you make iteration using for-each construction for Collection
for (Object x : collection) ...
you have implicit creation of Iterator object for that Collection. This iterator performs a check: is collection was changed since iterator was created? If so, throwing an exception. So, you should avoid to any modify to your collection, until iterator done. That means, you should not use add and remove.
In either way, it is better to access ArrayList by index, because it will prevent creation of Iterator object. Like this:
for (int i = objects.size() - 1; i >= 0; i--) {
ParseObject object = objects.get(i);
// when iterating from tail to head, you can safely add or remove objects to/from this array list
}
Instead of assigning the reference of objects to requestedNetArrayList,
create a new ArrayList with the same contents
requestedNetArrayList=new ArrayList<ParseObject>(objects);
Then you can iterate on objects and modify requestedNetArrayList.
I have a Class
public class Arc{
...
}
and 2 ArrayList
ArrayList<ArrayList<Arc>> rotalar1 = new ArrayList<ArrayList<Arc>>();
ArrayList<ArrayList<Arc>> rotalar2 = new ArrayList<ArrayList<Arc>>();
i try to copy rotalar1 to in rotalar2:
rotalar2.addAll(rotalar1);
but i have a problem. if i make any change in rotalar2 , it has an impact on rotalar1 too. I dont want to make a change in rotalar1 :
These rows make problem
rotalar2.get(random1).remove(random3);
rotalar2.get(random2).remove(random4);
Thanks for your time
Iterate over rotalar1 an copy each list of this list to rotalar2. You can make the copy in different ways. In the first example i use the constructor and create a new list with the same elements. Be careful, if you make changes to the Arc objects, this changes will still take effect in both lists. If you dont want this, you have to copy your Arc objects too.
ArrayList<ArrayList<Arc>> rotalar1 = new ArrayList<ArrayList<Arc>>();
ArrayList<ArrayList<Arc>> rotalar2 = new ArrayList<ArrayList<Arc>>();
for(ArrayList<Arc> list : rotalar1)
{
rotalar2.add(new ArrayList<Arc>(list));
}
This is another way, using Collections.copy(dest,src)
for(ArrayList<Arc> list : rotalar1)
{
ArrayList<Arc> copy = new ArrayList<>();
Collections.copy(copy, list); //or copy.addAll(list);
rotalar2.add(copy);
}
This problem is soved now:
rotalar2.get(random1).remove(random3);
rotalar2.get(random2).remove(random4);
but this will still take effect on both lists:
rotalar2.get(rndList).get(rndArc).set(xvy)
If you want to fix this problem too, you can do something like this:
ArrayList<ArrayList<Arc>> rotalar1 = new ArrayList<ArrayList<Arc>>();
ArrayList<ArrayList<Arc>> rotalar2 = new ArrayList<ArrayList<Arc>>();
for(ArrayList<Arc> list : rotalar1)
{
ArrayList<Arc> tmpList = new ArrayList<>();
for(Arc arcObj : list)
{
tmpList.add(copyOfyourArc); //TODO how do you want to creat a copy of Arc obj?
}
rotalar2.add(tmpList);
}
Method addAll does shallow copy which means it copies all the reference of object (not actual Object) from rotalar1 to rotalar2.
One way, you need to iterate over each object(Arc) and clone
it and add it to new list.
One other way is deep copy using serialization. Example Code
You are not deep copying your list.
The problem is, that your lists contain references to objects. If you copy that (list of) refereces to your second list, both references (the original and the copied one) are pointing to the very same object. Every change applied to the object through the referenc in the second list, will be visible in the first list as well.
To deep copy the collection, you could e.g. iterate over it and manually copy each index.
You should implement your own method to do a deep copy within the Arc class. The method should create a new instance of the object and set all fields(attributes) to the value that the current object has. This method should return a new Object of type Arc that has all the same values as the object trying to be copied. You should then iterate over your arraylist(s) and use your copy method on each object and add the new object to a new arraylist which will be a copy of your original arraylist. Example:
//I don't know the attributes of your Arc class this is just an example
public Arc deepCopy()
{
Arc copyOfArc = new Arc(this.field, this.field2, this.field3, this.field4, etc...);
//if you don't set everything in the constructor then you should use your setters here.
copyOfArc.setField5(this.Field5);
etc...
return copyOfArc;
}
Use this method to iterate over your arraylist and copy each arc object to a new arraylist.
Here is an example of using the deepCopy() method to copy your objects to new arraylist:
ArrayList<ArrayList<Arc>> rotalar2 = new ArrayList<ArrayList<Arc>>();
int counter = 0;
for(ArrayList<Arc> temp : rotalar1)
{
rotalar2.add(new ArrayList<Arc>());
for(Arc temp1 : temp)
{
rotalar2.get(counter).add(temp1.deepCopy());
}
counter++;
}
This will copy arraylist rotalar1 to arraylist rotalar2 with a deepCopy so each arraylist will have its own objects and won't effect each other anymore.
I have the code:
private class Record {
byte year;
float val;
}
Record record=new Record();
List<Record> recList = new ArrayList<Record>();
...
//now I add first element to array list
record.year=12;
record.val=55;
recList.add(record);
//now I add second element to array list
record.year=13;
record.val=77;
recList.add(record);
As you see I add different elements.
But as a result all elements in array list are the same.
So adding 2-nd, 3-d... element changes all previous elements
to the values of last "record".
What's wrong? Thanks?
An ArrayList keeps a list of references to objects. You're always modifying the same original object which means the reference is the same, but its values differ.
You can fix it by explicitly assigning a new instance to the record variable:
record.year=12;
record.val=55;
recList.add(record);
record = new Record();
record.year=13;
record.val=77;
recList.add(record);
You need to instantiate new objects so they are physically different objects. Right now, you only have one object that is in the ArrayList multiple times.
Record record = new Record();
Also, you should add hashCode() and equals() to Record since you are working with collections.
As you see I add different elements
No, you just edited old Record object and added it again. Each time before you add Record object you need to crate new one.
I am implementing a Java class responsible for ordering java.util.List. The problem comes when I use this class. I'm able to ordering the list but I want to copy the "original" list without modification so that I could register every change made on the original list. The sorted list contains object and one of its fields stores a classification id, and this id it is updated with the index value of the list.
I tried to use clone method and it keeps the list unsorted but the changes made on original list are updated in the clone list too.
Is there any way to accomplish it?
My Code:
List<Torero> listaTorero = tbTlgTorerolHome.findByExample(new Torero());
List<Torero> listaToreroTemp = ((List<Torero>) ((ArrayList<Torero>) listaTorero).clone());
Clasificacion clasificacion = new Clasificacion();
Iterator<Torero> iterTorero = clasificacion.getClasificacion(listaTorero, torero).iterator(); //Sorting List
A Clasificacion method:
public List<Torero> getClasificacion(List<Torero> listaToreroTemp, Torero torero)
{
List<Torero> listaTorero = new ArrayList<Torero>();
Collections.sort(listaToreroTemp,new ToreroClasifiacionComparator());
Iterator<Torero> iterTorero = listaToreroTemp.iterator();
int index=1;
while(iterTorero.hasNext())
{
Torero toreroTemp = iterTorero.next();
toreroTemp.setNumClasificacion(index);
listaTorero.add(toreroTemp);
index=index+1;
}
return listaTorero;
}
You may create a new list with an input of a previous list like so:
List one = new ArrayList()
//... add data, sort, etc
List two = new ArrayList(one);
This will allow you to modify the order or what elemtents are contained independent of the first list.
Keep in mind that the two lists will contain the same objects though, so if you modify an object in List two, the same object will be modified in list one.
example:
MyObject value1 = one.get(0);
MyObject value2 = two.get(0);
value1 == value2 //true
value1.setName("hello");
value2.getName(); //returns "hello"
Edit
To avoid this you need a deep copy of each element in the list like so:
List<Torero> one = new ArrayList<Torero>();
//add elements
List<Torero> two = new Arraylist<Torero>();
for(Torero t : one){
Torero copy = deepCopy(t);
two.add(copy);
}
with copy like the following:
public Torero deepCopy(Torero input){
Torero copy = new Torero();
copy.setValue(input.getValue());//.. copy primitives, deep copy objects again
return copy;
}
Use the ArrayList copy constructor, then sort that.
List oldList;
List newList = new ArrayList(oldList);
Collections.sort(newList);
After making the copy, any changes to newList do not affect oldList.
Note however that only the references are copied, so the two lists share the same objects, so changes made to elements of one list affect the elements of the other.