Having different ArrayLists for class objects in Java - java

I have a class and this class has one public element ArrayList myList.(I have other elements too in my class but they have nothing to do with this element)
What I am trying to do is having different ArrayLists for different Class Objects. However when I tried to code this, even if I use different class objects, the code reserves every entry in one single ArrayList. What am i doing wrong?
This is what i tried:
My class:
public class myClass {
public static ArrayList myList;
public static ArrayList getList() {
return myList;
}
public static void setList(ArrayList myList) {
myClass.myList = myList;
}
In main:
myClass my = new myClass();
myClass my2 = new myClass();
ArrayList tmp = new ArrayList();
ArrayList tmp2 = new ArrayList();
tmp.add("aaaaa");
tmp.add("bbbbb");
tmp2.add("ccccc");
tmp2.add("ddddd");
my.setList(tmp);
my2.setList(tmp2);
for(int i=0;i<my.getList().size();i++)
{
System.out.println(my.getList().get(i));
}
And the output of this main is being:
ccccc
ddddd
but i want it to be:
aaaaa
bbbbb
What am i doing wrong?

You declared myClass#myList static, which means only one instance of myList will exist, inside the CLASS myClass. Declare it non-static, including the getter and setter, to have different instances for my and my2 and you're good to go.

you are using static in your class.
remove static keyword for the variable in your class and you should be fine. Static is class scoped so will be shared across objects.

As identified by the other comments, you are declaring the ArrayList as static, which means it is shared across all object instances of the class - as such in the following statement:
my.setList(tmp);
my2.setList(tmp2);
...the second setList overwrites the first.
Read on up the Singleton pattern for a good example of where to use static fields:
Singleton pattern
As an aside, consider passing your values into the constructor and only providing a getter, thus encapsulating the use of ArrayList and making the values immutable - for example:
myClass my = new myClass("aaaa", "bbbb");
String element = my.get(0);
Finally, if using Java 5 or 6, think about using Generics when working with collections/lists:
List<String> tmp = new ArrayList<String>();
Hope that helps.

Modify your class as follows
public class myClass {
public ArrayList myList;
public ArrayList getList() {
return myList;
}
public void setList(ArrayList myList) {
listler.myList = myList;
}
You're using static ArrayList myList which is common to all the objects of your class myClass. Therefore, you're not getting what you expect. Avoid using static, if you need to use the ArrayList myList separately to all the objects of the class.
Java allows you to access static members of a class in both the ways with its objects and with associating them with their class name but its a bad practice to associate static members with the class objects.
Associating static members themselves with the class object was actual a flaw in language design itself (hence, should be avoided accessing them with objects) which was corrected by C# and hence in C# you can not associate static members with the respective class objects.
In java, some IDEs might issue warnings or errors, if you try to access static members with the respective class objects.

Related

Why I can't add CustomType ArrayList to ArrayList of Object ArrayLists?

I have Singleton class like this:
public class Singleton
private static Singleton instance;
private ArrayList<Release> releases;
private ArrayList<Place> places;
ArrayList<ArrayList<Object>> list = new ArrayList<ArrayList<Object>>(2);
private Singleton() {
releases = new ArrayList<Release>();
places = new ArrayList<Place>();
list.add(release); //error, required AL<Object>, provided AL<Release>
list.add(places); //same
}
public static Singleton getInstance(){
/* Singleton code */
}
I thought that it is possible because, every Class extends Object class. My intention is to read from files where ALs are saved as object a then these ALs have in collection of one AL, where al.get(PLACES_INDEX) would return places and so on. It is a good approach or am I missing something?
Later on I would like to have some unified method, which would be something like:
public ArrayList<T> getArrayList() {
/*return places or releases based on <T>*/
}
I don't know if it's even possible since this class is Singleton.
I will explain why you're getting the error, but from what you describe this looks like a bad design for your class: don't store "generic" lists in a list, to access them based on a certain index. And don't create a method like public ArrayList<T> getArrayList() { that returns one of the lists depending on the type T. This is overengineering, and makes your code much harder to maintain, and easy to break.
Just keep the distinct lists separately, and provide getters for each one of them. If you are reading from a file and want to deserialize the content into a data structure, simply create a class structure that models the content. Your code will be much simpler and easier to read.
Even though Release is a subclass of Object, ArrayList<Release> is not a subclass of ArrayList<Object>, therefore you cannot add an ArrayList<Release> to an ArrayList<ArrayList<Object>> (we say that generics are not covariant). If Java allowed you to do that, then you can end up with a scenario that breaks generic usage of the code:
ArrayList<ArrayList<Object>> list = new ArrayList<>();
ArrayList<Release> releases = new ArrayList<>();
list.add(releases); // imagine this is allowed
ArrayList<Object> releasesFromList = list.get(0);
releasesFromList.add(place); // oops, added a place to list of release

initializing static ArrayList field using anonymous class including a block initializer

I was playing javaDeathmatch game and encountered a question I couldn't answer. Can you help me?
public class DeathMatch {
private static final List<String> NAMES = new ArrayList<>() {{
add("John");
System.out.println(NAMES);
}};
public static void main(String[] args) {
//Nothing in particular
}
}
In this case when we run the JVM, the class will be loaded and first of all its static member 'NAMES' is created and initialized.The ArrayList is also initialized through an anonymous class including a block initializer.
But the problem is we add "John" to 'this' reference and print NAMES and thus it shows null.
The code will run correctly if we make changes this way:
System.out.println(this);
instead of:
System.out.println(NAMES);
Why is it like this?
When you use "double brace" initialization, you are creating an anonymous subclass of ArrayList with the outer braces, and the inner pair of braces represents the instance initializer, where you are calling add and printing out NAMES. But at the point where you're constructing the ArrayList, the ArrayList hasn't finished being constructed yet, and it has not been assignd to NAMES yet. The variable NAMES still has its default value null.
While the syntax may look pretty, it's usually not worth it to create an anonymous subclass just for the sake of easy-on-the-eyes initialization.
Instead, if this must be done statically, then move the initialization of the contents of the list to a static initializer block, so that NAMES is already initialized when referenced.
private static final List<String> NAMES = new ArrayList<String>();
static {
NAMES.add("John");
System.out.println(NAMES);
}
new ArrayList<>() {{
add("John");
System.out.println(NAMES);
}};
Can essentially be thought of as
new MyList();
where MyList is defined as:
class MyList extends ArrayList<String> {
public MyList() {
super();
add("John");
System.out.println(NAMES);
}
}
The order of events goes:
Call the constructor
Assign the object which is returned by the constructor to the static field named 'NAMES'
So because System.out.println happens within the constructor, calling it with NAMES means the assignment hasn't happened yet and doesn't work, but calling it with this is valid.
You should prefer one of the following (depending on Java version and the number of elements):
private static final List<String> NAMES = Arrays.asList("John");
private static final List<String> NAMES = List.of("John");
private static final List<String> NAMES = Collections.singletonList("John");
followed by a static block for the printing:
static {
System.out.println(NAMES);
}
The reason behind that initialization is not yet completed for the List NAMES so you are getting null for NAMES but getting [John] while using this keyword, if you print that in main, it will producing output as desired.

I'm trying to create an ArrayList of arrays but it won't compile properly [duplicate]

In a Java class where you normally declare/define instance variables, I would like to have an ArrayList as one of the instance variables and initialize it with some elements to start out with. One way of doing this is declare the ArrayList and initialize it in a constructor. However, I am wondering why it is illegal to initialize the value outside the constructor. For example,
public class Test {
// some instance variables...
private ArrayList<String> list = new ArrayList<String>();
list.add("asdf");
// methods here...
}
So I get that this is illegal. But why exactly is this illegal?
You cannot execute statements freely in a class. They should be inside a method. I recommend you to add this line in the constructor of the class or in a class initialization block.
In class constructor:
public class Test {
// some instance variables...
private List<String> list = new ArrayList<>();
public Test() {
list.add("asdf");
}
// methods here...
}
In class initialization block:
public class Test {
// some instance variables...
private List<String> list = new ArrayList<>();
{
list.add("asdf");
}
// methods here...
}
More info:
What's the difference between an instance initializer and a constructor?
It is illegal, because initializing fields is exactly the reason, why constructors exist!
In Java, it is not possible to have code anywhere 'outside' of a method or constructor (or class-initializer). It is possible to have simple expressions in a field initializer, but not multiple statements:
public class Test {
// here, at class level, you can only declare fields, methods or constructors!
// But you cannot have procedural code!!!
// field without initializer (=> default initialization with null)
private List<String> list1;
// field with explicit initializer expression
private List<String> list2 = new ArrayList<String>();
public Test() {
// initialize fields
this.list1 = new ArrayList<>();
this.list2.add("asdf");
}
}
If you use Guava (https://code.google.com/p/guava-libraries/) you will have this sugar code available:
private ArrayList<String> list = Lists.newArrayList("element1", "element2", ...)
Also, has was mentioned before, I suggest not typing your field as ArrayList but as List. Always use the more abstract type, good rule of the thumb.
That code will not get called if it outside a defined function for the class. If this were to be allowed, everything within the class would get executed as soon as you created a class which is not a behavior one would want.
If you would like to initialize with some elements, you can do it like this:
private ArrayList<String> list = new ArrayList<>(java.util.Arrays.asList("asdf"));
You cannot do what you're proposing, instead you can initialize the variable using java.utils.Arrays.asList(T) like this:
public class Test{
private List<String> foo = new ArrayLis<>(Arrays.asList("a", "b", "c"));
}

dot operator and static keyword in Java

Hello fellow programmers.
I have a question about static and the dot operator using this example in Java.
So I have this class variable declaration of an ArrayList inside my Inventory class.
static List<Multimedia> list = new ArrayList<Multimedia>();
If I choose to use the add method of the ArrayList in the method, should I write the method call like this: Inventory.list.add(Object o) or should I use list.add(Object o). Do they mean the same thing? If they are not, which method call should I use?
from class both are same,
Use
Inventory.list.add(Object o )
It will keep telling you that its a static field in code
You can't access the list in other packages so it would be better to create private list and expose it via public wrapper methods.
private static List<Multimedia> list = new ArrayList<Multimedia>();
public static void addMultimedia(Multimedia media){
list.add(media);
}
public static List<Multimedia> getList(){
return list;
}
To add Multimedia object:
Inventory.addMultimedia(new Multimedia());
//or
Inventory.getList().add(new Multimedia());
Outside the class you have to access it via the class name (but it depends on the access modifier i.e private cannot be accessed outside the class), inside the class you could use either of them.
Definately you should use Inventory.list.add(Object o ) because static fields are at class level i.e. shared among objects of that class.

Java Final arraylist

My question is regarding declaring an arraylist as final. I know that once I write final ArrayList list = new ArrayList(); I can add, delete objects from this list, but I can not list = new ArrayList() or list = list1. But what will be the use of declaring arraylist as
Private static final ArrayList list = new ArrayList();. And apart from the difference I have mentioned above what will be the difference between following two declaration:
1. ArrayList list = new ArrayList()
2. private static final ArrayList list = new ArrayList();
Just to "bring a little water to your Mill" you will understand the interest of final when you'll want to make your list publically availiable but unmodifiable.
In java one can make a list unmodifiable with Collections.unmodifiableList(modifiableList).
Now have a look to the following code :
public class MyClass{
public static List<String> MY_PUBLIC_LIST;
static{
ArrayList<String> tmp = new ArrayList<String>();
tmp.add("a");
tmp.add("b");
tmp.add("c");
MY_PUBLIC_LIST = tmp;
}
}
Well, in anyclass, anywhere in your code you can do something like this
MyClass.MY_PUBLIC_LIST = null;
MyClass.MY_PUBLIC_LIST = new ArrayList<String>();
MyClass.MY_PUBLIC_LIST.clear();
MyClass.MY_PUBLIC_LIST.add("1");
When you add the final keyword to your variable, the first two won't be allowed
public static final List<String> MY_PUBLIC_LIST;
But you'll still be able to modify the content of the list :
MyClass.MY_PUBLIC_LIST.clear();
MyClass.MY_PUBLIC_LIST.add("1");
By adding a Collections.unmodifiableList(modifiableList) at the end of the static block you'll prevent this too :
MY_PUBLIC_LIST = Collections.unmodifiableList(tmp);
Ok we are almost there. Just to be sure you get the whole picture lets keep the Collections.unmodifiableList(modifiableList) but let me remove the final modifier
public class MyClass{
public static List<String> MY_PUBLIC_LIST;
static{
ArrayList<String> tmp = new ArrayList<String>();
tmp.add("a");
tmp.add("b");
tmp.add("c");
MY_PUBLIC_LIST = Collections.unmodifiableList(tmp);
}
}
What can you do in that case ?
...
...
Well you can do whatever you want like in the first case (given that you assign the new list first) :
MyClass.MY_PUBLIC_LIST = null;
MyClass.MY_PUBLIC_LIST = new ArrayList<String>();
MyClass.MY_PUBLIC_LIST.clear();
MyClass.MY_PUBLIC_LIST.add("1");
You're right that declaring the list final means that you cannot reassign the list variable to another object.
The other question (I think) was
public class SomeClass {
private static final ArrayList list = new ArrayList();
}
vs
public class SomeClass {
ArrayList list = new ArrayList();
}
let's take each modifier in turn.
private Means only this class (SomeClass) can access list
static Means that there is only one instance of the list variable for all instances of SomeClass to share. The list instance is associated with the SomeClass class rather than each new SomeClass instance. If a variable is non-static it's said to be an instance variable
final as you know means that you cannot reassign the list variable another value.
In the second declaration there are no modifiers, so the variable is an instance variable and it also gets package-private access protection (Sometimes called default access protection). This means that this class (SomeClass) and other classes in the same package can access the variable.
You can find out more about public, private, and package-private here: Access control
You can find out more about final and static here: Class variables
When you say
final ArrayList list = new ArrayList();
this means that the variable list will always point to the same ArrayList object. There are two situations in which this can be useful.
You want to make sure that no-one reassigns your list variable once it has received its value. This can reduce complexity and helps in understanding the semantics of your class/method. In this case you are usually better off by using good naming conventions and reducing method length (the class/method is already too complex to be easily understood).
When using inner classes you need to declare variables as final in an enclosing scope so that you can access them in the inner class. This way, Java can copy your final variable into the inner class object (it will never change its value) and the inner class object does not need to worry what happens to the outer class object while the inner class object is alive and needs to access the value of that variable.
The second part of your question is about the difference between
ArrayList list = new ArrayList();
and
private static final ArrayList list = new ArrayList();
The difference of course are the modifiers. private means not visible outside the class, static means that it is defined on the class level and doesn't need an instance to exist, and final is discussed above. No modifiers means package-private or default access.
You say "I can add, delete (and find) objects", but who is I?
The different between your two cases concerns from which code those list operations can be called.
In general you need to consider the scope of the declaration, you greatly increase the maintainability of code if you reduce the visibility of your variables. If you have a class:
Public Class MyThing {
public int importantValue;
// more code
}
That important value can be changed by any other code, anywhere else in an application. If instead you make it private and provide a read accessor:
Public Class MyThing {
private int importantValue;
public int getImportantValue(){
return importantValue;
}
// more code
}
you now know only the class itself can change the value - for large applications this massively increases maintainability. So declaring the list private limits what code can see, and change the contents of the list.
The use of static makes the list shared by all instances of the class, rather than each instance getting its ovn copy.

Categories

Resources