Need help useing a Iterator in java - java

I am trying to print out a array list of linked lists of size 8 using an Iterator here is what I have so far
ArrayList<LinkedList> myaol = new ArrayList<>();//my array which the linked lists are created when needed
public void printList(Iterator<Gen> itr)//gen is the generic data type
{
while( this.hasNext() )
{
System.out.println(this.next());
}
}
I under stand how to iterate through one linked list but am not sure how to go to the next index of the the arraylist in order to get every linked list any help would be much appreciated

Since you have an ArrayList of LinkedLists, you can get each LinkedList with the following code, and do whatever you want to do with the LinkedLists...
ArrayList<LinkedList> myaol = new ArrayList<>();
Iterator<LinkedList> itr = myaol.iterator();
while (itr.hasNext()) {
LinkedList myList = itr.next();
}
You can print the list like that
// print the list
System.out.println("LinkedList:" + myList);
// create an array and copy the list to it
Object[] array = myList.toArray();
// print the array
for (int i = 0; i < myList.size(); i++) {
System.out.println("Array:" + array[i]);
}

Related

ConcurrentModificationException When removing element using list iterator java

I have an issue removing the 1st and 2nd element of my list even by using the iterator.
I have read the following threads but can't fix my issue (those were the most relevant but I checked other material as well):
ConcurrentModificationException when trying remove element from list
Iterating through a Collection, avoiding ConcurrentModificationException when removing objects in a loop
So my code looks like this:
List<List<String>> list = cnf.read();
List<List<String>> nlist = new ArrayList<>();
for (List<String> l : list) {
if (l.size() <= 3) {
nlist.add(l);
} else {
int size = l.size();
while (size > 3) {
List<String> three = l.subList(0, 2);
three.add("Y" + (count++));
//Iterator itr = l.iterator();
ListIterator itr = l.listIterator();
int v = 0;
while (itr.hasNext()) {
itr.next();
if (v == 0 || v == 1) {
itr.remove();
v++;
}
}
l.add(0, "Y" + (count++));
size--;
nlist.add(three);
}
nlist.add(l);
}
}
for (List<String> l : nlist) {
System.out.println(l.toString());
System.out.println(l.size());
}
I get a ConcurrentModificationException at the print statement here :
System.out.println(l.toString());
I tried using iterators for my 2 for loops as well but It doesn't seem to make a difference!
I am new to posting questions so let me know If I am doing it right!
Thank you.
After A long debugging, here is the solution.
The sublist function passes by reference and not by value, a sublist created by ArrayList.subList call keeps a reference to the original list and accesses its elementData array directly.
For this reason, when adding an element to the "three" list, we alter the state of the original list. this happens here:
three.add("Y" + (count++));
A way of fixing it for this specific case is to create and initialize the "three" list the following way:
String one = l.get(0);
String two = l.get(1);
List<String> three = new ArrayList<>();
three.add(one);
three.add(two);
three.add("Y" + (count));
This allows us to manipulate our lists without getting Concurrency Exceptions (ConcurrentModificationException). However, if you are manipulating big lists, I would suggest you use another less hardcoded method for list creation.
I will mark this thread as answered and hope it helps people.

Swaping the elements of a list

i am having a List of objects and i i wants to do some operation on the list in such a way that the a particular object should be shifted to list position 0 and the the object at position 0 will take place the shifted object. the diagram is as shown below.
the list is as follows
final List<Object> list= new ArrayList<Object>();
presently i have made two temporary lists as
final List<Object> temp1= new ArrayList<Object>();
final List<Object> temp2= new ArrayList<Object>();
to do the operation i am running a loop and on particular condition adding object to temp1 else adding to temp2 , something like as follows :
for (int i = 0; i < 5; i++) {
if (i==3) {
temp1.add(i);
} else {
temp2.add(i);
}
}
and finally doing
list.addAll(temp1);
list.addAll(temp2);
how to do the same logic in redundant and effective steps rather than using temp lists.
Use this swap method:
Collections.swap(List<?> list, int i, int j);
Try this code:
Object temp = list.get(0);
list.set(0, list.get(3));
list.set(3, temp);

change a list while iterating or using a for each loop

