How to initialize List<String> object in Java? - java

I can not initialize a List as in the following code:
List<String> supplierNames = new List<String>();
supplierNames.add("sup1");
supplierNames.add("sup2");
supplierNames.add("sup3");
System.out.println(supplierNames.get(1));
I face the following error:
Cannot instantiate the type List<String>
How can I instantiate List<String>?

If you check the API for List you'll notice it says:
Interface List<E>
Being an interface means it cannot be instantiated (no new List() is possible).
If you check that link, you'll find some classes that implement List:
All Known Implementing Classes:
AbstractList, AbstractSequentialList, ArrayList, AttributeList, CopyOnWriteArrayList, LinkedList, RoleList, RoleUnresolvedList, Stack, Vector
Some of those can be instantiated (the ones that are not defined as abstract class). Use their links to know more about them, I.E: to know which fits better your needs.
The 3 most commonly used ones probably are:
List<String> supplierNames1 = new ArrayList<String>();
List<String> supplierNames2 = new LinkedList<String>();
List<String> supplierNames3 = new Vector<String>();
Bonus:
You can also instantiate it with values, in an easier way, using the Arrays class, as follows:
List<String> supplierNames = Arrays.asList("sup1", "sup2", "sup3");
System.out.println(supplierNames.get(1));
But note you are not allowed to add more elements to that list, as it's fixed-size.

Can't instantiate an interface but there are few implementations:
JDK2
List<String> list = Arrays.asList("one", "two", "three");
JDK7
//diamond operator
List<String> list = new ArrayList<>();
list.add("one");
list.add("two");
list.add("three");
JDK8
List<String> list = Stream.of("one", "two", "three").collect(Collectors.toList());
JDK9
// creates immutable lists, so you can't modify such list
List<String> immutableList = List.of("one", "two", "three");
// if we want mutable list we can copy content of immutable list
// to mutable one for instance via copy-constructor (which creates shallow copy)
List<String> mutableList = new ArrayList<>(List.of("one", "two", "three"));
Plus there are lots of other ways supplied by other libraries like Guava.
List<String> list = Lists.newArrayList("one", "two", "three");

List is an Interface, you cannot instantiate an Interface, because interface is a convention, what methods should have your classes. In order to instantiate, you need some realizations(implementations) of that interface. Try the below code with very popular implementations of List interface:
List<String> supplierNames = new ArrayList<String>();
or
List<String> supplierNames = new LinkedList<String>();

You will need to use ArrayList<String> or such.
List<String> is an interface.
Use this:
import java.util.ArrayList;
...
List<String> supplierNames = new ArrayList<String>();

List is an interface, and you can not initialize an interface. Instantiate an implementing class instead.
Like:
List<String> abc = new ArrayList<String>();
List<String> xyz = new LinkedList<String>();

In most cases you want simple ArrayList - an implementation of List
Before JDK version 7
List<String> list = new ArrayList<String>();
JDK 7 and later you can use the diamond operator
List<String> list = new ArrayList<>();
Further informations are written here Oracle documentation - Collections

List is just an interface, a definition of some generic list. You need to provide an implementation of this list interface. Two most common are:
ArrayList - a list implemented over an array
List<String> supplierNames = new ArrayList<String>();
LinkedList - a list implemented like an interconnected chain of elements
List<String> supplierNames = new LinkedList<String>();

Depending on what kind of List you want to use, something like
List<String> supplierNames = new ArrayList<String>();
should get you going.
List is the interface, ArrayList is one implementation of the List interface. More implementations that may better suit your needs can be found by reading the JavaDocs of the List interface.

