I am new in Android and Java developing...so maybe my question will be confused or not normal :)
Is it possible to make an ArrayList or any collection where I give the index value?
Example:
ArrayList<String> list = new ArrayList<String>();
list.add(3, "Item1");
list.add(10, "Item2");
When I try to use this I got an exception message: IndexOutOfBounds...
I want to add my ArrayList (collection) to an Android ArrayAdapter...
So! Is it possible to make a collection with optional index and it is able to add android ArrayAdapter?
Thanks the help!
You can add an element to a specific location in the ArrayList, but only if the size of the ArrayList prior to that operation is higher or equal to the index you are specifying. This means that the ArrayList can have no gaps. You can't add an elements to the index number 3 if indices 0,1,2 are not already occupied.
So, list.size() should be at least 3 in order for list.add(3, "Item1"); to be valid. Adding elements to the ArrayList in this manner increments the index of all the elements of the list starting in the given index.
Use HashMap, it should solve your problem
http://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html
You can create your own List implementation which will support this functionality:
public class SparseArrayList<E> extends ArrayList<E> {
#Override
public E set(int index, E element) {
while (size() <= index) add(null);
return super.set(index, element);
}
}
Related
From what I read, it is safe to remove elements while iterating through a list. (instead of using the simple for each loop).
Suppose I have a list of elements, and I want to visit all of the elements, but while I visit each element, I will visit its neighbours (note that I have a map for each element which will give me its neighbours), thus I will
have to remove other elements from the original list. Thus I cannot use
iterator.remove().
What is a good way to do this, that is to say, remove elements from the list that I am going through without being at the position with the iterator?
One idea I had was the following, have my elements in a map, with value as
a boolean, (true for visited, and false otherwise).
Thus, I go through my list, and for each element i set it visited true, and if one if its neighbours I also see while visiting that element, I will also set them as true.
Use a for loop instead of a foreach to iterate over the items. Then remove as you see fit. Here is an example of removing even elements from the List
import java.util.List;
import java.util.ArrayList;
class Test {
public static void main(String[] args){
final List<Integer> ints = new ArrayList<Integer>();
ints.add(100);
ints.add(1);
ints.add(15);
ints.add(42);
ints.add(187);
System.out.println("Original List");
for(Integer i: ints){
System.out.println(i);
}
/* Remove any even elements from the list */
for(int i=0; i < ints.size(); i++){
if(ints.get(i) % 2 == 0){
ints.remove(i);
}
}
System.out.println("\nModified List");
for(Integer i: ints){
System.out.println(i);
}
}
}
Lets assume that you are talking about an input list that is an ArrayList.
The following approach will give you O(N) behaviour (for at least OpenJDK Java 6 through Java 8):
Create a HashSet.
Iterate over the elements of your input list:
Visit the element and add it to the set if it should be removed
Visit the neighbours of the element and add to the set any one that should be removed.
Call list.removeAll(set).
The removeAll method for ArrayList calls an internal batchRemove method (see here). This method performs a single pass over the ArrayList's backing array, removing elements and filling the holes. It tests each element to see if it should be removed by calling set.contains(elem). For a HashSet that test is O(1), and hence the removeAll(set) call is O(N) where N is the list size.
It is interesting to note that arrayList.removeAll(hashSet) will be O(N) where N is the list length, but removing the same elements like this:
for (Iterator it = arrayList.iterator; it.hasNext(); ) {
if (hashSet.contains(it.next())) {
it.remove();
}
}
will be O(NM) where N is the list length and M is the set size.
On creating an arrayList using the below mentioned code snippet:
List arrayList = new ArrayList(16);
The internal implementation of ArrayList creates an array elementData of size 16 and assigns nullat every location. On doing something like arrayList.add(2,"HelloWorld") gives an IndexOutOfBoundException as the index at which the element is being added (i.e 2) is greater than the size attribute of the arrayList .
As clear from the javaDocs, the size attribute of the arrayList is initialized to 0 when the arrayList is initialized and is incremented by 1 everytime a new element is added to the arrayList
Can someone please explain, why the ArrayList dataStructure was designed this way in the first place. Even tho' the internal dataStructure elementData was initialized with 16 null values at the creation of arrayList, still it does not allow to add value at indeces > size; (assuming index <16 in this case). What was the idea to implement the add(index,object)
funtionality to be governed by the size attribute of the arrayList?
The purpose of having an internal array with a size greater then List.size() is to avoid re-allocating the array unnecessarily. If the internal array always had the same size as the List, then every time a new element is added, the internal array would have to be re-allocated, causing a performance penalty.
In fact, the default constructor of ArrayList constructs a list with an initial capacity of 10.
public ArrayList() {
this(10);
}
But why we need such an allocation? As you understand, if you indicate the size of ArrayList in advance, you can provide efficient for the list. Otherwise, after the number of elements exceeds the initial capacity of ArrayList, a new reallocation operation is performed for each element.
The documentation says:
public void add(int index, E element)
Throws:
IndexOutOfBoundsException -
if the index is out of range
(index < 0 || index > size())
As you can see, it throws IndexOutOfBoundsException if (index > size()).
Since ArrayList's "public int size()" returns elements which are not equal to null, your size equals to 0 (not 16 as you said in your example). In other words, if null values were counted as well, the size of each ArrayList that was created with default constructor would be 10.
Consequently, "arrayList.add(2, "HelloWorld")" throws IndexOutOfBoundsException since index = 2 but size() = 0.
Edit:
I think when you mount your argument, you use this as base:
String[] arr = new String[5];
arr[3] = "hello";
System.out.println(arr[3]);
Then, you think why you can give a value in an array element directly but why you cannot do the same thing while using add(int index, E element) method of ArrayList. Actually, it is true but there is no condition to implement ArrayList as complete counterpart of Array. In other words, this method is conditioned with that rule since it is nature of ArrayList. As we all know, when you create an array, you specify its size in square brackets. The constructor of ArrayList which takes int as parameter does not do the same thing. It performs just an imaginary allocation. Yes, it could specify its initial size with this allocation or after add(int index, E element) is called, size could be increased by one. However, ArrayList is implemented to provide an array-like structure which has continuity with respect to index number but has no fixed size. Thence, there are some other higher level of abstraction examples do this task. To exemplify, LinkedHashMap structure.
You can not add object at a specific index till it contains null. You just need to add object using add method and then you can update values on a index.
For Example.
ArrayList<Integer> arrlist = new ArrayList<Integer>(5);
// use add() method to add elements in the list
arrlist.add(15);
arrlist.add(22);
arrlist.add(30);
arrlist.add(40);
// adding element 25 at third position
arrlist.add(2,25);
You rarely need to specify the capacity of an ArrayList, it can improve the performance only if you know how many elements your ArrayList will hold.
ArrayList is simply a List that can automatically be grown or shrink. Using List, you never need to add an element in the place n if the list is empty, you simply link it to the previous node (unless it's the head of course) - that's the idea of ArrayList except the fact that it can be grown/shrink automatically.
See the java doc of ArrayList's add(int index,
E element) method. Here you can find the ArrayIndexOutOfBound exception occurred when if the index is out of range (index < 0 || index > size()).
You declared an ArrayList with an initial capacity 16. It doesn't mean that each of the 16 indexed position of the ArrayList contains element. It just mention the initial capacity and when it necessary it will grow it's size dynamically.
See the source code the constructor from the ArrayList class -
/**
* Constructs an empty list with the specified initial capacity.
*
* #param initialCapacity the initial capacity of the list
* #exception IllegalArgumentException if the specified initial capacity
* is negative
*/
public ArrayList(int initialCapacity) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
}
Here we can not find anything that told us - ArrayList will initiated with null value.
Update: Based on your comment I have done some experiment, since I'm not sure about whether an array of reference/non-primitive type will initialized with null. See the following code below. Run the the code by uncommenting each of line at per execution -
import java.util.List;
import java.util.ArrayList;
public class ArrayListTest{
public static void main(String[] args){
List<String> list1 = new ArrayList<String>(); //default with initial capacity 10
List<String> list2 = new ArrayList<String>(5);
List<String> list3 = new ArrayList<String>(5);
list2.add(null);
list2.add(null);
list2.add(null);
list3.add("zero");
list3.add("one");
list3.add("two");
//System.out.println(list1.get(4)); //IndexOutOfBoundException
//System.out.println(list2.get(0)); //null
//System.out.println(list2.get(2)); //null;
//System.out.println(list2.get(3)); //IndexOutOfBoundException
//System.out.println(list3.get(0)); //zero
//System.out.println(list3.get(2)); //two;
//System.out.println(list3.get(3)); //IndexOutOfBoundException
//list3.add(4, "four"); //IndexOutOfBoundException
}
}
Here you can see list2.get(0) and list2.get(2) gives you null. Because we put null at these index. But list2.get(3) doesn't give null since we didn't put null at index 3. So it seems array of reference/non-primitive type won't initialize with null. list2.get(3) gives IndexOutOfBoundException.
You found the same scenario for the list3. where I didn't put any null in this list. Even when we are trying to add some value at index 4 of list3 it gives IndexOutOfBoundException. Since the index 4 is not available for the list3. But you can add some value at index 2 of list2. Cause at index 2 of this list I have inserted null manually.
So in long story short (I think) - new ArrayList<SomeType>(givenSize) wouldn't initialize an array with givenSize with all element setting to null.
Hope it will Help.
Thanks.
I have an ArrayList of type String. I want to determine whether any element of this ArrayList starts with a specified string and if the ArrayList contains this element, then I want to get the index of this element. In addition, I do not want to loop this ArrayList to get the index of that element.
For example :
ArrayList<String> asd = new ArrayList<String>(); // We have an array list
//We filled the array list
asd.add("abcc trtiou");
asd.add("aiwr hiut qwe");
asd.add("vkl: gtr");
asd.add("aAgiur gfjhg ewru");
Now, I want to get the index of the element vkl: gtr by using vkl: without looping array list.(searching also should be case insensitive, so, using vkl: and VkL: should give the index of vkl: gtr)
How can I do this ?
Thanks in advance.
You have to loop the ArrayList. You cant possibly access just a single index and be guaranteed it is what you're looking for.
Also, you should consider using another data structure if a lot of searching is involved. Searching an ArrayList takes O(n)time while something like a red-black tree can be done in O(log n).
If you know before program execution the strings used to locate the items in the structure, consider using a HashMap. You can access the items in O(1).
If none of these solutions suit your particular problem expand on your answer with what you're trying to do, we could provide a better answer as to how you'd locate your items with minimal search time.
This is as far as you can get with your requirement if you're not looking to perform loop and search against the string objects held in the arraylist.
if(asd.contains("vkl: gtr"))
{
int index=asd.indexOf("vkl: gtr");
}
or simply:
int index = Arrays.binarySearch(asd.toArray(), 0, asd.size()-1, "vkl: gtr");
If performing loop in your calling method is what you're looking to avoid then, alternative you can create a class which extends ArrayList and have a method which does the index lookup.
class MyArray extends ArrayList<String>
{
public int getIndexOf(String o)
{
for (int i = 0; i < size(); i++)
{
if (get(i).contains((String) o)) return i;
}
return -(size() - 1);
}
}
Then from your calling program do:
public void foo()
{
MyArray asd = new MyArray();
asd.add("abcc trtiou");
asd.add("aiwr hiut qwe");
asd.add("vkl: gtr");
asd.add("aAgiur gfjhg ewru");
int index = asd.getIndexOf("vkl:");
}
for(int i=0; i < asd.size(); i++) {
String s = asd.get(i);
//search the string
if(found) {
return i
}
}
return -1
I don't really understand if you are looking for something like key-value pairs or single string entry search.
If you are looking for the first one you should use Map instead of a simple array if you want to search for a key
Here you can put a pair using
put(Object key, Object value)
and the getting the value of a specified key with
get(Object key)
If you are looing only for a quick way of finding a part of string into an array you have to read all indexes and compare strings one by one using stringToCompare.equalsIgnoreCase(otherStringToCompare). Note that this will throw an exception if stringToCompare is NULL
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Java: adding elements to a collection during iteration
My problem is that I want to expand a list with new elements while iterating over it and I want the iterator to continue with the elements that I just added.
From my understanding the ListIterator.add() adds an element before the current element in the list, not after it. Is it possible to achieve this in some other way?
You can't modify a Collection while iterating over it using an Iterator, except for Iterator.remove().
However, if you use the listIterator() method, which returns a ListIterator, and iterate over that you have more options to modify. From the javadoc for add():
The new element is inserted before the implicit cursor: ... a subsequent call to previous() would return the new element
Given that, this code should work to set the new element as the next in the iteration:
ListIterator<T> i;
i.add(e);
i.previous(); // returns e
i.previous(); // returns element before e, and e will be next
This will work except when the list starts iteration empty, in which case there will be no previous element. If that's a problem, you'll have to maintain a flag of some sort to indicate this edge case.
There might be some trick with ListIterator, but the easiest solution is probably an old style index loop. Verify performance isn't an issue (no linked lists - but ArrayList is fine).
List<Object> myList;
for(int i = 0; i < myList.size(); i++)
{
Object current = myList.get(i);
// Anything you insert after i will be discovered during next iterations
}
How about
List<Foo> fooList = getFooList();
List<Foo> tempFooList = new ArrayList<Foo>()
for(Foo f : fooList)
{
...
// add items that need to be added to temp
tempFooList.add(new Foo());
...
}
fooList.addAll(tempFooList);
I think it's a fairly simple question, but I can't figure out how to do this properly.
I've got an empty arraylist:
ArrayList<object> list = new ArrayList<object>();
I've got some objects In which I want to add object and each object has to be at a certain position. It is necessary however that they can be added in each possible order. When I try this, it doesn't work and I get an IndexOutOfBoundsException:
list.add(1, object1)
list.add(3, object3)
list.add(2, object2)
What I have tried is filling the ArrayList with null and then doing the above. It works, but I think it's a horrible solution. Is there another way to do this?
You can do it like this:
list.add(1, object1)
list.add(2, object3)
list.add(2, object2)
After you add object2 to position 2, it will move object3 to position 3.
If you want object3 to be at position3 all the time I'd suggest you use a HashMap with position as key and object as a value.
You can use Array of objects and convert it to ArrayList-
Object[] array= new Object[10];
array[0]="1";
array[3]= "3";
array[2]="2";
array[7]="7";
List<Object> list= Arrays.asList(array);
ArrayList will be- [1, null, 2, 3, null, null, null, 7, null, null]
If that's the case then why don't you consider using a regular Array, initialize the capacity and put objects at the index you want.
Object[] list = new Object[10];
list[0] = object1;
list[2] = object3;
list[1] = object2;
You could also override ArrayList to insert nulls between your size and the element you want to add.
import java.util.ArrayList;
public class ArrayListAnySize<E> extends ArrayList<E>{
#Override
public void add(int index, E element){
if(index >= 0 && index <= size()){
super.add(index, element);
return;
}
int insertNulls = index - size();
for(int i = 0; i < insertNulls; i++){
super.add(null);
}
super.add(element);
}
}
Then you can add at any point in the ArrayList. For example, this main method:
public static void main(String[] args){
ArrayListAnySize<String> a = new ArrayListAnySize<>();
a.add("zero");
a.add("one");
a.add("two");
a.add(5,"five");
for(int i = 0; i < a.size(); i++){
System.out.println(i+": "+a.get(i));
}
}
yields this result from the console:
0: zero
1: one
2: two
3: null
4: null
5: five
I draw your attention to the ArrayList.add documentation, which says it throws IndexOutOfBoundsException - if the index is out of range (index < 0 || index > size())
Check the size() of your list before you call list.add(1, object1)
You need to populate the empty indexes with nulls.
while (arraylist.size() < position)
{
arraylist.add(null);
}
arraylist.add(position, object);
#Maethortje
The problem here is java creates an empty list when you called new ArrayList and
while trying to add an element at specified position you got IndexOutOfBound ,
so the list should have some elements at their position.
Please try following
/*
Add an element to specified index of Java ArrayList Example
This Java Example shows how to add an element at specified index of java
ArrayList object using add method.
*/
import java.util.ArrayList;
public class AddElementToSpecifiedIndexArrayListExample {
public static void main(String[] args) {
//create an ArrayList object
ArrayList arrayList = new ArrayList();
//Add elements to Arraylist
arrayList.add("1");
arrayList.add("2");
arrayList.add("3");
/*
To add an element at the specified index of ArrayList use
void add(int index, Object obj) method.
This method inserts the specified element at the specified index in the
ArrayList.
*/
arrayList.add(1,"INSERTED ELEMENT");
/*
Please note that add method DOES NOT overwrites the element previously
at the specified index in the list. It shifts the elements to right side
and increasing the list size by 1.
*/
System.out.println("ArrayList contains...");
//display elements of ArrayList
for(int index=0; index < arrayList.size(); index++)
System.out.println(arrayList.get(index));
}
}
/*
Output would be
ArrayList contains...
1
INSERTED ELEMENT
2
3
*/
How about this little while loop as a solution?
private ArrayList<Object> list = new ArrayList<Object>();
private void addObject(int i, Object object) {
while(list.size() < i) {
list.add(list.size(), null);
}
list.add(i, object);
}
....
addObject(1, object1)
addObject(3, object3)
addObject(2, object2)
This is a possible solution:
list.add(list.size(), new Object());
I think the solution from medopal is what you are looking for.
But just another alternative solution is to use a HashMap and use the key (Integer) to store positions.
This way you won't need to populate it with nulls etc initially, just stick the position and the object in the map as you go along. You can write a couple of lines at the end to convert it to a List if you need it that way.
Bit late but hopefully can still be useful to someone.
2 steps to adding items to a specific position in an ArrayList
add null items to a specific index in an ArrayList
Then set the positions as and when required.
list = new ArrayList();//Initialise the ArrayList
for (Integer i = 0; i < mItems.size(); i++) {
list.add(i, null); //"Add" all positions to null
}
// "Set" Items
list.set(position, SomeObject);
This way you don't have redundant items in the ArrayList i.e. if you were to add items such as,
list = new ArrayList(mItems.size());
list.add(position, SomeObject);
This would not overwrite existing items in the position merely, shifting existing ones to the right by one - so you have an ArrayList with twice as many indicies.
You should set instead of add to replace existing value at index.
list.add(1, object1)
list.add(2, object3)
list.set(2, object2)
List will contain [object1,object2]
Suppose you want to add an item at a position, then the list size must be more than the position.
add(2, item): this syntax means, move the old item at position 2 to next index and add the item at 2nd position.
If there is no item in 2nd position, then this will not work, It'll throw an exception.
That means if you want to add something in position 2,
your list size must be at least (2 + 1) =3, so the items are available at 0,1,2 Position.
in that way it is ensured that the position 2 is accessed safely and there would be no exception.
If you are using the Android flavor of Java, might I suggest using a SparseArray. It's a more memory efficient mapping of integers to objects and easier to iterate over than a Map