I am trying to iterate (or use a for each loop) on a Linked list class and be able to change the item (when found) to a passed in parameter.
for(Item n : items)
{
if (n.getKey().equals(key))
{
n = new Item(key, value);
}
}
Does this change of data work or is it temporary (only to be lost when the activation record is deleted)?
You can't iterate over a collection and modify it. You will always get a java.util.ConcurrentModificationException. First off all you need to use an iterator, to remove the item. Then you can use a second list to store the data you want to add.
Here you are an example:
LinkedList<String> linkedList = new LinkedList<String>();
linkedList.add("This");
linkedList.add("is");
linkedList.add("an");
linkedList.add("test");
LinkedList<String> temp = new LinkedList<String>();
for (Iterator<String> iterator = linkedList.iterator(); iterator.hasNext();) {
String string = (String) iterator.next();
if(string.equals("an")) {
iterator.remove();
temp.add("a");
}
}
linkedList.addAll(temp);
You can call iterator.remove() to savely remove the current item from list.
You are using fast enumeration, which protects the list that you are iterating through. If you would like to change the data in the list, you would need to use a traditional for loop.
Basically how fast enumeration works is it makes the array read-only in the block of code because you have no access to what integer the iteration is.
You could do this:
for(int i = 0; i < items.length; i++)
{
if (n.getKey().equals(key))
{
items[i] = new Item(key, value);
}
}

How to remove items from generic arraylist in Android (Java)

I have a generic arraylist of an object here I want to remove certain elements, The problem is when I iterate the list with for loop, I can't do a simple sequence of remove()'s because the elements are shifted after each removal.
Thanks
Use Iterator to remove element
Like
Iterator itr = list.iterator();
String strElement = "";
while (itr.hasNext()) {
strElement = (String) itr.next();
if (strElement.equals("2")) {
itr.remove();
}
}
See here
You can iterate the list this way ...
public void clean(List<Kopek> kopeks) {
for(Kopek kopek : kopeks) {
if (kopek.isDirty())
kopeks.remove(kopek);
}
}
Which is equiv to ...
public void clean1(List<Kopek> kopeks) {
Iterator<Kopek> kopekIter = kopeks.iterator();
while (kopekIter.hasNext()) {
Kopek kopek = kopekIter.next();
if (kopek.isDirty())
kopeks.remove(kopek);
}
}
Don't do this ... (due to the reason you have already observed.)
public void clean(List<Kopek> kopeks) {
for(int i=0; i<kopeks.size(); i++) {
Kopek kopek = kopeks.get(i);
if (kopek.isDirty())
kopeks.remove(i);
}
}
However, I believe removal by index rather than by object is more efficient. Removal by object is not efficient because the list is in most cases not a hashed list.
kopeks.remove(kopek);
vs
kopeks.remove(i);
To achieve positional remove, by treating a moving target appropriately ...
public void clean(List<Kopek> kopeks) {
int i=0;
while(i<kopeks.size()) {
Kopek kopek = kopeks.get(i);
if (kopek.isDirty()) // no need to increment.
kopeks.remove(i);
else
i++;
}
}
If you have the objects that you want to remove from your ArrayList<T> you can use :
mArrayList.remove(object);
or you can use an Iterator to remove your objects:
while(iterator.hasNext()){
if(iterator.next() == some condition for removal){
iterator.remove();
}
}
You could iterate backwards and remove as you go through the ArrayList. This has the advantage of subsequent elements not needing to shift and is easier to program than moving forwards.
List<String> arr = new ArrayList<String>();
ListIterator<String> li = arr.listIterator(arr.size());
// Iterate in reverse.
while(li.hasPrevious()) {
String str=li.previous();
if(str.equals("A"))
{
li.remove();
}
}
Create a separate ArrayList of Index of the data to be removed from the original ArrayList, then remove those elements by looping over it with for loop.
ArrayList<Myobj> arr = new ArrayList<Myobj>();
for (Myobj o : arr){
arr.remove(arr.indexOf(o));
}
without using iterators also solves the issue.. All i wanted to do is get the index which are to be deleted and sort it in decending order then remove it from the list.
check the code below
Arraylist<obj> addlist = getlist();
List<Integer> indices = new ArrayList<Integer>();
for(int i=0; i<addlist.size() ;i++){
if(addlist.get(i).getDelete()){
indices.add(i);
}
}
Collections.sort(indices, Collections.reverseOrder());
for (int i : indices)
addlist.remove(i);

