How do I find the size of an ArrayList in Java? I do not mean the number of elements, but the number of indexes.
public static void main(String[] args) {
ArrayList hash = new ArrayList(5);
System.out.println(hash.size());
}
Prints out "0." Using:
System.out.println(hash.toArray().length);
Also prints out a "0."
I have looked in http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html but I do not see a method that will help me. Is my ArrayList reverting to a size of 0 if I do not add anything to it?
EDIT The assignment is to create a hash table using ArrayList. I am supposed to create a hash function using the formula
double hashkey = Math.floor(hash.size()*(Math.E*key-Math.floor(Math.E*key)));
Where key is an integer. hashkey then becomes the index where the value will be stored. I am using hash.size() as a placeholder at the moment, but that value should be the capacity of my ArrayList.
ArrayList.size() will give the current size.That's why hash.size() giving you the current size of your ArrayList hash. It will not give you the capacity.
You just initialized the list. Have not add any elements to your arraylist, that's why its giving 0.
There is no such method in the ArrayList API. The capacity of an ArrayList is hidden by design.
However, I think that your question is based on a misunderstanding.
How do I find the size of an ArrayList in Java? I do not mean the number of elements, but the number of indexes.
In fact, the size of a List, the number of elements in a List, and the number of indexes (i.e. indexable positions) for a List ... are all the same thing.
The capacity of an ArrayList is something different. It is the number of elements that the object could contain, without reallocating the list's backing array. However, the fact that the list has a capacity N does NOT mean that you can index up to N - 1. In fact, you can only index up to size() - 1, irrespective of the capacity.
Now to deal with your examples:
ArrayList list = new ArrayList(5);
System.out.println(list.size());
This prints out zero because the list has zero elements. The ArrayList() and ArrayList(int) constructors both create and return lists that are empty. The list currently has space for 5 elements (because you gave it an initial capacity of 5) but you can't index those slots.
System.out.println(list.toArray().length);
This prints zero because when you copy the list's contents to an array (using toArray()), the array is the same size as the list. By definition.
This does not mean that the list's backing array has changed. On the contrary, it is still big enough to hold 5 elements without reallocation ... just like before.
But ... I hear you say ... the array's length is zero!
Yes, but that is not the backing array! The toArray() method allocates a new array and copies the List contents into that array. It does NOT return the actual backing array.
Maybe you should encapsulate your ArrayList in a class and add another attribute private int capacity in that class as well.
public class AdvancedArrayList<T>
{
private int capacity;
private ArrayList<T> list;
public AdvancedArrayList<T>(int capacity)
{
this.capacity = capacity;
list = new ArrayList<>();
}
public ArrayList<T> getList()
{
return list;
}
public int getCapacity()
{
return capacity;
}
public void addElement(T element)
{
if(list.size() < capacity)
list.add(element);
else
System.out.println("Capacity is full");
}
}
Notice that size is different than capacity.
Related
I want to add a element in specific location of array list For that i tried to initialize the array list with inital capacity.
import java.util.ArrayList;
public class AddInArrayList{
public static void main(String[] args) {
ArrayList list = new ArrayList(4);
Object obj1 = new Object();
list.add(1, obj1);
}
}
OUTPUT
Exception in thread "main" java.lang.IndexOutOfBoundsException:
Index: 1, Size: 0
at java.util.ArrayList.add(ArrayList.java:359)
at AddInArrayList.main(AddInArrayList.java:7)
Is There any way to add a element by specific index location ?
You are confused about the meaning of capacity: the number you pass to the constructor does not set the inital list size.
You can't insert an element at index 1 of an empty list because list slots cannot be empty. If you wanted a function that expands the list before inserting at an index greater than its length, you could use:
static void addAtPos(List list, int index, Object o) {
while (list.size() < index) {
list.add(null);
}
list.add(index, o);
}
That said, ArrayLists are based on arrays which do not perform well with mid-insertion. So a different data structure will almost certainly be better suited to your problem, but you'd have to let us know what you're trying to achieve.
Arrays will not let you to perform insertion at an index which is greater than array.size.
So if you want to associate each item with a number/index it is better to use maps.
Map map = new HashMap<Integer, Object>();
Object obj1 = new Object();
map.put(1, obj1);
You're getting IndexOutOfBoundsException because when you call add(index, value), the value has to be not less than 0 and not bigger than list.size()-1. In your case it should be add(0, obj1).
initial capacity will be used only to set the initial "buffer" size of underlying array. so after calling new ArrayList(4) you list is still empty.
If you know your List will contain about 10_000 elements, create the ArrayList instance with intial capacity c = 10_000 + x. In this way you will avoid expensive ArrayList#grow(newcapacity) (Java 8) calls.
The method ArrayList#add(position, element) could be also called ArrayList#addAndMoveOtherToTheRight(position, element)
I am new to Java. I apologize if I ask a simple thing.
I wrote the below code but it seems that it doesn't initialize properly. because when I print the size of list1 it show the size = 0!! However, it should be 4!
public static class MyClass{
public List <Integer> list1
// Class Constructor
public MyClass(int n){
list1 = new ArrayList <Integer> (n);
System.out.println("Size = " + list1.size() );
// prints Size = 0 !!!why???
}
public void init(int n){
for(int cnt1 = 0; cnt1 < list1.size(); cnt1++){
list1.set(cnt1 , cnt1);
}
}
...}
public static List<Integer> Func1(int n){
MyClass = new myclass (n);
myclass.init(n);
... }
public static void main(String args[]){
int n = 4;
result = Func1 (n);
...}
Why the size of the list1 is 0? It should be 4, because I pass 4 to Func1, and then it creates MyClass object with size n.
I would be thankful if someone can help me about this problem.
Array lists in Java have both a size and a capacity.
Size tells you how many items are there in the list, while
Capacity tells you how many items the list can hold before it needs to resize.
When you call ArrayList(int) constructor, you set the capacity, not the size, of the newly created array list. That is why you see zero printed out when you get the size.
Having a capacity of 4 means that you can add four integers to the list without triggering a resize, yet the list has zero elements until you start adding some data to it.
You have used the ArrayList constructor that determines its initial capacity, not its initial size. The list has a capacity of 4, but nothing has been added yet, so its size is still 0.
Quoting from the linked Javadocs:
Constructs an empty list with the specified initial capacity.
Also, don't use set to add to the list. That method replaces an element that is already there. You must add to the list first (or use the other overloaded add method).
When I do
ArrayList<Integer> arr = new ArrayList<Integer>(10);
arr.set(0, 1);
Java gives me
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.set(Unknown Source)
at HelloWorld.main(HelloWorld.java:13)
Is there an easy way I can pre-reserve the size of ArrayList and then use the indices immediately, just like arrays?
How about this:
ArrayList<Integer> arr = new ArrayList<Integer>(Collections.nCopies(10, 0));
This will initialize arr with 10 zero's. Then you can feel free to use the indexes immediately.
Here's the source from ArrayList:
The constructor:
public ArrayList(int initialCapacity)
{
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);
this.elementData = new Object[initialCapacity];
}
You called set(int, E):
public E set(int index, E element)
{
rangeCheck(index);
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
Set calls rangeCheck(int):
private void rangeCheck(int index)
{
if (index >= size) {
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
}
It may be subtle, but when you called the constructor, despite initializing an Object[], you did not initialize size. Hence, from rangeCheck, you get the IndexOutOfBoundsException, since size is 0. Instead of using set(int, E), you can use add(E e) (adds e of type E to the end of the list, in your case: add(1)) and this won't occur. Or, if it suits you, you could initialize all elements to 0 as suggested in another answer.
I believe the issue here is that although you have suggested the allocated space of entries in the Array, you have not actually created entries.
What does arr.size() return?
I think you need to use the add(T) method instead.
Programming aside, what you are trying to do here is illogical.
Imagine an empty egg carton with space for ten eggs. That is more or less what you have created. Then you tell a super-precise-and-annoying-which-does-exactly-what-you-tell-him robot to replace the 0th egg with another egg. The robot reports an error. Why? He can't replace the 0th egg, because there is no egg there! There is a space reserved for 10 eggs, but there are really no eggs inside!
You could use arr.add(1), which will add 1 in the first empty cell, i.e. the 0-indexed one.
Or you could create your own list:
public static class PresetArrayList<E> extends ArrayList<E> {
private static final long serialVersionUID = 1L;
public PresetArrayList(int initialCapacity) {
super(initialCapacity);
addAll(Collections.nCopies(initialCapacity, (E) null));
}
}
Then:
List<Integer> list = new PresetArrayList<Integer>(5);
list.set(3, 1);
System.out.println(list);
Prints:
[null, null, null, 1, null]
This is not an Java-specific answer but an data structure answer.
You are confusing the Capacity concept with the Count (or Size) one.
Capacity is when you tell the list to reserve/preallocate a number of slots in advance (in this ArrayList case, you are saying to it create an array of 10 positions) in its' internal storage. When this happens, the list still does not have any items.
Size (or Count) is the quantity of items the list really have. In your code, you really doesn't added any item - so the IndexOutOfBoundException is deserved.
While you can't do what you want with arraylist, there is another option: Arrays.asList()
Capacity is used to prepare ArrayLists for expansion. Take the loop
List<Integer> list = new ArrayList<>();
for(final int i = 0; i < 1024; ++i) {
list.add(i);
}
list starts off with a capacity of 10. Therefore it holds a new Integer[10] inside. As the loop adds to the list, the integers are added to that array. When the array is filled and another number is added, a new array is allocated twice the size of the old one, and the old values are copied to the new ones. Adding an item is O(1) at best, and O(N) at worst. But adding N items will take about 2*1024 individual assignments: amortized linear time.
Capacity isn't size. If you haven't added to the array list yet, the size will be zero, and attempting to write into the 3rd element will fail.
Either I'm doing this wrong or i'm not understanding how this method works.
ArrayList<String> a = new ArrayList<String>();
a.ensureCapacity(200);
a.add(190,"test");
System.out.println(a.get(190).toString());
I would have thought that ensureCapacity would let me insert a record with an index up to that value. Is there a different way to do this?
I get an IndexOutOfBounds error on the third line.
No, ensureCapacity doesn't change the logical size of an ArrayList - it changes the capacity, which is the size the list can reach before it next needs to copy values.
You need to be very aware of the difference between a logical size (i.e. all the values in the range [0, size) are accessible, and adding a new element will add it at index size) and the capacity which is more of an implementation detail really - it's the size of the backing array used for storage.
Calling ensureCapacity should only ever make any difference in terms of performance (by avoiding excessive copying) - it doesn't affect the logical model of what's in the list, if you see what I mean.
EDIT: It sounds like you want a sort of ensureSize() method, which might look something like this:
public static void ensureSize(ArrayList<?> list, int size) {
// Prevent excessive copying while we're adding
list.ensureCapacity(size);
while (list.size() < size) {
list.add(null);
}
}
So as others have mentioned ensureCapacity isn't for that.
It looks like you want to start out with an ArrayList of 200 nulls? Then this would be the simplest way to do it:
ArrayList<String> a = new ArrayList<String>(Arrays.asList( new String[200] ));
Then if you want to replace element 190 with "test" do:
a.set(190, "test");
This is different from
a.add(190, "test");
which will add "test" in index 190 and shift the other 9 elements up, resulting in a list of size 201.
If you know you are always going to have 200 elements it might be better to just use an array.
Ensuring capacity isn't adding items to the list. You can only get element 190 or add at element 190 if you've added 191 elements already. "Capacity" is just the number of objects the ArrayList can hold before it needs to resize its internal data structure (an array). If ArrayList had a getCapacity(), then doing this:
ArrayList<String> a = new ArrayList<String>();
a.ensureCapacity(200);
System.out.println(a.size());
System.out.println(a.getCapacity());
would print out 0 and some number greater than or equal to 200, respectively
ArrayList maintains its capacity (the size of the internal array) separately from its size (the number of elements added), and the 'set' method depends on the index already having been assigned to an element. There isn't a way to set the size. If you need this, you can add dummy elements with a loop:
for (int i = 200; --i >= 0;) a.add(null);
Once again JavaDoc to clarify the situation:
Throws: IndexOutOfBoundsException
- if index is out of range (index < 0 || index > size()).
Note that size() returns the number of elements currently held by the List.
ensureCapacity just makes sure that the underlying array's capacity is greater than or equal to the argument. It doesn't change the size of the ArrayList. It does't make any changes visible through the API, so you won't notice a difference except that it will probably be longer before the ArrayList resizes it's internal array.
Adding 190 null entries to an ArrayList reeks of a misuse of the data structure.
Think about using a standard primitive array.
If you require a generics or want more efficient use of space then consider SparseArray or even a Map like a HashMap may be appropriate for your purposes.
public static void fillArrayList(ArrayList<String> arrayList, long size) {
for (int i = 0; i < size + 1; i++) {
arrayList.add(i,"-1");
}
}
public static void main(String[] args) throws Exception {
ArrayList<String> a = new ArrayList<String>(10);
fillArrayList(a, 190);
a.add(190,"test");
System.out.println(a.get(190).toString());
}
import java.util.ArrayList;
public class WTFAMIDOINGWRONG
{
public static void main(String[] args)
{
ArrayList<Integer> intsAR = new ArrayList<Integer>(5);
intsAR.add(3, 1);
}
}
So, I've been fooling around with this for about an hour and I haven't the slightest Idea what I could be doing wrong. No matter what I do, it's convinced the arraylist has no size and everything is therefore out of bounds. If anyone could tell me what I'm doing wrong I'd really appreciate it.
An ArrayList is backed by an array, so when you specify the initial capacity, you are specifying how large of an array to allocate. This is important because it specifies how much memory the ArrayList will occupy sequentially.
However, the size of the ArrayList specifies how many items are actually in the list. Once the list reaches a certain size (relative to the capacity of the backing array), the backing array will be reallocated to take up additional space.
If you wanted to create an ArrayList of 10 items, all with 0, you would do:
List<Integer> list = new ArrayList<Integer>();
for ( int i = 0; i < 10; i++ ) {
list.add(0);
}
Now you could insert an item at position 3 (or somewhere in the middle) if you wanted to.
Because the size of your list is ZERO. Yes, you are actually constructing it by specifying the initialCapacity, but that doesn't mean size. Are you getting my point? You can say that taht will just reserve the space for future.
BTW, size() documentation clearly states that, it is the number of elements in the list. Now, I hope you know what is happening.
You cannot insert into an empty list in position 3 - what would be the first 2 elements then? With empty list only intsAR.add(0, 1); will work