My texted book that uses an inner class as an iterator says that the method hasNext is just return current < this.size; where current is the current index. But if the size is 3 and the index is 2, there wouldn't be a next value, so why wouldn't it be < size - 1
I am not sure which Iterator implementation your are referring to but talking about java implementation it is like below:
public boolean hasNext() {
return cursor != size; //cursor is the index of next element to be fetched
}
So the implementation you are referring to I believe current actually refers to the element to be fetched next.
Lets take your example:
Size : 3
current : 2
condition: 2<3(true) returns true and next() gets you the list.get(current)
Size:3
current :3
Condition : 3<3(fail) you don't have anymore element to iterate as you reached to the end.
Depends on what you are doing in next method. Check the code from ArrayList.Itr implementation. Here is one way of implementing scenario you described(this is similar to ArrayList.Itr implementation),
current initially points to 0.
When next is called, current value of current is saved to a variable, say, i. current is incremented.
The value at index i is returned.
In above case if the current value is 3, there are no more elements. The logic is right. The iterator have elements as long as current<size.
Probably because it hasn't given the value at the index current yet. The function hasNext just tells you if there is something left to get out of an Iterator. For example if you'd like to print all the contents of an Iterator you would do something like this:
while (iterator.hasNext()) {
System.out.print(iterator.next());
}
Where the functions hasNext and next would be defined as something like:
public boolean hasNext() {
return current < this.size;
}
public T next() {
return this.array[current];
current++;
}
Related
My Problem
I have a fixed-size ArrayList which contains custom variables. Despite of the ArrayList having a fixed size, sometimes a lot of them will actually be null. The thing is that I need to return the ArrayList without the null variables inside it. One important thing to note: the ArrayList will have all of its non-null items first, and then all of the nulls below them, e.g., the elements are not mixed. Example: [non-null, non-null, .... null, null, null]
My workaround
I though of creating a for-loop that checked (from last to first index) each of the elements inside the ArrayList to determine if it's null or not. If is null, then I'd call this code:
for (i = size-1; i >=0 ; i--) {
groupList = new ArrayList<>(groupList.subList(0, i));
}
My question
If the ArrayList is too big, this method might me particularly slow (or not?). I was wondering if there exists a better, more performance-friendly solution. AFAIK the .subList method is expensive.
You can have a variant of binary search, where your custom comparator is:
Both elements are null/not null? They are equal
Only one element is null? The none null is "smaller".
You are looking for the first null element.
This will take O(logn) time, where n is the size of the array.
However, taking the sublist of the ArrayList that is none null (assuming you are going to copy it to a new list object), is going to be linear time of the elements copied, since you must "touch" each of them.
This gives you total time complexity of O(logn + k), where k is number of non null elements, and n is the size of the array.
Following all of your outstanding advices, I modified the original method so that I can take the last (first) ever null item position and call the .subList method just once. And here it is:
int lastNullIndex = size - 1;
for (i = lastNullIndex; i >= 0; i--) {
if (null == groupList.get(i)) {
lastNullIndex = i;
} else {
break;
}
}
groupList = new ArrayList<>(groupList.subList(0, lastNullIndex));
return groupList;
If you think it can be further modified so as to allow for a better performance, let us know.
I'd like to store a list of numbers 1,2,3,4 - (lets start with List<Integer>)
I'd like to make sure numbers are unique (ok, fine, Set<Integer>)
I'd like to guarantee order (ok ... LinkedHashSet<Integer>)
I'd like to get the last element from the list ..
What would be the simplest way to get the last number inserted into the LinkedHashSet<Integer> please?
There's no prebaked option for this. There's two off-the-cuff options, and neither are good:
The Order n approach:
public <E> E getLast(Collection<E> c) {
E last = null;
for(E e : c) last = e;
return last;
}
Yuck! But there's also an Order 1 approach:
class CachedLinkedHashSet<E> extends LinkedHashSet<E> {
private E last = null;
#Override
public boolean add(E e) {
last = e;
return super.add(e);
}
public E getLast() {
return last;
}
}
This is off the cuff, so there might be a subtle bug in it, and for sure this isn't thread safe or anything. Your needs may vary and lead you to one approach over another.
With java-8, you could get a sequential Stream of the LinkedHashSet, skip the first n-1 elements and get the last one.
Integer lastInteger = set.stream().skip(s.size()-1).findFirst().get();
First of all, I agree with corsiKa's solution which suggests an extended version of LinkedHashSet class that contains a pointer to the last element. However, you can use a traditional way by consuming some space for an array:
set.toArray()[ set.size()-1 ] // returns the last element.
here is a implementation that adds method to access the last entry O(1):
LinkedHashSetEx.java
enjoy...
Sets are independent of order.We cannot access element by index.If you require last element,
1)create new ArrayList(Set)
The last element of an arrayList can be accessed easily
I'm working on a project for school but i'm a little stuck right now
My problem is that i have an arrayList of Squares
Each Square has a value(from 0 to 100). Its starting value is 9999 so i can check if its is checked.
If a square is checked i want it to be removed from the arrayList.
So after a while there will be no Squares left.
there is a little bit of code where the first value is set so thats why i check if the value is 9999.
But i get an error. One that i havent seen before.
Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException
Vak = Square
this is my code:
while (!vakken.isEmpty()) { // check if empty
Iterator itrVak = vakken.iterator();
while (itrVak.hasNext()) {
Vak vak = (Vak) itrVak.next(); // here is get the error
if (vak.getValue() != 9999) {// check if square value is 9999
Collection checkVakken = vak.getNeighbour().values();
Iterator itre = checkVakken.iterator();
while (itre.hasNext()) {
Vak nextVak = (Vak) itre.next();
if (nextVak != null) {
if (nextVak.getValue() == 9999) {
nextVak.setValue(vak.getValue() + 1); // set value by its neighbour
vakken.remove(vak);
checkvakken.add(vak);
}
}
}
} else {
vakken.remove(vak);
checkvakken.add(vak);
}
}
}
You are removing elements from the collection while you are iterating it. As the iterator may produce unpredictable results in this situation, it fails fast throwing the exception you encountered.
You may only alter a collection through the iterator's methods while traversing it. There should be remove method on the iterator itself, that removes the current element and keeps the iterator intact.
While iterating, you should use Iterator instance for removing object:
itre.remove();
You can try like this:
itre.remove();
ITERATOR never lets you modify when you are iterating.. you need to use loops instead.. this happens coz you are using the Iterator, same time other thread is modifying the list...
I wrote a custom iterator class that iterates over the set of numbers found in a PoSet, and here is my code:
private class IntGenerator implements Iterator {
private Iterator<Integer> i;
private Set<Integer> returnedNumbers;
public IntGenerator () {
returnedNumbers = new HashSet<Integer> ();
i = S.iterator();
}
public boolean hasNext() {
return i.hasNext();
}
public Object next() {
int n = i.next();
for (Pair p : R) {
if (isInSecondElmPair(p, n)) {
if (returnedNumbers.contains(p.getFirstElm())) {
returnedNumbers.add(n);
return n;
}else{
returnedNumbers.add(p.getFirstElm());
return p.getFirstElm();
}
}else if (isInFirstElmPair(p, n)){
returnedNumbers.add(n);
return n;
}
}
return n;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
The thing is that when returning a number, I should abide by the partial order rules, that is:
1. if (x, y) belongs to R, then x should be returned before y
However the code above seems to follow that ordering but it is creating duplicates, how can I fix my code to not allow it?
NOTE: In my code, S is the set of numbers in the PoSet, it is a HashSet and R is an arraylist of pairs (pair: a class i created that takes 2 ints as param) to hold the relations in the PoSet.
Is there any way to fix this problem?
Thanks
Your next method always calls i.next(), and returns one of two things:
the value that i.next() returned
some value that is less than that value.
This means that if your poset contains {1,2,3,4} and uses the natural ordering for integers, and i.next() returns 4, then either you return 4 now (due to 1, 2, and 3 already having been returned), or you will never return 4 (because it's not less than any future value).
The reason you're getting duplicates is that you return one value for every value of i.next(), and there are some values that never get returned (see previous paragraph), so naturally there are some values that get returned multiple times in compensation. Note that you never check whether the value returned from i.next() has previously been returned by your next() method, so if an element in the poset is not greater than any other element, then when i.next() returns that element, your next() method will automatically return it, even if it has previously returned it.
I think the only sensible fix for this to completely change your approach; I don't think your current approach can readily be made to work. I think your iterator's constructor needs to copy all the elements of the poset into an acceptably-ordered list, and then the next() method will simply return the next element of that list. Or, alternatively, since your current approach already requires iterating over R on every call to next() anyway, it might make more sense to base your iterator on an iterator over R. (I'm assuming here that R is already ordered using itself; if it's not, then your for loop makes no sense at all, and will essentially return randomly selected elements.)
If you do want to try to stick with your approach, then you'll need to keep track not only of the elements that your next() method has returned, but also of the elements that i.next() returned but that your next() method did not return; you'll need to be able to return these elements later.
Also, your for (Pair p : R) loop doesn't do what you want — it automatically returns n as soon as it finds any element that is less than n that's already been returned, even if there are other elements less than n that haven't been returned yet. (This is if R is already ordered using itself. If it isn't, then this loop has even bigger problems.)
My dipslay function of linked list is as follows:-
public void display()
{
cur = first;
if(isEmpty())
{
System.out.println("no elements in the list");
}
else
{
System.out.println("elements in the list are:");
do {
System.out.println(first.data);
first = first.link;
} while(first.link!=null);
first=cur;
}
where curr and first are references of class node
public class node
{
int data;
Node link=null;
}
why is this function only printing the last element?
The function looks more or less correct. However why are you setting cur to first and then using first to do the iteration? Just use cur in the iteration so you don't have to reset first.
Check to make sure you're adding nodes into the list correctly. So if you think there are 3 elements in the list, run this in display():
System.out.println(first.data);
System.out.println(first.link.data);
System.out.println(first.link.link.data);
This is to check if your links are correct.
It is not possible to say for sure, but it is probable that your list actually contains only one element; i.e. that the code that creates the list is broken.
I should also point out that the display method should use a local variable to step through the elements. If you use an instance variable (e.g. first) you are liable to get different methods interfering with each other.
Finally, your test for the end of the list is incorrect. Think carefully about what first and first.link point at when the while test is executed.