If you just want to create an immutable List<T> with only one object in it, you can use this API:
List<String> oneObjectList = Collections.singletonList("theOnlyObjectā€¯);
More info: docs

List is an Interface . You cant use List to initialize it.
List<String> supplierNames = new ArrayList<String>();
These are the some of List impelemented classes,
ArrayList, LinkedList, Vector
You could use any of this as per your requirement. These each classes have its own features.

Just in case, any one still lingering around this question. Because, i see one or two new users again asking the same question and everyone telling then , No you can't do that, Dear Prudence, Apart from all the answers given here, I would like to provide additional Information -
Yes you can actually do, List list = new List();
But at the cost of writing implementations of all the methods of Interfaces.
The notion is not simply List list = new List(); but
List<Integer> list = new List<Integer>(){
#Override
public int size() {
// TODO Auto-generated method stub
return 0;
}
#Override
public boolean isEmpty() {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean contains(Object o) {
// TODO Auto-generated method stub
return false;
}
..... and So on (Cant write all methods.)
This is an example of Anonymous class. Its correct when someone states , No you cant instantiate an interface, and that's right. But you can never say , You CANT write List list = new List(); but, evidently you can do that and that's a hard statement to make that You can't do.

Instead of :
List<String> supplierNames = new List<String>();
Write this if you are using latest JDK:
List<String> supplierNames = new ArrayList<>();
It's the correct way of initializing a List.

We created soyuz-to to simplify 1 problem: how to convert X to Y (e.g. String to Integer). Constructing of an object is also kind of conversion so it has a simple function to construct Map, List, Set:
import io.thedocs.soyuz.to;
List<String> names = to.list("John", "Fedor");
Please check it - it has a lot of other useful features

Related

How to add ArrayList elements in TreeSet or TreeMap

As we all know, we need to implement Comparable interface and add compareTo() when we work with TreeSet. Not doing so will throw ClassCastException.
Now I have a TreeSet and I need to add ArrayLists as elements of TreeSet.
if we write:
ArrayList al = new ArrayList();
ArrayList al2 = new ArrayList();
ArrayList al3 = new ArrayList();
TreeSet ts = new TreeSet();
ts.add(al);
ts.add(al2);
ts.add(al3);
It throws ClassCastException.
Question: How can I add ArrayList istances (not their elements) to a TreeSet or TreeMap?
If you really need to add array list (as an instance) and not its elements, you should use another constructor rather than the empty one, consider the constructor taking as a parameter a Comparator.
TreeSet(Comparator<? super E> comparator)
Constructs a new, empty tree set, sorted according to the specified comparator.
You can define upfront a Comparator for your purpose with the meaning you actually want with regards to the concerned arraylists.
Then add the array list instances, which will properly compared according to your comparator.
As an example, you can define a Comparator which would compare array lists based on their size (sample simple comparison):
public class MyArrayListComparator implements java.util.Comparator<ArrayList> {
public int compare(ArrayList al1, ArrayList al2) {
if (al1.size() > al2.size())
return 1;
if (al1.size() < al2.size())
return -1;
return 0;
}
}
Then in your code:
ArrayList al = new ArrayList();
ArrayList al2 = new ArrayList();
ArrayList al3 = new ArrayList();
TreeSet ts = new TreeSet(new MyArrayListComparator());
ts.add(al);
ts.add(al2);
ts.add(al3);
Note the
TreeSet ts = new TreeSet(new MyArrayListComparator());
This is actually a good example of the difference between Comparable and Comparator:
Comparable is implemented by the class you want to use, with a specific behavior and you cannot change it or add it
Comparator is an external implementation you can add (if supported by the concerned consumer) with the behavior you want
Check also this SO Q/A for further details on Comparable vs Comparator.
Currently you are adding ArrayList objects and not the elements within them. As described in another answer, using the addAll will work because ultimately it will go through each ArrayList and add the individual elements.
1) As said before, you are adding ArrayList to TreeSet, not an element inside ArrayList.
al.add(__something__);
ts.add(al.get(__something-to-get-your-element-from-al__));
2) It's not recommended to use raw types, as Lists and Sets are generic types:
List<String> al = new ArrayList();
Set<String> ts = new TreeSet();
al.add("hello");
al.add("hello2");
ts.add(al.get(0));
ts.add(al.get(1));
or:
ts.addAll(al); //which will add to your TreeSet all the elements that are in the ArrayList.
EDIT: 3) probably you want to add ArrayList to TreeSet, then you have to declare the set like this:
List<String> al = new ArrayList();
//add elements to al
Set<List<String>> ts = new TreeSet();
ts.add(al);

