Reputation: 457
The purpose of the method removeDuplicate(ArrayList<Card> l)
is that removing the duplicated object based on the attribute card_value
in class Card
and then add them to an ArrayList and return the arr.
But my program return an error: NoSuchElementException
at the line
dum.add((Card) it.next());
I have no idea what's going on here because I print out the object that returned by the next()
method, it prints out perfectly.
Someone please show me why I get mistake in the implementation below:
private ArrayList<Card> removeDuplicate(ArrayList<Card> l){
int end = l.size();
Set<Card> set = new HashSet<>();
for(int i = 0; i < end; i++){
set.add(l.get(i));
}
ArrayList<Card> dummy = new ArrayList<>();
Iterator it = set.iterator();
while(it.hasNext()){
System.out.println(it.next());
dummy.add((Card) it.next());
}
return dummy;
}
And these are override methods:
@Override
public int hashCode() {
int hash = 5;
hash = 97 * hash + this.card_value;
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == this){
return true;
}
if (!(obj instanceof Card)){
return false;
}
Card other = (Card) obj;
return (this.card_value == other.card_value);
}
Upvotes: 1
Views: 628
Reputation: 5067
Here you can see the source code of the next()
method from java Iterator
. It looks something like this:
public E next() {
checkForComodification();
try {
int i = cursor;
E next = get(i);
lastRet = i;
cursor = i + 1;
return next;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
As you can see, if you are out of the array a NoSuchElementException
will be thrown. So calling next()
twice without checking before each call if elements are still available by using hasNext()
will have the behaviour you described.
Your while()
should be replaced with:
while(it.hasNext()) {
dummy.add((Card) it.next());
}
But if you really want the print-out as you have it, just change it to:
while (it.hasNext()) {
Card card = (Card)it.next();
System.out.println(card);
dummy.add(card);
}
The second approach is the better way to go when you need to use an object more than once in a method or loop if the method called may be expensive.
Upvotes: 2
Reputation: 2481
because next() moves on the pointer each time, so when you print it out, it will print the last one, then try to move on again the line after
Upvotes: 0
Reputation: 10626
It.next()
returns the next item.
What you do in your code is calling it.next() twice
Upvotes: 1
Reputation: 30568
You are calling .next()
twice. next()
fetches the next element in the iterator but you only check hasNext()
before the first one.
Change
while(it.hasNext()){
System.out.println(it.next());
dummy.add((Card) it.next());
}
to
while(it.hasNext()){
Card nextCard = (Card) it.next();
System.out.println(nextCard);
dummy.add(nextCard);
}
Upvotes: 5