Have a question.. I have a list of mp3 filenames
to add a new file name use:
musicList.add(new Mp3(id, filename));
now I wanted to create a array containing this lists
private static final int LIST_COUNT = 8;
public static List<List<Mp3>> musicLists = new ArrayList<List<Mp3>>(LIST_COUNT);
private void parseMus(){
musicLists = new ArrayList<List<Mp3>>(LIST_COUNT);
...
//gettin mp3 list id,filename, length
...
musicLists.get(listNr).add(new Mp3(id,filename,length));
...
}
but it gives me errors:
03-15 21:01:36.030: E/AndroidRuntime(3393): java.lang.IndexOutOfBoundsException: Invalid index 4, size is 0
Second quwestion!
now I edited code and have no errors... BUT now what i get is that all list is filled with same lists.. so when i try to see:
for(int i =0; i< Settings.musicLists.size();i++){
if(D)Log.e("visio added","MP3 file muslist nr="+i+"= "+Settings.musicLists.get(i));
}
I get 8 identical rows shown... what I do wrong?
musicLists = new ArrayList<List<Mp3>>(LIST_COUNT);
You seem to think that this line creates a list of 8 lists. However, what it really does is to create an empty list of lists with initial capacity 8. That is, it doesn't actually populate any lists into musicLists.
In order for this you do what you expect it to, you need to initialize musicLists and then use musicLists.add(foo) to add 8 List<Mp3> objects to it.
As VeeArr said you need to fill the list with lists before you can get the lists.
// this creates an empty list of initial capacity 8
musicLists = new ArrayList<List<Mp3>>(8);
// musicList.size() is still 0
// we can add as much items as we want, the list will dynamically grow.
for (int i = 0; i < 8; i++) {
List<Mp3> emptySubList = new ArrayList<Mp3>();
// emptySubList.size() is 0 each as well.
musicList.add(emptySubList);
}
// musicList.size() is 8 now.
// do your stuff...
musicLists.get(listNr).add(new Mp3(id,filename,length));
The initial capacity you can specify for an ArrayList is just a way to improve memory consumption.
ArrayLists can dynamically grow unlike array[]s. They do that by internally keeping an array[] where the data you put in your ArrayList is actually stored. If the size they need gets bigger than the array[] can hold they create a bigger array[] and copy the content to that new version (afaik the size is always doubled).
Thats nice because you don't need to worry about doing that yourself. But copying arrays is expensive. Therefore you can define an initial size to hint your ArrayList that it should expect a certain number of elements. It's usually fine if you don't give an initially capacity unless you really know how much items you need.
Related
I know ArrayList can contain "any number of items" (as long you have the memory for it). However, I was wondering if the initial size of the list is different for each machine running it. If I have 8GB of RAM vs 4GB RAM does this change the intial size? Thanks!
ArrayList list = new ArrayList<Integer>();
The initial size of the ArrayList if the no-arg constructor is used quoting from the javadoc:
Constructs an empty list with an initial capacity of ten.
So it does not depend on anything, it doesn't depend on the RAM size either.
However there are some clever optimization going on in the background. If you check the Oracle implementation of ArrayList, you will see that in this case an initial empty internal array will be used so no array will be allocated until you actually add some elements to the list - in which case an array of size 10 will be created.
Once you attempt to add the 11th element, the internal array will be "resized". The new size is also implementation dependent, Oracle uses a 50% increment in the 1.7.0 version, so adding the 11th element will cause a new array to be allocated with the size of 15.
Going behind the scene
For the curious ones, you can use the following method to query the size of the internal array of the ArrayList (the solution uses reflection):
public static int getCap(ArrayList<?> list) throws Exception {
Field f = list.getClass().getDeclaredField("elementData");
f.setAccessible(true);
Object[] o = (Object[]) f.get(list);
return o.length;
}
Test results
ArrayList<String> list = new ArrayList<>();
System.out.println(getCap(list)); // Prints 0
list.add("");
System.out.println(getCap(list)); // Prints 10
for (int i = 1; i < 11; i++)
list.add("");
System.out.println(getCap(list)); // Prints 15
for (int i = 11; i < 16; i++)
list.add("");
System.out.println(getCap(list)); // Prints 22
The initial capacity is by default 10. You can always use the constructor that accepts a capacity parameter in order to start with a different capacity.
/**
* Constructs an empty list with an initial capacity of ten.
*/
public ArrayList() {
this(10);
}
It is by default created with an initial capacity of 10 (regardless of available RAM).
By default ArrayList is of size 10 object and keep growing by size of 10.
Eg
ArrayList list = new ArrayList<Integer>();
Here the size of list will be 10.
Once you add the 11 object the size will be incremented by 10 and will become 20.
You can change the initial size by invoking the constructor with a size. See the example.
Example:
ArrayList list = new ArrayList<Integer>(2);
list.add(1); // size() == 1
list.add(2); // size() == 2, list is "filled"
list.add(3); // size() == 3, list is expanded to make room for the third element
I'm developing for the Android platform and, to simplify the question, I'm using pseudo-names for the entities.
I have an object array stuff[] of the class StuffClass[].
StuffClass stuff[]={
new StuffClass(Argument, argument, argument),
new StuffClass(argument, argument, argument)
};
I have an activity returning a result of three arguments that I want to then use to add a new object to stuff[]. I've done so as follows:
stuff[stuff.length]=new StuffClass(argument, argument, argument);
and I get ArrayOutOfBounds (Figured that would happen).
So how might I go about creating a new object in the stuff[] array?
Arrays are static you can't change size without creating a new one before. Instead of that you can use a dynamic data structure such as an ArrayList
Example:
List<MyType> objects = new ArrayList<>();
objects.add(new MyType());
Here you forget about array size.
Array in Java is little bit special, it's length is fixed when it's initialized, you can not extend it later on.
What you can do is to create a new array, and use System.arraycopy to generate a new array, here's the sample code:
String[] arr1 = new String[]{"a", "b"};
String[] arr2 = new String[3];
System.arraycopy(arr1, 0, arr2, 0, 2);
arr2[2] = "c";
You cannot increase the size of an existing array. Once it's created, the size of the array is fixed.
You will need to create another bigger array and copy the items from the old array to the new array.
A better alternative is to use an ArrayList. When you add items to an ArrayList, the capacity will grow behind the scenes if needed; you don't have to worry about increasing the size.
you can use the ArrayList to do this
arraylist.add(object);
in java arrays are fixed length. you need to initialise them with the desired length.
Consider using a Collection such as ArrayList which will handle everything for you.
List<StuffClass> myList = new ArrayList<>();
myList.add(...);
Lists support similar behaviour to arrays ie:
myList.set(i, elem);
myArray[i] = elem;
elem = myList.get(i);
elem = myArray[i];
len = myList.size();
len = myArray.length;
You can then convert the list to an array.
StuffClass[] myArray = myList.toArray(new StuffClass[myList.size()]);
If you don't want to use lists consider using System.arrayCopy to create a new array with more elements.
read here for a good description.
I am new in android programming.
Here is my question
I tried to declare an array before onCreate() method like
int[] userselected;
Note that i want to use this array to store ids of buttons user had pressed.
Then i tried to find no. of elements in this array with
int noOfElements = userselected.length;
which game me an error.
Then I changed declaration to
int[] userselected = {};
it worked, but when i tried to put an id in this array with code
userselected[1] = R.id.textview1;
it again gave me an error.
I also tried declaring array as
int[] userselected = new int[4];
but then, when i tried to find how many elements have already been stored,
userselected.length
always gave number 4.
Please tell me, how can i get what i want
You need to use ArrayList. It will give you a more flexible structure giving your case.
ArrayList<Integer> userselected = new ArrayList<Integer>();
userselected.add(R.id.textview1); //To add id.
int noOfElement = userselected.size(); //to get size
an array is fixed size. so when you declare this array
int[] userselected = new int[4]
you are creating an array with a fixed size of 4. The array index is zero based so its from [0] to [3]. I recommend you use an ArrayList object like the top answer states
when you do this:
int[] userselected = {};
it is the same as this:
int[] userselected = new int[0]; // empty
and you got an error from this:
int[] userselected;
because you have not allocated any space in memory
Java primitive arrays, such as int[], are constant in length and cannot contain more than their initial length. If you need an array that can change in size, you need to use fx. a List implementation. I would suggest you read up on basic Java before you start developing Android, it would save you a lot of time in the long run.
I think this page can help: http://www.javaclass.info/classes/java-array/array-examples-demonstration-and-code-snippets.php
In the array declaration you do, you say that its size is 4 elements, therefore the length method will always return 4.
regards
declare it as a integer array then Add this to your code
Integer a=0;
for (int i=0;i>userselected.length;i++)
{
if(userselected[i]!=null)
{
a++;
}
}
then a will give you the count you need:) cheers:)
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