Unmodifiable List of modifiable objects

Let's say we have got a List<List<String>> and want to make it completely unmodifiable. Simply passing it to a Collection.unmodifiableList would not suffice because the inner Lists can still be modified.
I would go with the following approach:
List<List<String>> someList;
Make it unmodifiable:
List<List<String>> tempList = new ArrayList<>();
for(List<String> strList : someList) {
tempList.add(Collections.unmodifiableList(strList));
}
List<List<String>> safeList = Collections.unmodifiableList(tempList);
Is this approach okay?
This approach should work, as long as you don't keep references to the original, modifiable, lists. Such references could modify the lists wrapped by the unmodifiable lists.
The below code should do :-
List<List<String>> tempList = new ArrayList<>();
for(List<String> strList : someList) {
tempList.add(new ArrayList<>(strList));
}
List<List<String>> safeList = Collections.unmodifiableList(tempList);
Here goes the test for this :-
List<List<String>> someList = new ArrayList<>();
List<String> l1 = new ArrayList<String>();
List<String> l2 = new ArrayList<String>();
l1.add("STR1");
l1.add("STR2");
l1.add("STR3");
l2.add("STR4");
l2.add("STR5");
l2.add("STR6");
someList.add(l1);
someList.add(l2);
List<List<String>> tempList = new ArrayList<>();
for(List<String> strList : someList) {
tempList.add(new ArrayList<>(strList));
}
List<List<String>> safeList = Collections.unmodifiableList(tempList);
l1.add("STR7"); // The inner list reference is modified this doesnot cause the safelist internal structure to get changed
for(List<String> safeInnerList : safeList) {
System.out.println(safeInnerList);
}
I feel it doesnot work:-
List<List<String>> someList = new ArrayList<>();
List<String> l1 = new ArrayList<String>();
List<String> l2 = new ArrayList<String>();
l1.add("STR1");
l1.add("STR2");
l1.add("STR3");
l2.add("STR4");
l2.add("STR5");
l2.add("STR6");
someList.add(l1);
someList.add(l2);
List<List<String>> tempList = new ArrayList<>();
for(List<String> strList : someList) {
tempList.add(Collections.unmodifiableList(strList));
}
List<List<String>> safeList = Collections.unmodifiableList(tempList);
l1.add("STR7"); // The inner list reference is modified which causes the
safelist internal structure to get changed
for(List<String> safeInnerList : safeList) {
System.out.println(safeInnerList);
}
The way to achieve immutability is to create defensive copies.
Data in
Whenever a mutable object is passed to your method(s), you create a deep copy of it. This should be the first thing you do, even before you check validity, if you want maximum security.
Wrapping a list into a Collections.unmodifiableList() isn't going to work here because there's no guarantee that the underlying list won't be modified by a third party. In other words, you're not in control of the instance.
A good way of creating immutable copies of lists is by using Google Guava's ImmutableList.copyOf() method, but remember that you need a deep copy, so you need to create immutable copies of the lists within the main list.
Data out
whenever you return a value, you make another defensive copy, so that changes to the returned object don't reflect back. Here you can use unmodifiable wrappers (e.g. ImmutableList.of()) on your lists because you're holding the only reference to the original list.
If you do both (copy on the way in, copy/wrap on the way out), your code will be safe and correct. Any other solution and no such general guarantees can be given, your code may or many not be correct.

How to correctly specify a list in java

