I have a class SimpHisto
that takes in an array of generic type SL
, and returns the size and the count of a specific element of that array. My code is provided down below.
public class SimpHisto<SL> implements Histo<SL>, Iterable<SL> { DT[] items; public SimpHisto() { } public SimpHisto(SL[] items) { this.items = items; } public int getCount(SL item) { var n = 0; Iterator<SL> L = this.iterator(); while (L.hasNext()) { for (DT dt : items) { if (dt == item) { n++; } } } return n; } @Override public Iterator<SL> iterator() { return new Iterate(); } @Override public int getTotalCount() { return items.length; } private class Iterate implements Iterator<SL> { int index = 0; boolean lastRemoved = false; @Override public boolean hasNext() { return (index < items.length); } @Override public SL next() { if (index <= items.length) throw new NoSuchElementException("No element at index"); SL object = items[index]; index++; lastRemoved = false; return object; } }
After I tried to run my code using the snippet down below…
public class SimpleHistogramTest { @Test public void testHistogram() { Character[] s = {'a','b','c','a'}; Histo<Character> h = new SimpHisto<>(s); Iterator<Character> iter = h.iterator(); int elemCount = 0; while(iter.hasNext()) { iter.next(); elemCount++; } assertEquals(3, elemCount); assertEquals(2, h.getCount('a')); assertEquals(1, h.getCount('b')); assertEquals(1, h.getCount('c')); assertEquals(4, h.getTotalCount()); } }
I get an error saying:
> Task :compileJava UP-TO-DATE > Task :processResources UP-TO-DATE > Task :classes UP-TO-DATE > Task :compileTestJava > Task :processTestResources NO-SOURCE > Task :testClasses > Task :test FAILED No element at index
Can someone please explain what’s wrong with my code and provide any explanations on solutions?
Thank you
P.S. this is interface Histo
which is implemented by SimpHisto
public interface Histo<DT> extends Iterable<DT> { public int getTotalCount(); public int getCount(DT item); public void setCount(DT item, int count); }
Advertisement
Answer
The error is in your Iterate
.
You throw that exception if (index <= items.length)
.
index
starts with 0 so this is always true
.
You only have to change to >=
As mentioned by 英語は苦手 your while
in getCount
does not call next
.
Since you iterate over the items directly I would prefer to remove the Iterator
at all.
And a Stream
may increase readability:
return (int) Stream.of(this.items) .filter(dt -> dt == item) .count();
EDIT: without Stream
-API you can iterate over your items
directly:
for (SL dt : this.items) { if (dt == item) { n++; } }
If you want to use the Iterator
you have to call next
while (L.hasNext()) { SL dt = L.next(); if (dt == item) { n++; } }
BTW: why assertEquals(3, elemCount);
? There are 4 elements