How to add element in List while iterating in java?

Say I have a List like:
List<String> list = new ArrayList<>();
list.add("a");
list.add("h");
list.add("f");
list.add("s");
While iterating through this list I want to add an element at the end of the list. But I don't want to iterate through the newly added elements that is I want to iterate up to the initial size of the list.
for (String s : list)
/* Here I want to add new element if needed while iterating */
Can anybody suggest me how can I do this?
You can't use a foreach statement for that. The foreach is using internally an iterator:
The iterators returned by this class's iterator and listIterator
methods are fail-fast: if the list is structurally modified at any
time after the iterator is created, in any way except through the
iterator's own remove or add methods, the iterator will throw a
ConcurrentModificationException.
(From ArrayList javadoc)
In the foreach statement you don't have access to the iterator's add method and in any case that's still not the type of add that you want because it does not append at the end. You'll need to traverse the list manually:
int listSize = list.size();
for(int i = 0; i < listSize; ++i)
list.add("whatever");
Note that this is only efficient for Lists that allow random access. You can check for this feature by checking whether the list implements the RandomAccess marker interface. An ArrayList has random access. A linked list does not.
Iterate through a copy of the list and add new elements to the original list.
for (String s : new ArrayList<String>(list))
{
list.add("u");
}
See
How to make a copy of ArrayList object which is type of List?
Just iterate the old-fashion way, because you need explicit index handling:
List myList = ...
...
int length = myList.size();
for(int i = 0; i < length; i++) {
String s = myList.get(i);
// add items here, if you want to
}
You could iterate on a copy (clone) of your original list:
List<String> copy = new ArrayList<String>(list);
for (String s : copy) {
// And if you have to add an element to the list, add it to the original one:
list.add("some element");
}
Note that it is not even possible to add a new element to a list while iterating on it, because it will result in a ConcurrentModificationException.
I do this by adding the elements to an new, empty tmp List, then adding the tmp list to the original list using addAll(). This prevents unnecessarily copying a large source list.
Imagine what happens when the OP's original list has a few million items in it; for a while you'll suck down twice the memory.
In addition to conserving resources, this technique also prevents us from having to resort to 80s-style for loops and using what are effectively array indexes which could be unattractive in some cases.
To help with this I created a function to make this more easy to achieve it.
public static <T> void forEachCurrent(List<T> list, Consumer<T> action) {
final int size = list.size();
for (int i = 0; i < size; i++) {
action.accept(list.get(i));
}
}
Example
List<String> l = new ArrayList<>();
l.add("1");
l.add("2");
l.add("3");
forEachCurrent(l, e -> {
l.add(e + "A");
l.add(e + "B");
l.add(e + "C");
});
l.forEach(System.out::println);
We can store the integer value while iterating in the list using for loop.
import java.util.*;
class ArrayListDemo{
public static void main(String args[]){
Scanner scanner = new Scanner(System.in);
List<Integer> list = new ArrayList<Integer>();
System.out.println("Enter the number of elements you wanna print :");
int n = scanner.nextInt();
System.out.println("Enter the elements :");
for(int i = 0; i < n; i++){
list.add(scanner.nextInt());
}
System.out.println("List's elements are : " + list);
/*Like this you can store string while iterating in java using forloop*/
List<String> list1 = new ArrayList<String>();
System.out.println("Enter the number of elements you wanna store or print : ");
int nString = scanner.nextInt();
System.out.println("Enter the elements : ");
for(int i = 0; i < nString; i++){
list1.add(scanner.next());
}
System.out.println("Names are : " + list1);
scanner.close();
}
}
Output:
Enter the number of elements you wanna print :
5
Enter the elements :
11
12
13
14
15
List's elements are : [11, 12, 13, 14, 15]
Enter the number of elements you wanna store or print :
5
Enter the elements :
apple
banana
mango
papaya
orange
Names are : [apple, banana, mango, papaya, orange]

Categories