How can i get the most recent objects in a List?
I have tried
int i = 5;
while(i > 0) {
Object o = list.get(list.size() - i);
i--;
}
but to no avail, i could be doing it wrong, but if i am i am unware how to fix my mistake :/
(The problem is it is still giving me the entire list)
You could just reverse the list then iterate over it:
// Your original list
List<Object> list = new ArrayList<Object>(); // Populated elsewhere
// Make a copy, so you don't corrupt the original list
List<Object> reverseList = new ArrayList<Object>(list);
// Reverse the order of its elements
Collections.reverse(reverseList);
// Now iteration will be in "latest added first" order - ie LIFO
for (Object o : reverseList) {
// Do something with o
}
I think that you're expecting your code to change the original list, but this is a wrong assumption since the code simply gets an object held by the list and doesn't remove it. Then you discard the object held by o, so there is no way to test if your method is working or not. To solve this, you've got to save the stuff produced from your method to test if it works or not.
int i = 5;
List savedJunk = new ArrayList();
while(i > 0) {
Object o = list.get(list.size() - i);
savedJunk.add(o);
i--;
}
for (Object foo : savedJunk) {
System.out.println(foo);
}
It's a good question and you pretty much had the right answer. The central idea is that items in a list appear in the order in which you added them, so to get the most recent item you need to go through the list in reverse. Here is one way to do that with a for loop.
ArrayList<String> myList = new ArrayList<String>();
myList.add("one");
myList.add("two");
myList.add("three");
myList.add("four");
for (int index = myList.size() - 1; index >= 0 ; index--) {
System.out.println(myList.get(index));
}
The output of the above code is:
four
three
two
one
Related
I'm trying to iterate over a list os lists but I'm getting CME all the time even using Iterator to remove and add elements while iterating over the lists.
I searched here in the community for similar questions but those I found didn't help me. Really hope you guys help me to figure out how to do what I need to do.
I have I ListIterator<List<Event<T>>> itrListsEvent = partitionSubLists.listIterator();
partitionSubLists is A list of lists. So I have one bigger List and inside it I have four sublists.
I need to iterate over the sublists, and while iterating I remove and add elements. After finishing to iterate over the first sublist, I need to go forward to iterate over the second sublist and so on and so forth.
This is what I've done so far:
public List<List<Event<T>>> partitionedLists (List<Event<T>> list)
{
int listSize = list.size();
int partitionSize = listSize / 4;
List<List<Event<T>>> partitions = new ArrayList<>();
for (int i = 0; i < listSize; i += partitionSize)
{
partitions.add(list.subList(i, Math.min(i + partitionSize, list.size())));
}
return partitions;
}
List<List<Event<T>>> partitionSubLists = partitionedLists(List<Event<T>>);
ListIterator<List<Event<T>>> itrListsEvent = partitionSubLists.listIterator();
while(itrListsEvent.hasNext())
{
List<PrefixEvent<T>> listPE = new ArrayList<Event<T>>();
listPE = itrListsPrefixEvent.next();
ListIterator<Event<T>> itrEvent = listPE.listIterator();
while(itrEvent.hasNext())
{
//here I remove and add elements inside the sublist.
//when finished, I need to go back to first while and go forward to the next sublists
//and in this moment, i got ConcurrentModificationException
itrEvent.remove()
.
.
.
// some code here
itrEvent.add(new Event<T>);
}
}
It's rather unclear exactly what you're trying to achieve. As far as I understand, you could achieve it like this:
List<PrefixEvent<T>> listPE = itrListsPrefixEvent.next();
// No iterator.
for (int i = 0; i < listPE.size(); ++i) {
listPE.remove(i);
// some code here
listPE.add(i, new Event<>());
}
This avoids a ConcurrentModificationException because you don't structurally modify the list after creating an Iterator.
If you don't actually require the "one element removed" list in between the itrEvent.remove() and itrEvent.add(new Event<T>()), you can continue to use the ListIterator, and then set the value to a new value:
itrEvent.set(new Event<>());
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.
I am trying to delete one object from an ArrayList, but after iterating through the list with the for loop i'm stuck at what to do next. nameInput is a lowercase string from the user.
If i run this it prints the object from arr list equal to the input from nameInput. But I cannot understand how to go from printing that object to deleting it?
I'm sure this is a stupid question but the 50+ answers i have read and tried all seem to fail me (or more likely I fail to understand them). I have tried the list.remove and removeIf.
private ArrayList<Arr> arr = new ArrayList<>();
private void removeItem() {
for (Object arr : arr) {
if (((Arr) arr).getName().equals(nameInput())) {
System.out.println(arr);
break;
} else {
System.out.println("Error");
}
}
}
Using for loop
List<Arr> arr = new ArrayList<>();
for (Arr item : arr) {
if (item.getName().equals(nameInput())) {
arr.remove(item);
break;
}
}
If not call break after remove element, you get ConcurrentElementException
Note from #Aomine: you have to implement correct Arr.equals() method.
Using Iterator
List<Arr> arr = new ArrayList<>();
Iterator<Arr> it = arr.iterator();
while (it.hasNext()) {
Arr items = it.next();
if (item.getName().equals(nameInput())) {
it.remove();
break; // you can continue iterating and remove another item
}
}
Using Streams
List<Arr> arr = new ArrayList<>();
arr.removeIf(item -> item.getName().equals(nameInput()));
Remove all items that match given condition
This is not good to remove element from ArrayList. In case you know that you have to remove element from the middle of the List, do use LinkedList.
You are trying to remove an item while you are traversing/iterating the list in the for loop. You cannot remove an item from the list iterating it in a for loop. Use an Iterator instead and invoke arr.remove().
If you use Java 8 you could do
private void removeItem() {
arr.removeIf(t -> t.getName().equals(nameInput));
}
Note that this will remove all objects with name equal to nameInput
Also you should change your declaration of arr to
List<Arr> arr = new ArrayList<>();
A couple of things here...
The loop variable receiver type should ideally be Arr instead of Object as the list contains Arr objects. This also means you no longer need the cast you're performing.
You could remove the item via remove(Object o) but this requires overriding equals and hashcode based on name only. Another option is via an iterator but this would mean changing your code completely. Thus, to keep it as close to your code as possible you can use a for loop; get the index which the object is located and then remove.
Thus, you can do:
for(int i = 0; i < arr.size(); i++){
if (arr.get(i).getName().equals(nameInput)) {
Arr obj = arr.remove(i); // remove the item by index
System.out.println(obj); // print the object
break; // terminate the loop iteration
}
}
How can I modify an arraylist while iterating over it? I would like answers that only deal with whilst I am iterating it please no answers regarding that I can save it and then modify it.
for (ListIterator<CardGroup> ShortSeqGroupListIterator = ShortSeqGroupList
.listIterator(); ShortSeqGroupListIterator.hasNext();) {
CardGroup ShortSeqGroup = ShortSeqGroupListIterator.next();
System.out.println("Iteration --- "+ShortSeqGroup.getCardList());
for (ListIterator<CardGroup> cardGroupListIterator = this.cardGroupList
.listIterator(); cardGroupListIterator.hasNext();) {
CardGroup cardGroup = cardGroupListIterator.next();
if (cardGroup.getCardGroupType() == CardGroupType.PURESEQUENCE
|| cardGroup.getCardGroupType() == CardGroupType.SHORTSEQUENCE) {
continue;
}
Listindex = cardGroupListIterator.nextIndex() - 1;
listOfIndex.add(Listindex);
cardGroup.setCardGroupType(CardGroupType.NONE);
this.mergeExtraGroups();
}
ShortSeqGroup.setCardGroupType(CardGroupType.NONE);
this.mergeExtraGroups();
this.markSets();
this.markSequences(false);
int PenaltyPointsShSeq = totalPenaltyOfUser(this.cardGroupList);
PenaltyMapShortSeq.put(PenaltyPointsShSeq, this.cardGroupList);
this.cardGroupList = clonedCardGroupList;
System.out.println("&************************&");
this.print();
}
NavigableMap<Integer, List<CardGroup>> descendedPenaltyMapShortSeq=PenaltyMapShortSeq.descendingMap();
System.out.println(descendedPenaltyMapShortSeq.firstKey());
I want to operate on the list and then after saving the operation I need to get the previous state of the list back ..
The problem is of course Concurrent modification exception.
The this.cardList is the one I am operating on and the cloned cardgrouplist is a copy of it...
The cardGrouplist 1st element again contains:
An arraylist
Don't use an Iterator, switch it out for a normal for(int i = 0; i < list.length; i++) loop.
It look messy to modify a collection while iterating. I would suggest you to iterate to collect the list of items to add/delete first. Then, perform add/delete the collected item accordingly.
Very rudimentary question but I have a loop e.g.
List<ObjectList> = //set of values inside.
for(Object data : ObjectList){
// how to access next element?
// current element is accesed by 'data'. I could get the index position and then increment but is there a easier way?
}
How would you get the next element/previous? I know there are iterators i can use and so on but i want to know a neat way to do it in a for loop.
You can but don't do it as the time complexity of the loop will
increase. Just use a normal loop with an int i looping variable.
If you still want to do it you can find the index this way:
int index = lst.indexOf(data);
Then index+1 is the index of the next element.
And index-1 is the index of the previous element.
Make two methods for next and pervious and pass list and element.
public static <T> T nextElement(List<T> list,T element){
int nextIndex=list.indexOf(element)+1;
return list.size()<nextIndexlist?null:list.get(nextIndex);
}
public static <T> T previousElement(List<T> list,T element){
int previousIndex=list.indexOf(element)-1;
return list.size()>previousIndexlist?null:list.get(previousIndex);
}
1)First way
for(ObjectList data : objectList){
ObjectList previousElement=previousElement(objectList,data);
ObjectList nextElement=nextElement(objectList,data);
}
2) Second way
for(int i=0;i<=objectList.size();i++){
ObjectList previousElement=objectList.size>i-1?null:objectList.get(i-1);
ObjectList nextElement=objectList.size<i+1?null:objectList.get(i+1);
}
3) Third way using iterator
Actually, your for-each isn't iterating a List. This,
List<ObjectList> = //set of values inside.
for(Object data : ObjectList){
}
Should look something like,
List<ObjectList> al = new ArrayList<>();
for(ObjectList data : al){ // <-- like so.
}
But that won't find any data until you populate the List.
Using a "normal" for-loop, this might be, what you are looking for:
List<Object> objectList = new ArrayList<>();
// add some data
for (int i = 0; i < objectList.size(); i++) {
System.out.println((i > 0) ? "previous Object: " + objectList.get(i - 1) : "No previous object, current is the first one.");
System.out.println("Current Object: " + objectList.get(i));
System.out.println((i < objectList.size()) ? "Next Object: " + objectList.get(i + 1) : "No next object, current is the last one.");
}
Key aspect is, that you have to use your loop variable (i in this case) to access your actual elements. i + 1 gives you the next element and i - 1 the previous.
I think what you is an iterator, its used like this:
List<ObjectList> list= //set of values inside.
Iterator<ObjectList> iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
System.out.println(iterator.previous());
iterator.next()
}
It allows you to access the next and previous objects.
ListIterator:
There is the ListIterator which can a bit of stepping back and forth.
Mind in the code below previousIndex() yields -1 at the start.
for (ListIterator<Object> iter = objectList.listIterator(); iter.hasNext(); ) {
Object object = iter.next();
Object previous = objectList.get(iter.previousIndex()); // Might fail
Object next = objectList.get(iter.nextIndex()); // Might fail
if (iter.hasPrevious()) ... iter.previous();
}