Will
ArrayList<int>(20);
create a maximum of 20 array or is it an illegal syntax?
This will not compile since the element type cannot be a primitive. Use Integer instead.
new ArrayList<Integer>(20); will create a list backed by an array with an initial capacity of 20.
Perhaps you should read API documentation for ArrayList first.
You can create an ArrayList instance like this:
List<Integer> list = new ArrayList<Integer>(20);
In this case, 20 is initial capacity.
From Java7, you can omit the parameterized type.
List<Integer> list = new ArrayList<>(20);
You can't use primitive type as type parameter. Why don't Java Generics support primitive types? also helpful.
ArrayList<int>(20); is illegal, since you can't use primitives as generic types nor put them into the standard collections.
ArrayList<Integer>(20); would create a list with a basic capacity of 20 integer objects but it can be resized as needed.
Assuming that you change int to Integer (You can't use generics with primitives), that will create an ArrayList of initial size 20.
It can still grow past that limit, as per the JavaDocs at http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html#ArrayList(int):
Constructs an empty list with the specified initial capacity.
If your question is about the memory allocation part and considering you use a syntax like:
ArrayList<Integer> arr = new ArrayList<Integer>(20);
It just allocates memory for 20 Integer. It still an empty ArrayList though.
This is intended to be used for performance reasons but for most common situation there isn't a big difference (without the memory preallocation that is).
Generally we should use the default constructor for any Collection object If we don't know the required size. Because think about the situation you are creating an ArrayList of size 500 but actually you are adding only 5 items into it. That is not recommended.
We can not use primitives in Generics for type safety in Collections. This restriction is for providing backward compatibility to older version java codes(Older than 1.5).
For more details kindly have a look here: Link 1, Link 2, Link 3, Link 5
Related
Is an ArrayList is just the interface for a dynamic array? Or are they the same thing?
like: ArrayList corresponds to dynamic array, HashMap corresponds to Map ?
except I don't see any Java API for something like a dynamic array, unless it is ArrayList?
Yes. In short. A longer explanation is that an ArrayList is a collection that uses arrays for storage, rather than a linked list, doubly linked list or similar. This means that it gives all the benefits of using an Array, whilst Java looks after the mechanics of sizing the Array for you (dynamically).
I seem to remember that the initial array is created with a default maximum size (which can be specified by the user). Should the collection run out of space, then a larger array is created and the contents of the original array copied into the new one. The increment in size is set to prevent this happening too often, as the operation is fairly costly.
Java also offers the Vector collection which is similar, but is also thread safe, see: What are the differences between ArrayList and Vector?.
ArrayList is the resizable-array implementation of the List interface.
So that's probably what you are looking for if you need a dynamic array.
ArrayList is not a dynamic array, it's not an array type dynamic or not, it's just one of the implementations of the List interface. Understand the difference between classes and interfaces. On the other hand arrays are container objects with the fixed size.
If in the dynamic sense you mean an array which can change in size then a List is an interface for a dynamic array. It is named ArrayList because it uses an array internally that's all.
Your analogy does not fit in the java collections framework since you can say that an ArrayList is a dynamic array but Map (or HashMap for that matter) does not have a "primitive" counterpart.
If by 'dynamic array' you mean an array in C++, then all arrays in Java are dynamic and stored on heap. ArrayList is a resizable wrapper for it. It also provides simple consistency checks - i.e. that you don't modify your array from outside during iteration.
In C++ i can insert an item into an arbitrary position in a vector, just like the code below:
std::vector<int> vec(10);
vec.insert(vec.begin()+2,2);
vec.insert(vec.begin()+4,3);
In Java i can not do the same, i get an exception java.lang.ArrayIndexOutOfBoundsException, code below:
Vector l5 = new Vector(10);
l5.add(0, 1);
l5.add(1, "Test");
l5.add(3, "test");
It means that C++ is better designed or is just a Java design decision ?
Why java use this approach ?
In the C++ code:
std::vector<int> vec(10);
You are creating a vector of size 10. So all indexes from 0 to 9 are valid afterwards.
In the Java code:
Vector l5 = new Vector(10);
You are creating an empty vector with an initial capacity of 10. It means the underlying array is of size 10 but the vector itself has the size 0.
It does not mean one is better designed than the other. The API is just different and this is not a difference that makes one better than the other.
Note that in Java it is now preffered to use ArrayList, which has almost the same API, but is not synchronized. If you want to find a bad design decision in Java's Vector, then this synchronization on every operation was probably one.
Therefore the best way to write an equivalent of the C++ initialization code in Java is :
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < 10; i++){
list.add(new Integer());
}
The Javadoc for Vector.add(int, Object) pretty clearly states that an IndexOutOfBoundsException will be thrown if the index is less than zero or greater than or equal to the size. The Vector type grows as needed, and the constructor you've used sets the initial capacity, which is different than the size. Please read the linked Javadoc to better understand how to use the Vector type. Also, we java developers typically use a List type, such as ArrayList in situations where you would generally use a std::vector in C++.
Differences? You cannot compare how 2 languages do those. Normally Vector do use Stack data structure or LinkedList (or may be both). Which means, you put one item to the top, put another item on top of it, another item even on top of it, like wise. In LinkedList, it is bit different, you "pull" the value but the same thing. So in C++ it is better to use push_back() method.
C++ Vector objects are instantiated automatically. But in Java it is not, you have to fill it. I disagree with the way of filling it using l5.add(1, "Test");. Use l5.add("test").
Since you asked differences, you can define your object in this way as well
Vector a = new Vector();
That is without a type, in Java we call it without Generics. Possible since Java 1.6
Vector is now not widely used in Java. It has delays. We now move with ArrayList which is inside List interface.
Edit
variable names such as l5 are widely used in C++. But Java community expects more meaningful variable names :)
I need an array of Hashtables in a program that is storing all words from a given set of documents.
Index 1 of the array holds a hashtable of String -> Double which stores a word, and its count for document 1 (array index 100 = document number 100's hashtable).
I dont need help using this data structure, just in creating it.
I declare the Hashtable Array as follows:
Hashtable<String,Double>[] h1 = new Hashtable<String,Double>[];
... but this does not compile.
(NOTE: The Double is necessary rather than an Integer in the above declaration for later usage.)
QUESTION:
How do you create an array of hashtables which stores String->Double ???
Any suggestions appreciated guys....
... but this does not compile.
That's because the array has no name, new expects a number of elements and you can't just allocate an array of generics. Prefer a List instead:
List<Hashtable<String,Double>> wordCountPerDoc
= new ArrayList<Hashtable<String,Double>>();
just use
#SuppressWarnings("unchecked")
Hashtable<String,Double>[] h = (Hashtable<String,Double>[])new Hashtable<?,?>[10];
h[0] = new Hashtable<String, Double>();
why don't you use a Map<Integer, Map<String, Double> > ?
this way you don't waste space for non-existing documents, and still get O(1) retrieval.
you can create like this.
Hashtable<String,Double>[] arr = new Hashtable[10];
Two things: you can't declare an array with the parameterized types like that; you have to imply declare it a new Hashtable[]. And you need to give the array a length.
Mixing arrays and Collections, although possible, tends to be confusing and lead to problems in my experience; also HashMap is generally preferred to Hashtable. So I would tend to prefer a List<Map<String, Double>> for this application.
The reasons why this is an error are covered in Angelika Langer's Generics FAQ: Can I create an array whose component type is a concrete parameterized type?
Can I create an array whose component type is a concrete parameterized type?
No, because it is not type-safe.
Arrays are covariant, which means that
an array of supertype references is a
supertype of an array of subtype
references. That is, Object[] is a
supertype of String[] and a string
array can be accessed through a
reference variable of type Object[].
Arrays and generics can have odd interactions (largely due to implementation compromises to support compatibility). You may be better off (as larsmans suggested) looking at a suitable collection type such as a List of Maps.
An array seems to be an unusual choice of structure here. Perhaps you should consider storing your hashtables in a List. It will dynamically resize for you if you don't know how many document you will have ahead of time. If you use an ArrayList, you will still have constant-time reads of random indeces (like an array.) I think it's much simpler than using an array, and you still get the generic type checking. If you choose a List, you syntax becomes:
List<Map<String,Double>> documentWordCounts = new ArrayList<Map<String,Double>>();
Or choose a LinkedList depending on what kind of read/write pattern you want.
For fixed size array:
Hashtable<String,Double>[] h1 = new Hashtable[]{new Hashtable< String,Double>(),new Hashtable< String,Double>(),new Hashtable< String,Double>()};
Is it advisable to use Java Collections List in the cases when you know the size of the list before hand and you can also use array there? Are there any performance drawbacks?
Can a list be initialised with elements in a single statement like an array (list of all elements separated by commas) ?
Is it advisable to use Java Collections List in the cases when you know the size of the list before hand and you can also use array there ?
In some (probably most) circumstances yes, it is definitely advisable to use collections anyway, in some circumstances it is not advisable.
On the pro side:
If you use an List instead of an array, your code can use methods like contains, insert, remove and so on.
A lot of library classes expect collection-typed arguments.
You don't need to worry that the next version of the code may require a more dynamically sized array ... which would make an initial array-based approach a liability.
On the con side:
Collections are a bit slower, and more so if the base type of your array is a primitive type.
Collections do take more memory, especially if the base type of your array is a primitive type.
But performance is rarely a critical issue, and in many cases the performance difference is not relevant to the big picture.
And in practice, there is often a cost in performance and/or code complexity involved in working out what the array's size should be. (Consider the hypothetical case where you used a char[] to hold the concatenation of a series. You can work out how big the array needs to be; e.g. by adding up the component string sizes. But it is messy!)
Collections/lists are more flexible and provide more utility methods. For most situations, any performance overhead is negligible.
And for this single statement initialization, use:
Arrays.asList(yourArray);
From the docs:
Returns a fixed-size list backed by the specified array. (Changes to the returned list "write through" to the array.) This method acts as bridge between array-based and collection-based APIs, in combination with Collection.toArray. The returned list is serializable and implements RandomAccess.
My guess is that this is the most performance-wise way to convert to a list, but I may be wrong.
1) a Collection is the most basic type and only implies there is a collection of objects. If there is no order or duplication use java.util.Set, if there is possible duplication and ordering use java.util.List, is there is ordering but no duplication use java.util.SortedSet
2) Curly brackets to instantiate an Array, Arrays.asList() plus generics for the type inference
List<String> myStrings = Arrays.asList(new String[]{"one", "two", "three"});
There is also a trick using anonymous types but personally I'm not a big fan:
List<String> myStrings = new ArrayList<String>(){
// this is the inside of an anonymouse class
{
// this is the inside of an instance block in the anonymous class
this.add("one");
this.add("two");
this.add("three");
}};
Yes, it is advisable.
Some of the various list constructors (like ArrayList) even take arguments so you can "pre-allocate" sufficient backing storage, alleviating the need for the list to "grow" to the proper size as you add elements.
There are different things to consider: Is the type of the array known? Who accesses the array?
There are several issues with arrays, e.g.:
you can not create generic arrays
arrays are covariant: if A extends B -> A[] extends B[], which can lead to ArrayStoreExceptions
you cannot make the fields of an array immutable
...
Also see, item 25 "Prefer lists to arrays" of the Effective Java book.
That said, sometimes arrays are convenient, e.g. the new Object... parameter syntax.
How can a list be initialised with elements in a single statement like an array = {list of all elements separated by commas} ?
Arrays.asList(): http://download.oracle.com/javase/6/docs/api/java/util/Arrays.html#asList%28T...%29
Is it advisable to use Java Collections List in the cases when you know the size of the list before hand and you can also use array there ? Performance drawbacks ???
If an array is enough, then use an array. Just to keep things simple. You may even get a slightly better performance out of it. Keep in mind that if you...
ever need to pass the resulting array to a method that takes a Collection, or
if you ever need to work with List-methods such as .contains, .lastIndexOf, or what not, or
if you need to use Collections methods, such as reverse...
then may just as well go for the Collection/List classes from the beginning.
How can a list be initialised with elements in a single statement like an array = {list of all elements separated by commas} ?
You can do
List<String> list = Arrays.asList("foo", "bar");
or
List<String> arrayList = new ArrayList<String>(Arrays.asList("foo", "bar"));
or
List<String> list = new ArrayList<String>() {{ add("foo"); add("bar"); }};
Is it advisable to use Java
Collections List in the cases when you
know the size of the list before hand
and you can also use array there ?
Performance drawbacks ?
It can be perfectly acceptable to use a List instead of an array, even if you know the size before hand.
How can a list be initialised with
elements in a single statement like an
array = {list of all elements
separated by commas} ?
See Arrays.asList().
In Java, when would it be preferential to use a List rather than an Array?
I see the question as being the opposite-
When should you use an Array over a List?
Only you have a specific reason to do so (eg: Project Constraints, Memory Concerns (not really a good reason), etc.)
Lists are much easier to use (imo), and have much more functionality.
Note: You should also consider whether or not something like a Set, or another datastructure is a better fit than a List for what you are trying to do.
Each datastructure, and implmentation, has different pros/cons. Pick the ones that excel at the things that you need to do.
If you need get() to be O(1) for any item? Likely use an ArrayList, Need O(1) insert()? Possibly a Linked List. Need O(1) contains()? Possibly a Hashset.
TLDR: Each data structure is good at some things, and bad at others. Look at your objectives and choose the data structure that best fits the given problem.
Edit:
One thing not noted is that you're
better off declaring the variable as
its interface (i.e. List or Queue)
rather than its implementing class.
This way, you can change the
implementation at some later date
without changing anything else in the
code.
As an example:
List<String> myList = new ArrayList<String>();
vs
List<String> myList = new LinkedList<String>();
Note that myList is a List in both examples.
--R. Bemrose
Rules of thumb:
Use a List for reference types.
Use arrays for primitives.
If you have to deal with an API that is using arrays, it might be useful to use arrays. OTOH, it may be useful to enforce defensive copying with the type system by using Lists.
If you are doing a lot of List type operations on the sequence and it is not in a performance/memory critical section, then use List.
Low-level optimisations may use arrays. Expect nastiness with low-level optimisations.
Most people have answered it already.
There are almost no good reason to use an array instead of List. The main exception being the primitive array (like int[]). You cannot create a primitive list (must have List<Integer>).
The most important difference is that when using List you can decide what implementation will be used. The most obvious is to chose LinkedList or ArrayList.
I would like to point out in this answer that choosing the implementation gives you very fine grained control over the data that is simply not available to array:
You can prevent client from modifying your list by wrapping your list in a Collection.unmodifiableList
You can synchronize a list for multithreading using Collection.synchronizedList
You can create a fixed length queue with implementation of LinkedBlockingQueue
... etc
In any case, even if you don't want (now) any extra feature of the list. Just use an ArrayList and size it with the size of the array you would have created. It will use an Array in the back-end and the performance difference with a real array will be negligible. (except for primitive arrays)
Pretty much always prefer a list. Lists have much more functionality, particularly iterator support. You can convert a list to an array at any time with the toArray() method.
Always prefer lists.
Arrays when
Varargs for a method ( I guess you are forced to use Arrays here ).
When you want your collections to be covariant ( arrays of reference types are covariant ).
Performance critical code.
If you know how many things you'll be holding, you'll want an array. My screen is 1024x768, and a buffer of pixels for that isn't going to change in size ever during runtime.
If you know you'll need to access specific indexes (go get item #763!), use an array or array-backed list.
If you need to add or remove items from the group regularly, use a linked list.
In general, dealing with hardware, arrays, dealing with users, lists.
It depends on what kind of List.
It's better to use a LinkedList if you know you'll be inserting many elements in positions other than the end. LinkedList is not suitable for random access (getting the i'th element).
It's better to use an ArrayList if you don't know, in advance, how many elements there are going to be. The ArrayList correctly amortizes the cost of growing the backing array as you add more elements to it, and is suitable for random access once the elements are in place. An ArrayList can be efficiently sorted.
If you want the array of items to expand (i.e. if you don't know what the size of the list will be beforehand), a List will be beneficial. However, if you want performance, you would generally use an array.
In many cases the type of collection used is an implementation detail which shouldn't be exposed to the outside world. The more generic your returntype is the more flexibility you have changing the implementation afterwards.
Arrays (primitive type, ie. new int[10]) are not generic, you won't be able to change you implementation without an internal conversion or altering the client code. You might want to consider Iterable as a returntype.