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
Related
I am trying to use array lists, and I have a row of coordinates. I would like to shift all the coordinates in this row to the front or to the back. I'm not sure if I am on the correct lines here with the code.
List<Coordinate> coordinates = new ArrayList<>();
void addCoordinateToList(Coordinate singleCoordinate) {
coordinates.add(singleCoordinate)
}
void addCoordinateToBackList(ArrayList<> coordinateList) {
for(int i = 0; i < coordinates.size(); i++) {
coordinateList.add(i, coordinateList(i));
}
}
void addCoordinateToFrontList(ArrayList<> coordinateList) {
for(int i = coordinates.size(); i > 0; i--) {
coordinateList.add(i, coordinatesList(i));
}
}
This is not final code, its just writing thoughts out at the moment.
Well, you don't need to use a for loop here.
You could instead utilize the addAll method to achieve what you want:
void addCoordinatesToBack(List<Coordinate> coordinateList) {
coordinates.addAll(coordinateList);
}
void addCoordinatesToFront(List<Coordinate> coordinateList) {
coordinates.addAll(0, coordinateList);
}
addAll has two forms:
addAll(Collection c) adds all elements of the specified Collection at the end of the list;
addAll(int position, Collection c) adds all elements of the specified Collection at the given position. Use position 0 to add them at the beginning of the list.
Also note that I have used List instead of ArrayList with your parameters, as this makes it more flexible.
Note that this is not quite the same as reversing lists.
This functionality is built into the List interface. You can use the following functions for that:
List<String> myList = new ArrayList<>();
//adds to the end of the list
myList.add("reading");
myList.addAll(List.of("the","documentation","first!"));
//adds to the front of the list
myList.add(0,"with");
myList.addAll(0,List.of("It","begins");
Your code
void addCoordinateToBackList(ArrayList<> coordinateList) {
for(int i = 0; i < coordinates.size(); i++) {
coordinateList.add(i, coordinateList.get(i));
}
}
will endlessly add the first element of the original list to beginning of itself. Note that I added the call to List.get(int).
Your last method will throw an ArrayIndexOutOfBounds exception as index i=coordinates.size() is out of bounds. You probably need to change
void addCoordinateToFrontList(ArrayList<> coordinateList) {
for(int i = coordinates.size() - 1; i >= 0; i--) {
coordinateList.add(i, coordinatesList.get(i));
}
}
But this will again add endlessly the last element of the list to itself.
Probably what you want to achieve is:
List<Object> coordinateList = new ArrayList<>();
...
java.util.Collections.reverse(coordinateList);
This will reverse the order of the elements in the list. Note that it will work on the given list and not return anything. This will work only on modifiable lists.
EDIT:
You probably mean to "rotate" the elements, right? There is also the method Collections.rotate(List input, int distance). The documentation:
Rotates the elements in the specified list by the specified distance. After calling this method, the element at index i will be the element previously at index (i - distance) mod list.size(), for all values of i between 0 and list.size()-1, inclusive. (This method has no effect on the size of the list.)
For example, suppose list comprises [t, a, n, k, s]. After invoking Collections.rotate(list, 1) (or Collections.rotate(list, -4)), list will comprise [s, t, a, n, k].
This works in both directions.
I try to do it like this, but somehow it doesn't seem to work:
ArrayList<Integer> possible_values= new ArrayList<Integer>();
public void setValueToZero(){
for (Integer temp : possible_values) {
temp=0;
}
}
You could use Collections.fill(List<T> list, T obj).
In your case that would be Collections.fill(possible_values, 0)
You are assigning values to temp variable and there is no change to the possible_values list object elements, you can set the 0 values to the List elements as shown below:
public void setValueToZero(ArrayList<Integer> possible_values){
for (int i=0; i<possible_values.size(); i++) {
possible_values.set(i, 0);
}
}
or else, you can use streams (one liner code) as shown below:
IntStream.range(0,possible_values.size()).forEach(i->possible_values.set(i, 0));
The temp in your program is not the elements of the ArrayList,it is a new Object. In the other word, your program is not to set the integer in arraylist. You are just set the value of temp,which is a new object and you didn't change the true value of the element in the arraylist. Well, I hope you can understand what I write. I'm not a native speaker.
I have an Arraylist with (String-)Arrays in it. Now I want to be able to delete a specific element from the Arraylist.
Here is an example arraylist:
0: [Name, , , ]
1: [Telefon, \(\d+\) \d+, DAFAE8, FF6262]
2: [E-Mail, ^[a-zA-Z0-9]+(?:(\.|_)[A-Za-z0-9!#$%&'*+/=?^`{|}~-]+)*#(?!([a-zA-Z0-9]*\.[a-zA-Z0-9]*\.[a-zA-Z0-9]*\.))(?:[A-Za-z0-9](?:[a-zA-Z0-9-]*[A-Za-z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?$, DAFAE8, FF6262]
3: [Company, , , ]
4: [Test, , , ]
5: [Test2, , , ]
6: [Test3, , , ]
Now I want to delete the 5th element (the array which includes Test2). How do I accomplish that?
I already tried the following things:
public static List<String[]> removeSpecificElements(List<String[]> list, int i){
list.remove(new Integer(i));
return list;
}
This one doesn't throw any kind of Exception, but doesn't work either.
public static List<String[]> removeSpecificElements(List<String[]> list, int i){
list.remove(i);
return list;
}
This one throws ArrayIndexOutOfBounds.
public static List<String[]> removeSpecificElements(List<String[]> list, int i){
Iterator<String[]> itr = list.iterator();
itr.next();
for (int x = 0; x < i; x++){
itr.next();
System.out.println(itr);
}
itr.remove();
return list;
}
And this one always removes the first element.
Could you please help me?
Now I want to delete the 5th element (the array which includes Test2). How do I accomplish that?
You need to use
list.remove(i); // where i = 5 - 1, as the first element is 0.
if you do
list.remove(new Integer(i));
it will look for the object you just created, which doesn't exist in the list, so as you say it does nothing.
In short, don't confuse int for Integer as these are different types.
Ideally, the API would have a different method like removeAt(int) to remove this potential source of confusion, but it's too late to change it now.
When would this work? Consider the following.
List<Integer> ints = new ArrayList<>();
ints.add(4);
List<MyType> list = (List) ints; // it works but don't do this.
boolean wasRemoved = list.remove(new Integer(4)); // true!!
java.util.List#remove(int) should work, just don't forget that lists are zero indexed, i.e. 5th element is removed calling list.remove(4)
I am trying to part the mainListarraylist to 3 sublist Arraylist and then add it as sublist in other arraylist mainSublist but I am getting this error:
How can I fix it?
I appreciate any help.
1)-Type mismatch: cannot convert from List to ArrayList
2) -The method add(RootCreator) in the type ArrayList is not applicable for the arguments (ArrayList)
Code:
ArrayList<RootCreator> mainList = new ArrayList<RootCreator>();
for (String key : names) {
RootCreator rootcreat = join_line(path, key);
mainList.add(rootcreat);
}
ArrayList<RootCreator> mainSublist = new ArrayList<RootCreator>();
for(int i= 0 ; i < mainList.size(); i++){
int index = i*3;
//the error 1 is here
ArrayList<RootCreator> sublist = mainList.subList(0, index);
//error 2 is here
mainSublist.add(sublist);
}
All List are not ArrayList, so when you use sublist you get a generic List. On the other hand, the method to add a collection to another collection is addAll instead add.
List<RootCreator> mainList = new ArrayList<RootCreator>();
for (String key : names) {
RootCreator rootcreat = join_line(path, key);
mainList.add(rootcreat);
}
List<RootCreator> mainSublist = new ArrayList<RootCreator>();
for(int i= 0 ; i < mainList.size(); i++){
int index = i*3;
//the error 1 is here
List<RootCreator> sublist = mainList.subList(0, index);
//error 2 is here
mainSublist.addAll(sublist);
}
The subList method returns a List, not an ArrayList, and you cannot assign a List to an ArrayList. In fact, the List returned by the subList method is not an ArrayList.
If it needs to be an ArrayList, then create an ArrayList out of the sub list.
ArrayList<RootCreator> sublist = new ArrayList<>(mainList.subList(0, index));
If you just need a List, then make sublist a List instead.
List<RootCreator> sublist = mainList.subList(0, index);
You can't add an ArrayList<RootCreator> to an ArrayList<RootCreator>; you must add a RootCreator. If you want to add the elements of sublist to another list, then use the addAll method.
mainSublist.addAll(sublist);
OK, let's look at the two errors here:
//the error 1 is here
ArrayList<RootCreator> sublist = mainList.subList(0, index);
This is telling you that you're trying to assign something of the type List to a variable that's declared as an ArrayList. While an ArrayList is a subtype of List, it doesn't work both ways - you can assign an ArrayList to a List, but not vice versa. So let's change your declaration:
//the error 1 was here, but fixed.
List<RootCreator> sublist = mainList.subList(0, index);
The second one is slightly different:
//error 2 is here
mainSublist.add(sublist);
Here, you've got a list defined to hold items of the type RootCreator - but you're not adding RootCreator items, you're adding a list of them. So if you want to have the list hold other lists, you need to specify that when you create it:
ArrayList<List<RootCreator>> mainSublist = new ArrayList<List<RootCreator>>();
But, if you're trying to just keep a single list and want to add everything from the sublists, then instead, change your code to:
//error 2 was here, but Fixed
mainSublist.addAll(sublist);
Recently while using arrayList I found a weird issue. I want to keep 2 elements in the arraylist and would like to keep object1 in element 0 and object2 in element1.
I am deciding this in a loop.
When it happens to add the first element its throwing indexOutofBounds. As per java doc as the index is greater than size its doing this.
public static void main(String[] args)
{
ArrayList<String> list = new ArrayList<String>();
list.add(1,"SECONDITEM"); // throwing due to size is not set
list.add(0,"FIRSTITEM");
int postn=0;
for(String item:list){
System.out.println("Position "+postn+" :"+item);
postn++;
}
}
Then I tried to setup other items as placeholder in 0,1 element and tried to do same
public static void main(String[] args)
{
ArrayList<String> list = new ArrayList<String>();
list.add(0,"x");
list.add(1,"y");
list.add(1,"SECONDITEM");
list.add(0,"FIRSTITEM");
int postn=0;
for(String item:list){
System.out.println("Position "+postn+" :"+item);
postn++;
}
}
Output:
Position 0 :FIRSTITEM
Position 1 :x
Position 2 :SECONDITEM
Position 3 :y
How to get over this issue. One way I found is to remove the element in the index and add the element. Is there a better option.
public static void main(String[] args)
{
ArrayList<String> list = new ArrayList<String>();
list.add(0,"x");
list.add(1,"y");
list.remove(1);
list.add(1,"SECONDITEM");
list.remove(0);
list.add(0,"FIRSTITEM");
int postn=0;
for(String item:list){
System.out.println("Position "+postn+" :"+item);
postn++;
}
}
Position 0 :FIRSTITEM
Position 1 :SECONDITEM
.add() method insert the element at the given position and shift the other element accordingly
to overwrite the value at particular index you have to use the .set(position, value)
try the set method ..
list.add(0,"x");
list.add(1,"y");
list.set(1,"SECONDITEM");
list.set(0,"FIRSTITEM");
now it will return the only two values.
When you call in this order:
ArrayList<String> list = new ArrayList<String>();
list.add(1,"SECONDITEM"); // throwing due to size is not set
You are trying to add to position "1", but nothing has been added to the list yet. I believe that is why you get the error. Instead you probably want to use just:
ArrayList<String> list = new ArrayList<String>();
list.add("FIRSTITEM");
Since it's an empty list. You can also use the index, but you'll have to increment each time. Makes sense?
The issue is ... you're trying to use a List in a way it wasn't intended to be used. As you've found out, you can't set or add to an index that is outside the range of the current size.
If you know in advance the size you need and it's a fixed size, using a String[] is the better choice.
If you really want/need a dynamic structure that allows random access sets regardless of the current size, write your own method to fill the list when needed:
public static <T> void fillAndSet(int index, T object, List<T> list)
{
if (index > (list.size() - 1))
{
for (int i = list.size(); i < index; i++)
{
list.add(null);
}
list.add(object);
}
else
{
list.set(index, object);
}
}