I am using Eclipse Juno and Java.
I want to create a list and then store that list in another list so I can pass the list of lists to the server side. I have tried:
ArrayList<T> listAccountAndCubs = new ArrayList<Comparable>();
listAccountAndCubs.add(accountId);
listAccountAndCubs.add(sqlDateArchived);
However, I can not get the values "T" and "Comparable" correct. I tried "String" however that does not work for storing the date.
Once the above is correct how do I set up the list to contain "listAccountAndCubs"?
Thanks for any assistance,
Glyn
this is how you can create a list
List<String> l = new ArrayList<String>();
this is how you can create list of list
List<List<Comparable>> listOfList = new ArrayList<List<Comparable>>();
listOfList.add(new ArrayList<Comparable>());
...
Sounds like you want something like this
List<List<String>> listAccountAndCubs = new ArrayList<List<String>>();
I would recomment using Google Guava library to clean the syntax a bit
List<List<String>> listAccountAndCubs = Lists.newArrayList();
List<ArrayList<Comparable>> listAccountAndCubs = new ArrayList<>();
or
List<String> l1=new ArrayList<>();
List<List<String>> l2=new ArrayList<>();
l1.add("a");
l2.add(l1);
If I understand you crrectly you want to have a list of Strings, and store this in another list?
List<String> sl = new ArrayList<String>();
List<List<String>>sls = new ArrayList<List<String>>();
sls.add(sl);
sl.add("String 1");
The value "T" is just a placeholder for the type, as the list is a generic interface, which can take any arbitrary object.
If you want to create a list of unspecified types, you would use
List<?>list = new ArrayList<?>();
Then you can add untyped objects to it, but in your case this is not neccessary.
Instead you can of course also create a list of comparables. Like this:
List<Comparable<String>>list = new ArrayList<Comparable<String>>();

How to cast ArrayList<> from List<>

Can somebody please explain me why I can't cast List<> to ArrayList<> with first approach and I do with second one? Thank you.
First approach:
ArrayList<Task> tmp = ((ArrayList<Task>)mTrackytAdapter.getAllTasks(token));
Second approach:
ArrayList<Task> tmp = new ArrayList<Task>(mTrackytAdapter.getAllTasks(token));
When you do the second one, you're making a new arraylist, you're not trying to pretend the other list is an arraylist.
I mean, what if the original list is implemented as a linkedlist, or some custom list? You won't know. The second approach is preferred if you really need to make an arraylist from the result. But you can just leave it as a list, that's one of the best advantages of using Interfaces!
When you are using second approach you are initializing arraylist with its predefined values.
Like generally we do
**ArrayList listofStrings = new ArrayList<>();
**
Let's say you have an array with values, now you want to convert this array into arraylist.
you need to first get the list from the array using Arrays utils.
Because the ArrayList is concrete type that implement List interface. It is not guaranteed that method asList, will return this type of implementation.
List<String> listofOptions = (List<String>) Arrays.asList(options);
then you can user constructoru of an arraylist to instantiate with predefined values.
ArrayList<String> arrlistofOptions = new ArrayList<String>(list);
So your second approach is working that you have passed values which will intantiate arraylist with the list elements.
More over
ArrayList that is returned from Arrays.asList is not an actual arraylist, it is just a wrapper which doesnt allows any modification in the list.
If you try to add or remove over Arrays.asList it will give you
UnsupportedOperationException
Try running the following code:
List<String> listOfString = Arrays.asList("Hello", "World");
ArrayList<String> arrayListOfString = new ArrayList(listOfString);
System.out.println(listOfString.getClass());
System.out.println(arrayListOfString.getClass());
You'll get the following result:
class java.util.Arrays$ArrayList
class java.util.ArrayList
So, that means they're 2 different classes that aren't extending each other. java.util.Arrays$ArrayList signifies the private class named ArrayList (inner class of Arrays class) and java.util.ArrayList signifies the public class named ArrayList. Thus, casting from java.util.Arrays$ArrayList to java.util.ArrayList and vice versa are irrelevant/not available.
The second approach is clearly wrong if you want to cast. It instantiate a new ArrayList.
However the first approach should work just fine, if and only if getAllTasks return an ArrayList.
It is really needed for you to have an ArrayList ? isn't the List interface enough ? What you are doing can leads to Runtime Exception if the type isn't correct.
If getAllTasks() return an ArrayList you should change the return type in the class definition and then you won't need a cast and if it's returning something else, you can't cast to ArrayList.
Just try this :
ArrayList<SomeClass> arrayList;
public SomeConstructor(List<SomeClass> listData) {
arrayList.addAll(listData);
}
You can cast List<> to ArrayList<> if you understand what you doing. Java compiler won't block it.
But:
It's bad practice to casting parent type to child type (or interface to implementation type) without checking.
This way better:
if (list instanceof ArrayList<Task>) {
ArrayList<Task> arraylist = (ArrayList<Task>) list;
}
Maybe you don't need implementation type as reference. Look SonarQube warning https://sbforge.org/sonar/rules/show/squid:S1319. You can avoid this casting in the most cases.
You can use Guava method:
ArrayList<Task> arraylist = Lists.newArrayList(list);
The first approach is trying to cast the list but this would work only if the List<> were an ArrayList<>. That is not the case. So you need the second approach, that is building a new ArrayList<> with the elements of the List<>
Because in the first one , you're trying to convert a collection to an ArrayList.
In the 2nd one , you just use the built in constructor of ArrayList
May be:
ArrayList<ServiceModel> services = new ArrayList<>(parking.getServices());
intent.putExtra("servicios",services);
import java.util.List;
import java.util.Arrays;
import java.util.*;
public class Merge
{
public static void main(String[] args) {
// This is normal way
// List<Integer> l1 = new ArrayList<Integer>(); l1.add(2); l1.add(5); l1.add(10); l1.add(22);
// List<Integer> l2 = new ArrayList<Integer>(); l2.add(3); l2.add(8); l2.add(15);
//Array.asList only have the list interface, but ArrayList is inherited from List Interface with few more property like ArrayList.remove()
List<Integer> templ1 = Arrays.asList(2,5,10,22);
List<Integer> templ2 = Arrays.asList(3,8,12);
//So creation of ArrayList with the given list is required, then only ArrayList.remove function works.
List<Integer> l1 = new ArrayList<Integer>(templ1);
List<Integer> l2 = new ArrayList<Integer>(templ2);
List<Integer> l3 = new ArrayList<Integer>();
Iterator itr1 = l1.iterator();
while(itr1.hasNext()){
int x = (Integer) itr1.next();
Iterator itr2 = l2.iterator();
while(itr2.hasNext()) {
int y = (Integer) itr2.next();
if(x < y) {
l3.add(x);
break;
}
else{
l3.add(y);
itr2.remove();
}
}
}
Iterator it = l1.iterator();
while (it.hasNext()){
int k = (Integer) it.next();
if (l3.contains(k)){
continue;
}
else{
l3.add(k);
System.out.println(k);
}
}
Iterator itr2 = l2.iterator();
while (itr2.hasNext()){
int k = (Integer) itr2.next();
l3.add(k);
}
System.out.println(l3);
}
}

