0

For last few days I was trying figure out how to make linkedList as class field works. In my project, I am creating object and than after few irations i would like to set field with linkedList. I have made simple model of this problem below. First we are creating new "Car", than we are seting ArrayList (same problem with linkedlIst), than we are addin to list of cars. During this everyting is ok. Object gets this list and its seeing inside. But when I will add more objects to the list or just generate another LinkedList(Classfield for another object), all object will get new field like that last one. Exaple below:

public static void main(String[] args) {
    ArrayList<LinkedList> colors = new ArrayList();
    LinkedList<LinkedList> opcje = new LinkedList();
    List<Car>  cars = new ArrayList<>();

    Car car1 = new Car("Ford1");
    colors.add(generateColors(car1));
    car1.setColors(colors);
    cars.add(car1); 
    colors.clear();
    Car car2 = new Car("Ford2");
    colors.add(generateColors(car2));
    car2.setColors(colors);
    cars.add(car2);
    colors.clear();
    Car car3 = new Car("Ford3");
    colors.add(generateColors(car3));
    car3.setColors(colors);
    cars.add(car3);
    System.out.println(car1.getColors().toString());
    System.out.println(car1.getColors());
    for(Car c : cars) {
        System.out.println(c.toString());
    }

    System.out.println(car1.getColors().toString());
}

and Car.class

public class Car {
    private String name;
    private String engine;
    private ArrayList<LinkedList> colors;

    public Car(String name) {
        this.name=name;
    }

    public ArrayList<LinkedList> getColors() {
        return colors;
    }

    public void setColors(ArrayList<LinkedList> colors) {
        System.out.println("Setting up colors for "+colors.toString());
        this.colors = colors;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return "name : "+name+" colors: "+colors.toString();
    }
}

The result of this will be:

name : Ford1 colors: [[Ford3]]
name : Ford2 colors: [[Ford3]]
name : Ford3 colors: [[Ford3]]

What am I doing wrong?

mugx
  • 9,869
  • 3
  • 43
  • 55
Hardodziob
  • 49
  • 1
  • 10
  • 1
    You are using [raw types](https://stackoverflow.com/questions/2770321/what-is-a-raw-type-and-why-shouldnt-we-use-it), which should be avoided whenever possible. – Turing85 Dec 31 '17 at 13:03
  • Post your `generateColors` method. I think there should be a better way to implement this than with a list of lists. – Leo Aso Dec 31 '17 at 13:22
  • Its just easier example(with no sense) to ilustrate my problem. In my project im parsing html page with tree structure nodes. I did not figure better way to store this structure and be able to restore it as tree structer. I got 10 main node, some of them have nodes with nodes. I am storing it as: LinkedList - where i have linkedList of each node. Last element of this list is String, which helps me find "parent" of this node(1st element o other LinkedList). Also LinkedList helps me keep everything in right place, bcs all nodes at this HTML are just divs – Hardodziob Dec 31 '17 at 13:40
  • I think i cant add here "code" but maybe u will be able see anything. In this method is simple add name of objec to be able see acting of this LinkedList assigment. Its looks like every linkedlist in objects is replaced all times with last linkedlist assigment no matter when. public static LinkedList generateColors(Car car){ LinkedList opcje = new LinkedList(); System.out.println("Called for "+car.getName()); opcje.add(car.getName()); System.out.println("Return: "+opcje.toString()); return opcje; } – Hardodziob Dec 31 '17 at 13:42

1 Answers1

1

The reason that all Car instances points to the color [[Ford3]] is that they are all pointing to the single instance of ArrayList colors. Since you're storing a reference to the ArrayList<LinkedList> in each Car the ArrayList instance must be unique as well as the LinkedList instance. To get your desired behavior you could replace the lines colors.clear(); with colors = new ArrayList<>();

Full cleaned up example:

Main:

package so.q48042638;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<List<String>> colors = new ArrayList<>();
        List<Car> cars = new ArrayList<>();

        Car car1 = new Car("Ford1");
        colors.add(generateColors(car1));
        car1.setColors(colors);
        cars.add(car1);

        Car car2 = new Car("Ford2");
        colors = new ArrayList<>();
        colors.add(generateColors(car2));
        car2.setColors(colors);
        cars.add(car2);

        Car car3 = new Car("Ford3");
        colors = new ArrayList<>();
        colors.add(generateColors(car3));
        car3.setColors(colors);
        cars.add(car3);

        for (Car c : cars) {
            System.out.println(c);
        }
    }

    private static List<String> generateColors(Car car) {
        List<String> opcje = new LinkedList<>();
        opcje.add(car.getName());
        return opcje;
    }
}

Car:

package so.q48042638;

import java.util.List;

public class Car {
    private String name;
    private List<List<String>> colors;

    public Car(String name) {
        this.name = name;
    }

    public List<List<String>> getColors() {
        return colors;
    }

    public void setColors(List<List<String>> colors) {
        this.colors = colors;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return "name : " + name + " colors: " + colors;
    }
}