Getting only last element of arraylist and losing old elements - java

I have a problem about Arraylists. I created an arraylist of user defined object. In my drawing program, I created a class which takes only this arraylist. In another class I create this object, and I create another arraylist which takes these objects. You can understand better if you can look up my code. The problem is I have to remove all elements of the object's arraylist after adding to the last arraylist. But I always lose elements after removing. I used clone() method then I keep always last elements. I know its coplicated here, sorry about my english, you can understand clearly what I mean if you can check my code.
public class Lines {
public int id;
public Point point1;
public Point point2;
public int[] denklem;
}
public class Devline {
ArrayList<Lines> segmentim = new ArrayList<Lines>();
}
...
Devline devarray = new Devline();
Devline devarray3 = new Devline();
ArrayList<Devline> devarray2 = new ArrayList<Devline>();
if(SwingUtilities.isRightMouseButton(e) == true){
devarray3.segmentim = (ArrayList<Lines>) devarray.segmentim.clone();
devarray2.add(devarray3);
devarray = new Devline();
begin = true;
}
Here how I add an element to devarray.
devarray.segmentim.add(l1);
I need to add all elements to my devarray2 list. Each time I click rightbutton it will add devarray elements into devarray2, so I can make many different devarray elements inside devarray2. Thank you.

devarray3.segmentim = (ArrayList<Lines>) devarray.segmentim.clone();
devarray2.add(devarray3);
You are repeatedly adding the same Devline object to the ArrayList. Its segmentim is getting changed bu it is affecting all elements in the ArrayList.
You need to add a new Devline to the devaray2 ArrayList in each iteration. Since you are creating new devarray you can use that one itself:
devarray2.add(devarray);
devarray = new Devline();
begin = true;
Also you should change the names -- devarray is not an array, it should be devLine and the class Lines should be called Line

Could you try
devarray3.segmentim = new ArrayList<Lines>(devarray.segmentim);
to copy the devarray2 arraylist ?

Related

Adding Array[][] to ArrayList replaces and adds element, instead of just adding

I'm using an arraylist of arrays[][] for my app. The problem is when I add the second element to the arraylist is replaces the first (It also adds to the arraylist, then when the next element is added it replaces all elements and adds, this happens repeadtedly.
I'm not to sure what code to add, so I'll add anything I think is helpfull.
Initializing the arraylist:
ArrayList<Bitmap[][]> levelTileList = new ArrayList <Bitmap[][]>();
ArrayList<Rect[][]> levelTileListRec= new ArrayList <Rect[][]>();
ArrayList<Bitmap[][]> levelFireList = new ArrayList <Bitmap[][]>();
ArrayList<Rect[][]> levelFireListRec = new ArrayList <Rect[][]>();
Adding the first element:
lvldesign.addLevel();
levelTileList.add(lvldesign.getAllLevelTiles());
levelTileListRec.add(lvldesign.getTempTileRect());
//fire rect and bitmaps
levelFireList.add(lvldesign.getAllLevelFire());
levelFireListRec.add(lvldesign.getTempFireRect());
Note it calls another class to get the element.
The class it call
public Bitmap[][] getAllLevelTiles(){
return tempTile;
}
public Rect[][] getTempTileRect(){
return tempTileRect;
}
public Bitmap[][] getAllLevelFire(){ return tempFire; }
public Rect[][] getTempFireRect(){
return tempFireRect;
}
Adding subsequent elements:
lvldesign.addLevel();
levelTileList.add(lvldesign.getAllLevelTiles());
levelTileListRec.add(lvldesign.getTempTileRect());
//fire rect and bitmaps
levelFireList.add(lvldesign.getAllLevelFire());
levelFireListRec.add(lvldesign.getTempFireRect());
Note all elements it calls is either Bitmap[][] or Rect[][].
As I already said the latest added element replaces all earlier elements and adds an element.
Please let me know if there's any other specific code you want to see.
Alright seems each time you add to the arraylist it must be seen as a new variables. So I added the following code to my add level(this code runs before the call.) and it works. So if you have the same problem just make sure each element is seen a new element.
tempTileRect = new Rect[mapHeight][mapWidth];
tempFireRect = new Rect[mapHeight][mapWidth];
tempTile = new Bitmap[mapHeight][mapWidth];
tempFire = new Bitmap[mapHeight][mapWidth];

How to create a copy of ArrayList<ArrayList<Arc>> to another ArrayList<ArrayList<Arc>>

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.

ArrayLists and sub-lists