Java Get Multiple Items From Collection

Do Java collections have a built-in method to return multiple items from that collection? For example, the list below has n elements, some of which are duplicated in the list. How could I get all elements where the value = "one"? I realize it would be very easy to write my own method to achieve such functionality, I just wanted to make sure I am not missing a built in method to do this.
List<String> ls=new ArrayList<String>();
ls.add("one");
ls.add("two");
ls.add("three");
ls.add("one");
ls.add("one");
//some type of built in function????
//ls.getItems("one");
//should return elements 0,3,4
Thanks
Google Collections have Predicates for this purpose.
In this example, it's enough to know the number of times "one" appears in the list, which you can get with java.util.Collections.frequency(ls, "one").
You could also have been using a Multiset from google-collections, and called m.count("one"), which would be much more efficient.
There isn't a built-in method, but Apache Commons has a select method in CollectionUtils that will get all the elements that match some criterion. Example usage:
List<String> l = new ArrayList<String>();
// add some elements...
// Get all the strings that start with the letter "e".
Collection beginsWithE = CollectionUtils.select(l, new Predicate() {
public boolean evaluate(Object o) {
return ((String) o).toLowerCase().startsWith("e");
}
);
I think you could do the trick of retaining the elements of this list which are in another list with the retainall method of Collection class link text. In the other list you can add only the "one" object.
List<String> ls=new ArrayList<String>();
ls.add("one");
ls.add("two");
ls.add("three");
ls.add("one");
ls.add("one");
List<String> listToCompare = new ArrayList<String>();
listToCompare.add("one");
ls.retainAll(listToCompare);

Categories

Resources