List versus ArrayList [duplicate] - java

This question already has answers here:
Polymorphism: Why use "List list = new ArrayList" instead of "ArrayList list = new ArrayList"? [duplicate]
(8 answers)
Closed 5 years ago.
Which one is better and why ?
a) List<String> list = new ArrayList<>();
b) ArrayList<String> list = new ArrayList<>();

It depends on the context.
If you care only about the list semantics and not for the particular implementation, go for List<String>. If you want to enforce a particular implementation, go for ArrayList<String>, LinkedList<String> or anything else.
In most cases, you will want to go on with the interface and not the particular implementation.

(a) is better because it is more flexible. If for example, suddenly your requirement changes and says "Instead of creating a new empty array list to assign to the variable list, we will populate the list with items filtered from another list", you need to change your code for that. You might change it to something like this:
List<String> list = anotherList.stream().filter(x -> x.length() > 2).collect(Collectors.toList());
Since collect(Collectors.toList()) returns a List, you also need to change the type of list if you were using the code in (b).
Another situation is that later on you found out that you need to assign some other kind of list e.g. LinkedList to list. If you were using the code in (a), you can just assign the linked list straight away. If you were using the code in (b), you will have to go back to the declaration of list and change the type.
The general pattern is that as you use more "abstract" types, your code becomes more flexible but at the same time you can do less with your variables. For example, you can't use methods declared only in ArrayList on your list variable, but on the other hand, other kinds of lists can be assigned to list. If you an even more abstract type, Collection, then you can't use the members only declared in List anymore, but then all kinds of collections - Set, Map etc - can be assigned.

Related

What class to use for ArrayList?

I just wanted to clarify this question I had for a while for more efficient and 'correct' code.
I gave a class 'Student' with objects in an array list of objects. I have another class called Class which has an array list of references to the very same objects in the Student class.
Should I declare the 'Class' class as
ArrayList<Student> myStudents = new ArrayList<Student>();
or
ArrayList<Class> myStudents = new ArrayList<Class>();
Also another part of the question is I have seen people declare arrayLists as ArrayList<Student> myStudents = new ArrayList<>();
where the second half of the carrots are left empty. What exactly does the difference mean? Does this mean that the array list is not an object of any class?
Thank you so much for your time and help
Cheers
It depends on what you want to store in the list rather than where you are using it. If you're storing Student objects, then you'll use ArrayList<Student>().
The type omitted on the right side is called type inference (added in java 7), which means the type parameter on the right side will be inferred from the type of the assignment variable on the left. It helps to write the code in a cleaner way. For e.g.
Writing below is easier:
List<Some<Type<Another>>> var = new ArrayList<>();
than:
List<Some<Type<Another>>> var = new ArrayList<Some<Type<Another>>>();
Technically, neither.
You would want to do:
List<Student> myStudents = new ArrayList<>();
if you want to create an ArrayList with Student objects and
List<Class> myClasses = new ArrayList<>();
if you want to create an ArrayList with Class objects.
1) Note the variable names.
2) Note that you should always try to code to an interface (the left side is a List, not an ArrayList). This allows much greater flexibility since you're not dependent on the specific implementation of an ArrayList later on. This point is so powerful! You can write method signatures to accept objects of type List and then use an ArrayList, LinkedList or Stack or any class that implements a List. Depending on how you are using your ArrayList later, the Collection interface may be sufficient instead.
The diamond operator allows the compiler to infer the value of the type argument without having to type it all out. It's needed for backward compatibility for older Java versions.
As a general practice for performance optimization, you will also want to supply an initial capacity of an ArrayList if it's possible. So if you know that there are only 5 classes, then you would do:
List<Class> myClasses = new ArrayList<>(5);

When do I use List and when do I use ArrayList, also LinkedList in Java? [duplicate]

This question already has answers here:
When to use LinkedList over ArrayList in Java?
(33 answers)
Closed 8 years ago.
When do I use List and when do I use ArrayList in Java? Please phrase in terms of practical situations where you would rather apply one over another. Thank you!
Edit : Also, LinkedList. Business situations where these are used, thanks, thats what's different about this question.
List is an interface. The other two are implementations of which.
You mostly want to code against interfaces. That is you wil do something like
List<String> strList = new ArrayList<String>();
Later on in the coding process, you may find that LinkedList has better performance for your scenario, so you just need to change one single place. Or maybe you don't care which concrete implementation is used, you just need "some sort of list". Then you could use an injected List implementation. Like this:
class ExampleClass{
private List<String> strList = null;
// We don't know and we don't care if Array or Linked List.
public ExampleClass( List<String> aList ){
strList = aList;
}
//...
}
For the differences between the implementations, see the links given in the comments as "possible duplicate of ..." or the JavaDoc.
***There's no difference between list implementations in both of your
examples. There's however a difference in a way you can further use
variable myList in your code.
When you define your list as:
List myList = new ArrayList(); you can only call methods and reference
members that belong to List class. If you define it as:
ArrayList myList = new ArrayList(); you'll be able to invoke ArrayList
specific methods and use ArrayList specific members in addition to
those inherited from List.
Nevertheless, when you call a method of a List class in the first
example, which was overridden in ArrayList, then method from ArrayList
will be called not the one in the List.
That's called polymorphism. You can read upon it.***
This answer was given by ATrubka here

Declaring a List before an ArrayList [duplicate]

