why does following main method gives IndexOutOfBoundException at list.add(1, 2)?
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
list.add(1, 2);
int total = list.get(0);
System.out.println(total);
}
You can't add an element at index 1 when it the ArrayList is empty. It starts at 0, or just use add.
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
int total = list.get(0); // <-- You even use 0 here!
System.out.println(total);
}
Per the ArrayList#add(int index, E element) javadoc,
Throws:
IndexOutOfBoundsException - if the index is out of range
(index < 0 || index > size())
When size == 0, the index 1 is out of range.
Here's the problem:
list.add(1, 2);
To fix it, do this:
list.add(0, 2);
Or even simpler, this:
list.add(2);
Remember: in Java, lists an arrays start at index 0, you'll get an error if you try to add an element at index 1 in an empty list.
List maintains the insertion order.
We are trying to add an element at index 1, when the list is empty, that is why it results in java.lang.IndexOutOfBoundsException: Index: 1, Size: 0
Quick Solutions:-
Add elements in the list using add() method of the Collection interface.
List list = new ArrayList();
list.add(1);
list.add(2);
Add elements to the list using add(int index, T t) method of the List interface.
List list = new ArrayList();
list.add(0, 1); // Filling 0th index with value 1.
list.add(1, 2); // Filling 1th index with value 2.
Related
I want to duplicate the elements in a linked list. This is what I have tried:
public class duplicate {
public static void main(String[] args) {
LinkedList <Integer> list = new LinkedList<Integer>() ;
list.add(2);
list.add(3);
list.add(4);
list.add(1);
list.add(0);
for( int i= 0 ; i<list.size(); i++) {
list.addAll(list);
System.out.println(list);
break;
}
}
}
But I got an infinite loop.
Firstly, your code runs just fine (the break prevents the infinite loop, see JLS-The break Statement).
Now, you don't need to for-loop over the list because List.addAll already
Appends all of the elements in the specified collection to the end of
this list, in the order that they are returned by the specified
collection's iterator (optional operation) (...)
So, just by doing this you're fine:
LinkedList <Integer> list = new LinkedList<Integer>() ;
//... code omitted (adds every number)
list.addAll(list);
However, if you want to use List.add instead of List.addAll you can do it like this (need to use for-loop):
LinkedList <Integer> list = new LinkedList<Integer>() ;
//... code omitted (adds every number)
int initialSize = list.size();
for( int i = 0 ; i < initialSize; i++) {
list.add(list.get(i));
}
System.out.println(list);
you are adding the list elements again and again in the for loop.
for(int i= 0 ; i < list.size(); i++) {
list.addAll(list);
System.out.println(list);
}
Every time it will grow & which leads the size to grow for each iteration. correct the step. Either use a local variable to store the size or change your logic
You can simply do list.addAll(list);.
If you want to use the add method as an exercise, you need to be careful to save the original size of the list before you start iterating. You can do it in the initialization part of your for loop:
public static void main(String[] args) {
List<Integer> list = new ArrayList<>(Arrays.asList(2, 3, 4, 1, 0));
for (int i = 0, size = list.size(); i < size; i++)
list.add(list.get(i));
System.out.println(list);
assert list.equals(Arrays.asList(2, 3, 4, 1, 0, 2, 3, 4, 1, 0));
}
Now you'll notice the above uses ArrayList, rather than LinkedList. In general, you should prefer ArrayList. Even the author of Java's LinkedList says he doesn't use it. See also this SO question about ArrayList vs LinkedList.
If you have to use LinkedList, you can just replace the second line from the above to this:
List<Integer> list = new LinkedList<>(Arrays.asList(2, 3, 4, 1, 0));
The rest of the code can remain unchanged. However, if you have a very long list, then using the get(index) method of the LinkedList class can reduce performance. With LinkedList, you get higher performance if you iterate (using LinkedList.iterator() or an enhanced for loop, than by using a plain for loop with get() calls. But you can't iterate over the list while adding to it, as you'll then get a ConcurrentModificationException. Instead, you can copy the linked list to an array and iterate over that, while adding to the list:
public static void main(String[] args) {
List<Integer> list = new LinkedList<>(Arrays.asList(2, 3, 4, 1, 0));
for (Integer element : list.toArray(new Integer[0])) {
list.add(element);
}
System.out.println(list);
assert list.equals(Arrays.asList(2, 3, 4, 1, 0, 2, 3, 4, 1, 0));
}
package com.unisys.geeks.arrays;
import java.util.ArrayList;
import java.util.ConcurrentModificationException;
import java.util.List;
public class RemoveElementFromIteration {
static List<Integer> iterateElements() {
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
for (int i = 0; i < list.size(); i++) {
list.remove(i);
}
return list;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
List<Integer> list = iterateElements();
System.out.print(list);
}
catch (ConcurrentModificationException e) {
System.out.println(e.getMessage());
}
}
}
Oracle says this:
remove(int index)
Removes the element at the specified position in this list (optional operation). Shifts any subsequent elements to the left (subtracts one from their indices). Returns the element that was removed from the list.
List = [1,2,3,4]
In the first loop count (i = 0), you remove the element on index 0, which in your case is 1.
List = [2,3,4]
On the second loop count (i = 1), you remove the the element at index 1. But remember that lists are dynamic. So after you removed the Integer 1 in your list. The list changes in size. Now, at index 1, you'll find the Integer 3. After removing the 3, you'll be left with this:
List = [2,4]
Now, the loops counter will be incremented to 2, making the loop condition false. You'll be left with the list
[2,4]
It's because your loop
for (int i = 0; i < list.size(); i++) {
list.remove(i);
}
Is executed only 2 times, because when you call remove() method, size of a list is decreasing. You can modify it to something like:
static List<Integer> iterateElements() {
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
int list_size = list.size();
for (int i = 0; i < list_size; i++) {
list.remove(0);
}
return list;
}
Here is my problem:
I have a list of integers: 7,0,2
If I sort the list using Collections.sort(list) the result is: 0,2,7
but I want to sort the list excluding the 0 from the sorting procedure so the output looks like this: 2,0,7.
Is it possible?
Thanks in advance.
EDIT: I've forgot to mention my 3 possible cases:
1) list contains only one "0" and two numbers
2) list contains two "0" and one number
3) list contains three "0" and no numbers
You can do it but not only with Collections.sort()
Retrieve and store in a variable the index where the 0 Integer is :
Remove the 0 from the List with List.remove(int) where int is the index.
Sort the list with Collections.sort()
Add 0 in the List at the stored index.
In code, it gives :
List<Integer> list = ...;
int indexOf = list.indexOf(Integer.valueOf(0));
list.remove(indexOf);
Collections.sort(list);
list.add(indexOf, Integer.valueOf(0));
Update after question edit to handle cases with more than one 0 in the List.
I updated because this case is a little more complex to handle.
As it removes more than one element, the index is not any longer the index of the original size.
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(7);
list.add(0);
list.add(2);
list.add(9);
list.add(0);
list.add(1);
list.add(0);
list.add(4);
Set<Integer> indexesOf = new HashSet<>();
int indexOf = -1;
int shift = 0;
while ((indexOf = list.indexOf(Integer.valueOf(0))) != -1) {
indexesOf.add(indexOf + shift++);
list.remove(indexOf);
}
Collections.sort(list);
indexesOf.stream().forEach(index -> list.add(index, Integer.valueOf(0)));
System.out.println(list);
}
Output :
[1, 0, 2, 4, 0, 7, 0, 9]
Bubble sort it's your friend!
public static void main(String[] args) {
List<Integer> list = Arrays.asList(7, 0, 2);
for (int i = 0; i < list.size() - 1; i++) {
int a = list.get(i);
for (int j = i + 1; a != 0 && j < list.size(); j++) {
int b = list.get(j);
if (b != 0 && b < a){
list.set(i, b);
list.set(j, a);
a = b; // EDITED
}
}
}
System.out.println(list);
}
how can i make a user enter a number, which will then shift the array to the right 1. the array cant exceed 50. please help, thanks in advance :)
List<Integer> list = new ArrayList<Integer>(1);
public void add(int value) {
list.add(0, value);
for(int i = 0; i < array.length; i++) {
list.add(index, value); // how to make the elements shift to the right?
if(list.size > 50) {
list.remove(50);
}
}
}
List<Integer> list = new ArrayList<Integer>(50);
public void add(int value) {
if (list.size() == 50)
list.remove(list.size() -1);
list.add(value);
}
ArrayList shifts elements for you, that's why it has index, look at this answer.
When you create the ArrayList: new ArrayList<Integer>(50) 50 dont define size, define capacity of the ArrayList. When created is empty and size is 0.
List<Integer> list = new ArrayList<Integer>(50);
public void add(int value) {
if (list.size <= 50) list.remove(list.size() - 1);
// inserting element at position 0 shifts other elements
list.add(0, value);
}
public class TestList {
public static void main(String[] args) {
ArrayList<Integer> arrlist = new ArrayList<Integer>(4);
// use add() method to add elements in the list
arrlist.add(15);
arrlist.add(4);
arrlist.add(5);
// adding element 25 at third position
arrlist.add(2,25);
for (Integer number : arrlist) {
System.out.println("List Value = " + number);
}
}
}
Inserts the specified element at the specified position in this list. Shifts the element currently at that position (if any) and any subsequent elements to the right (adds one to their indices). From this "http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html"
so you need just to check if the size of your list is no longer than 50, and add the number in the specified index.
List<Integer> list = new ArrayList<Integer>(50);
public void add(int value) {
if (list.size() == 50) // if the size of the array is 50, then remove the last value.
list.remove(list.size() -1);
list.add(int index, E element);// you can even choose where position to insert your value.
}
In the constructor part what you have defined is the capacity. The default minimum capacity is 10. You know your array cant exceed to 50. There is a chance that there must be less element then 50. So first remain that constructor part empty.
List<Integer> list = new ArrayList<Integer>();
public void add(int value) {
if(list.size() <50)
list.add(0,value);
else
{
list.remove(list.size()-1);
list.add(0, value);
}
private List<Integer> list = new ArrayList<Integer>(51);
public void add(int value) {
list.add(0, value); //other elements are shifted right, you need do nothing else
//then limit the list to 50 elements
while(list.size() > 50) list.remove(list.size() - 1);
}
I can't see the rest of the code. I don't know what list length is before add so I'm just guaranteeing it's <= 50 after with a while.
You can specify an initial capacity, if you do, use 51 not 50. It gives the array an initial size that can hold your 50, plus the 51st which is in list for a short period before removal.
Suppose we have an array ( int[] m ).
I need sort it... Result must be:
all items in the first half must be less or equal than any items in the second half.
how to do it?...
As Karl already mentioned in his comment, the task is equal to a partinioning step in the quicksort algorithm with the exception that you have to find the sample median first and use it as the pivot element.
Computing a median can be computed with O(n) operations, the partinioning step is linear too (O(n)), so the overall worst-case performance is still better than a full sorting (O(n log(n)).
The algorithm will go like this (standard methods need to be implemented):
public int[] roughSort(int[] input) {
int pivot = findMedian(input);
int[] result = partition(input, pivot);
return result;
}
Arrays.sort(array);
for (int i : array) {
System.out.println(i);
}
Sorting it in ascending order shall be ok for your case.
List<Integer> list = new ArrayList<Integer>();
list.add(2);
list.add(5);
list.add(1);
list.add(15);
list.add(55);
list.add(23);
Collections.sort(list);
int length = list.size();
List<Integer> list1 = list.subList(0, length/2);
List<Integer> list2 = list.subList(length/2, length);
Collections.shuffle(list1);
Collections.shuffle(list2);
List<Integer> newList = new ArrayList<Integer>();
newList.addAll(list1);
newList.addAll(list2);
System.out.println(newList);
Is this what you wanted?