Hello im rather stuck on this part of my java programming work. I have done what i think is right for this question but im unsure if it is right as the next question asks to add 4 different strings into two different sub-lists (and thats where im getting stuk).
This is the first question:
Create a variable called balancedThings of type ArrayList of ArrayLists of Strings and add a method balancedInit() that instantiates the balancedThings variable by creating a new ArrayList > object and that also creates two new ArrayList objects and adds these to the balancedThings list.
this is the second question:
Add a method balancedCreation() that adds the strings “sword” and “map” to the first of the two sub-lists, and the strings “shield” and “bottle” to the second sub-list.
This is my answer:
void balancedInit()
{
balancedThings = new ArrayList<>();
balancedThings.add(0, "SubListOne");
balancedThings.add(1, "SubListTwo");
}
Can anyone explain if this is right for the question and where i should go next in order to add into sublists?
I think you just need to build the solution from the bottom up. Before worrying about the list of lists, worry about the individual lists first.
So first, you just want a list of strings. You can do that like this:
private static ArrayList<String> firstSublist() {
ArrayList<String> list = new ArrayList<>();
list.add("sword");
list.add("map");
return list;
}
ArrayList is your list, and the String in angle brackets tells you what type is going to be in the list. Then you add the actual strings. Do this for the other sublist too.
Then when you have a way to make your little lists, time to compose the big one:
private static void balancedCreation(ArrayList<ArrayList<String>> listOfLists) {
listOfLists.add((firstSublist()));
listOfLists.add((secondSublist()));
}
Here you have a list of lists. I know all the angle brackets can be confusing with something like ArrayList<ArrayList<String>>, but just remember to look at it a little at a time from the inside out.
So with the big list, you are just adding a thing--exactly like the sublists. As long as you take care of business at the simpler level, building up to the top level is no sweat.
In the end, main looks like this
public static void main(String[] args) {
ArrayList<ArrayList<String>> listOfLists = new ArrayList<>();
balancedCreation(listOfLists);
}
Hope this helps.
you want to add an ArrayList of Strings in an ArrayList :
public void balancedInit() {
ArrayList<ArrayList<String>> balancedThings = new ArrayList<ArrayList<String>>();
ArrayList<String> subListOne = new ArrayList<String>();
ArrayList<String> subListTwo = new ArrayList<String>();
// add values to your Sub Lists then ...
balancedThings.add(subListOne); // this will be index 0 implicitly
balancedThings.add(subListTwo); // this will be index 1 implicitly
}
programmers prefer using polymorphism in Collections framework, like declaring the ArrayList as List, but this is not a good practice when it comes to Serialization
initialize andinstantiate the "SublistOne" and "SubListTwo" in the way you initialized the BalancedThings.
that should create the sublist.
void balancedInit()
{
ArrayList<ArrayList<String>> balancedThings = new ArrayList<ArrayList<String>>();
ArrayList<String> subLiostOne = = new ArrayList<String>();
ArrayList<String> subLiostTwo = = new ArrayList<String>();
subListOne.add(0,"sword");
subListOne.add(1,"map");
subListTwo.add(0,"shield");
subListTwo.add(1,"bottle");
balancedThings.add(0, subListOne);
balancedThings.add(1, subListTwo);
}
please mark the answer as helpful if it is helpful

How to copy java.util.list Collection

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.

2d arraylists in java (why are the collections the same eventually)

I have a 2D ArrayList. The ArrayList contains 10 ArrayLists. I tried the following code:
This is the main 2D ArrayList. Inside the main ArrayList there are10 ArrayLists:
ArrayList<ArrayList<Items>> arrayList = new ArrayList<ArrayList<Items>>();
Here I tried to create a copy of one of the ArrayList (selectedRow is just a number which says which ArrayList I get)
ArrayList<Items> newList = new ArrayList<Items>(arrayList.get(selectedRow));
After that I create another ArrayList:
ArrayList<Items> changeList = new ArrayList<Items>(it.returnTheNewArrayList(newList,randomItem));
Then in another class I created this method. The purpose of this method is to change an attribute of one of the objects.
public ArrayList<Items> returnTheNewArrayList(ArrayList<Items> a,int item){
int randomBin = r.nextInt(50);
for(Items i:a){
if(item==i.itemIds()){
while(randomBin==i.bins()){
randomBin = r.nextInt(50);
}
i.setBin(randomBin);
}
}
return a;
}
Finally, I set the new ArrayList in the 2D ArrayList
arrayList.set(whichList, changeList);
This is the procedure. I have find out, that when I run this procedure, both newList and changeList are the same. In both of these ArrayLists I'm saving the change I did in the method returnTheNewArrayList (I found out it with the debugging). But I want to change only one (the changeList).
What did I do wrong?
The lists contain references to objects. When you call i.setBin(...) that's (presumably) making a change to the object itself.
Each list has an independent copy of the references - so you could remove an element from one list without affecting the other - but they're only references.
Imagine you gave two people clipboards, with the same list of home addresses on. One person went and painted the front door of every house list on their clipboard red, then the second person visited all the same houses. The second person would see red doors, wouldn't they? It's the same thing here. The lists contain references, not objects.
If you want the lists to be completely independent, you'll need to populate them with references to different objects.
EDIT: I've just noticed that you'll also need to change your returnTheNewArrayList method, which actually isn't even creating a new ArrayList in the first place!
public ArrayList<Items> returnTheNewArrayList(ArrayList<Items> a,int item) {
// Stuff which doesn't change the value of a...
return a;
}
Again, the value of a is just a reference to the list... so when you return the same reference back, you're not returning a new ArrayList at all.
You really need to understand how references and objects work in Java - it's absolutely crucial to working with the language.
Inside of the returnTheNewArrayList method, you first need to clone a. Otherwise you will be modifying the original ArrayList and the original Items. Jon did a nice job of explaining why, so I won't go into it here. Your code could look something like:
ArrayList<Items> clone = new ArrayList<Items>(a.size());
for(Items item: a) clone.add(item.clone());
//modify clone here
return clone;
Since you've written the Items class yourself, you will need to implement the Cloneable interface yourself.
See the clone method's wikipedia page for more information.
The newList and changeList are not the same (not == ) but their content are identical.
Your "Item" objects are passed by reference that's why the two lists references the same Items.
To get a brand new reference you should create a new instance of Item in method returnTheNewArrayList (10 new instances for 10 new references.)
public ArrayList<Items> returnTheNewArrayList(ArrayList<Items> a,int item){
//create a new List
ArrayList<Items> newList = new ArrayList<Items>();
int randomBin = r.nextInt(50);
for(Items oldItem:a){
// make a copy of Item to get a new instance of Item for the new List
Item newItem = new Item(oldItem);
if(item==newItem.itemIds()){
while(randomBin==newItem.bins()){
randomBin = r.nextInt(50);
}
newItem.setBin(randomBin);
}
newList.add(newItem);
}
return newList;
}

Categories

Resources