What is the most correct and/or efficient way in terms of time & memory consumption to write simple pojo class containing ArrayList? (Regarding java mechanism for references, pass by ref', assignments etc.):
public class MyClass {
//1. Do we need to initialize here?
public List<String> mList = new ArrayList<>();
//2. Do we need to declare D. Constructor?
public MyClass() {}
//3. Need to initialize the list here or just pass?
public MyClass(List<String> list) {
this.mList = list;
}
//4. Better way for copy/assignment?
public void setMlist(List<String> list) {
this.mList = list;
}
public List<String> getMList() {
return this.mList;
}
}
- Do we need to initialize here?
No, initialize it only when you need it. Make sure to check for null if there is possibility of using it without being initialized.
- Do we need to declare D. Constructor?
If you do nothing in it, I don't really see the point of having it. Note that some people prefer to still declare it writing a comment in it and indicate that it should do nothing :
public MyClass(){
//NOP
}
See NOP. This won't change anything related to memory usage. However logically, the default constructor should initialize the list instead of initializing it at the beginning. So we have two options, we pass one that already exists (with the parameterized constructor) or we use the default constructor and create an empty list.
- Need to initialize the list here or just pass?
Just pass, else what would be the point of receiving it as an argument ? If you initialize it and re-assign that would make no sense. You may want to check if the received one is null and initialize it otherwise.
- Better way for copy/assignment?
If really you want to make a copy, you might want to check Collections#copy
. However, this is not the point of setter, what you have done here is correct.
This is impossible to answer without knowing about your intentions. There's a surprisingly large number of design decisions you have to make, even when writing a "simple pojo class containing ArrayList". Here are 8 off the top of my head, but there are many, many more.
public
or private
? (probably private
.)private
, do you want to provide a get
method?set
method, or do you want the field to be initialized once and for all in the constructor?set
method only accept a List<String>
or will you allow something more general, such as Collection<? extends CharSequence>
?mList
? (This is different from reassigning mList
.)final
?final
?ArrayList
to a sensible default value?The most subtle one of these questions is the 5th. Suppose somebody does this
List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));
myClass.setMList(list);
and then later does this
System.out.println(myClass.getMList());
They may expect to see [a, b, c]
, but this may not happen because it is possible to modify the internals of myClass
in between. For example:
List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));
myClass.setMList(list);
list.remove(1); // Modifies the List stored by myClass
System.out.println(myClass.getMList()); // prints [a, c]
If you don't want this kind of thing to be possible you'll have to write a class that copies List
objects in the constructor, setter and getter. This will have consequences for performance (but will be tiny for small lists).
There are no right or wrong answers. You need to think through who is using the class, why they need it, and weigh up all the relevant factors when answering all of the above questions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With