This question already has answers here:
"Program to an interface". What does it mean? [duplicate]
(8 answers)
Closed 8 years ago.
In this statement List<String> MyList = new ArrayList<String>();
Why declare Mylist as a List of type String. just to make MyList a new instance of an ArrayList type String?
It seems unnecessary.
To paraphrase Item 52 of Joshua Bloch's Effective Java, using the interface instead of the class makes the surrounding code much more flexible. So if you wanted to change myList to something like a Vector, you wouldn't have to change the surrounding code much if at all. Bloch goes on to say that there are certain times, such as major updates to java, when other types of Lists are updated for effectiveness or new ones are added entirely.
Declaring MyList as type List<String> guarantees that you won't use methods only available for ArrayList<String>. That way, you can change the right-hand side of the declaration in the future.
List is just an Interface, not an implementation. There are many different types of lists, such as ArrayList and LinkedList.
So if you declare MyList an List<String> it could possibly be any type of List, as #espertus said, you can change what type of list MyList is in the future without having to change it's declaration.

How to quickly and conveniently create a one element arraylist [duplicate]

This question already has answers here:
Initialization of an ArrayList in one line
(34 answers)
Closed 6 years ago.
Is there a Utility method somewhere that can do this in 1 line? I can't find it anywhere in Collections, or List.
public List<String> stringToOneElementList(String s) {
List<String> list = new ArrayList<String>();
list.add(s);
return list;
}
I don't want to re-invent the wheel unless I plan on putting fancy rims on it.
Well... the type can be T, and not String. but you get the point. (with all the null checking, safety checks...etc)
Fixed size List
The easiest way, that I know of, is to create a fixed-size single element List with Arrays.asList(T...) like
// Returns a List backed by a varargs T.
return Arrays.asList(s);
Variable size List
If it needs vary in size you can construct an ArrayList and the fixed-sizeList like
return new ArrayList<String>(Arrays.asList(s));
and (in Java 7+) you can use the diamond operator <> to make it
return new ArrayList<>(Arrays.asList(s));
Single Element List
Collections can return a list with a single element with list being immutable:
Collections.singletonList(s)
The benefit here is IDEs code analysis doesn't warn about single element asList(..) calls.
Collections.singletonList(object)
the list created by this method is immutable.
You can use the utility method Arrays.asList and feed that result into a new ArrayList.
List<String> list = new ArrayList<String>(Arrays.asList(s));
Other options:
List<String> list = new ArrayList<String>(Collections.nCopies(1, s));
and
List<String> list = new ArrayList<String>(Collections.singletonList(s));
ArrayList(Collection) constructor.
Arrays.asList method.
Collections.nCopies method.
Collections.singletonList method.
With Java 7+, you may use the "diamond operator", replacing new ArrayList<String>(...) with new ArrayList<>(...).
Java 9
If you're using Java 9+, you can use the List.of method:
List<String> list = new ArrayList<>(List.of(s));
Regardless of the use of each option above, you may choose not to use the new ArrayList<>() wrapper if you don't need your list to be mutable.
With Java 8 Streams:
Stream.of(object).collect(Collectors.toList())
or if you need a set:
Stream.of(object).collect(Collectors.toSet())
The other answers all use Arrays.asList(), which returns an unmodifiable list (an UnsupportedOperationException is thrown if you try to add or remove an element). To get a mutable list you can wrap the returned list in a new ArrayList as a couple of answers point out, but a cleaner solution is to use Guava's Lists.newArrayList() (available since at least Guava 10, released in 2011).
For example:
Lists.newArrayList("Blargle!");
Very simply:
Arrays.asList("Hi!")
Seeing as Guava gets a mention, I thought I would also suggest Eclipse Collections (formerly known as GS Collections).
The following examples all return a List with a single item.
Lists.mutable.of("Just one item");
Lists.mutable.with("Or use with");
Lists.immutable.of("Maybe it must be immutable?");
Lists.immutable.with("And use with if you want");
There are similar methods for other collections.
Yet another alternative is double brace initialization, e.g.
new ArrayList<String>() {{ add(s); }};
but it is inefficient and obscure. Therefore only suitable:
in code that doesn't mind memory leaks, such as most unit tests and other short-lived programs;
and if none of the other solutions apply, which I think implies you've scrolled all the way down here looking to populate a different type of container than the ArrayList in the question.

List & ArrayList in Java [duplicate]

This question already has answers here:
Type List vs type ArrayList in Java [duplicate]
(15 answers)
Closed 9 years ago.
Hi,I am a beginner of Java, I was taught to use "ArrayList" in OO programming in the Java lecture, however, I came across "List" today and have no idea how to use it, so what the difference between ArrayList and List? And what the same attributes of them?
something like:
List<...>list=new List<...>()
ArrayList<...>list=new ArrayList<...>()
List is an interface, whereas ArrayList is a concrete class that implements that interface
List is an interface.
ArrayList is a class that implements List.
You can't instantiate an interface, you have to instantiate one of classes which implements it.
List defines the basic contract that is expected that implementations would provide. ArrayList is a implementation of this contract that is backed by a dynamic array.
The great thing about this idea is, if you have a method that needs access to some kind of List, you can simply ask that callers pass you any implementation of List, meaning you don't need to know or care how the List is actually implemented, only that it will provide the contract described by List
You can't create an instance of List directly, you need to use one of the implementations, like ArrayList or LinkedList...
For example...
List<String> listOfStrings = new ArrayList<String>(25);
List<String> anotherListOfStrings = new LinkedList<String>();
List is an interface, essentially providing a list of operations (add, remove, get...), but no implementation (you cannot do new List). There are several classes implementing List interface, including ArrayList (using, as said, an array as internal container) and, for instance, LinkedList. You can instantiate these, instead, and write:
List<ElementType> myList = new ArrayList<ElementType>();
Using List as a type for myList reduces the effort if you want to replace ArrayList with LinkedList:
List<ElementType> myList = new LinkedList<ElementType>();
(immagine, instead, if you had to replace ArrayList with LinkedList in several places, instead). Additionally, you will hide the actual implementation lying behind, so that other programmers don't make tricky assumptions on how the List might behave.

Categories