I'm doing kind of a 'decorator' to List Collection in Java. Sth is wrong and i have no idea what it is. Here is my code and observed error.
1. myListContainer.java
public class myListContainer<T> implements List<T>{
List<T> basicList;
public myListContainer(List<T> basicList) {
this.basicList = basicList;
}
#Override
public Iterator<T> iterator() {
return new myIterator();
}
private class myIterator implements Iterator<T>{
int actIndex;
int visitTwice;
public myIterator() {
this.actIndex = 0;
this.visitTwice = 0;
}
#Override
public boolean hasNext() {
if (actIndex < basicList.size() - 1)
return true;
else if (actIndex == basicList.size() - 1 &&visitTwice < 1)
return true;
return false;
}
#Override
public T next() {
if (this.hasNext()) {
if (visitTwice < 1) {
visitTwice = 1;
return basicList.get(actIndex);
} else {
visitTwice = 0;
return basicList.get(actIndex++);
}
}
throw new ArrayIndexOutOfBoundsException();
}
}
//implementation of methods form List<T> interface
}
2. Client.java (psvm) AND A PROBLEM
public class Client {
List<String> test = new myListContainer<>(Arrays.asList("Janek",
"Bartek", "Stefan", "Horacy", "Jakub", "Antoni"));
boolean bl = test.iterator().hasNext(); //ok,
Iterator iter = test.iterator();
iter.hasNext(); //not ok, cannot resolve hasNext
}
PROBLEM:
1. test.iterator().hasNext() WORKS Fine
2. iter.hasNext() DOESN'T WORK, it is not visible(hasNext), 'Cannot resolve symbol'
EDIT: Certainly all files are in one module, and has necessary imports.
The problem is the scope of the call, in this scope of the class you should initialize or declare members/instance-variables.
This is works - boolean bl = test.iterator().hasNext(); //ok,
Iterator iter = test.iterator(); because it's a declarations of a class members.
So if yo'll try to call hasNext() in function scope- it will work. see example:
public class Client {
List<String> test = new myListContainer<>(Arrays.asList("Janek",
"Bartek", "Stefan", "Horacy", "Jakub", "Antoni"));
boolean bl = test.iterator().hasNext(); //ok,
Iterator iter = test.iterator();
public void foo() {
while (iter.hasNext()) { // here it will work!
}
}
}
I am very sorry, accidentally i deleted my main function and it was a problem. Sorry again.
QUESTION COULD BE DELETED, its just my simple mistake, sorry.
Related
I am currently trying to implement Iterator which receives a collection and a char and that yields the
Strings that starts with that char.
So I ended up with the following (working) code:
class A {
public static void main (String [] args) {
String [] arr = {"abcd","gr","gres","bvg","bb"};
class FirstCharIt implements Iterator<String> {
char c;
private Iterator<String> it;
public FirstCharIt (Collection<String> lst,char c) {
this.c = c;
this.it = lst.stream().filter(x->{
return (x.charAt(0)==this.c);
}).iterator();
}
#Override
public boolean hasNext() {
return it.hasNext();
}
#Override
public String next() {
return it.next();
}
public Iterator<String> get () {
return it;
}
}
FirstCharIt it1 = new FirstCharIt(Arrays.asList(arr),'b');
for (it1.get();it1.hasNext();) {
System.out.println(it1.next());
}
}
}
Although this code is working this is not actually implementing Iterator interface and I even can remove the 'implements Iterator' from my class headline.
And of course the method get wasn't there in more right implementation
So I would like to have some advice about what I did here,
thanks
Filter the input list at initialization, have that filtered collection and an index as fields of your iterator.
Have hasNext() check if the index has reached the end of the filtered collection, and next() increase the index and return the element it previously pointed at.
static class FirstCharIt implements Iterator<String> {
private int currentIndex;
private List<String> filtered;
public FirstCharIt (List<String> coll, char letter) {
this.filtered = coll.stream().filter(x->x.startsWith(""+letter)).collect(Collectors.toList());
this.currentIndex = 0;
}
#Override
public boolean hasNext() {
return currentIndex < filtered.size();
}
#Override
public String next() {
if (!hasNext()) { throw new NoSuchElementException(); }
return filtered.get(currentIndex++);
}
}
You can try it here.
I'm writing an ArrayStack class that uses an iterator. I know using an iterator for a stack doesn't necessarily make sense but this is for homework purposes. I am having trouble with the remove method. I understand its description but I'm having trouble implementing it. Here is the inner class of my program:
private class StackIterator implements Iterator<Item> {
private int index;
private boolean canremove;
public StackIterator() {
index = size - 1;
canremove = false;
}
#Override
public boolean hasNext()
{
return index > 0;
}
#Override
public Item next()
{
if (!hasNext()) {
throw new NoSuchElementException("There is no next element"+
" in the stack.");
}
canremove = true;
return contents[--index];
}
#Override
public void remove() {
if (!canremove) {
throw new IllegalStateException("Can only remove an element"
+ "after a call to the next method has been made.");
}
canremove = false;
}
}
How do I actually go about removing the element? Do I just decrease size? Or do I need more variables to keep track? Any help is appreciated.
I have implemented a SubListIterator which is a small utility Iterator for iterating over sublists of a given list.
Suppose I have a List containing 13500 elements and I want to split it into 7 sublists and use them.
#Test
public void shouldSplitTheGivenListIntoSmallerLists() {
List<Long> given = new ArrayList<Long>();
for (int count = 0; count < 13500; count++) {
given.add(Long.valueOf(count));
}
List<List<Long>> actualSubLists = new ArrayList<List<Long>>();
for (List<Long> subList : SubListIterator.subList(given, 2000)) { // Line got compilation error
actualSubLists.add(subList);
}
assertEquals(7, actualSubLists.size());
}
Everything works well if I implement the SubListIterator directly with List<Long>.
Then I wanted to extend my SubListIterator to work with every List regardless their generic type, so I went changing List<Long> to List<?> and get the compilation error:
Type mismatch: cannot convert from element type List<?> to List<Long>
I tried with List<T> and it doesn't work either.
My question is: Is there anyway to achieve my goal which is making the SubListIterator to work with every List, not just List<Long>?
Below is the SubListIterator:
public class SubListIterator implements Iterator<List<?>>, Iterable<List<?>> {
public static SubListIterator subList(List<?> given, int itemsEachSubList) {
return new SubListIterator(given, itemsEachSubList);
}
private final List<?> whole;
private final int elementsEachPart;
private int fromIndex;
private int toIndex;
public SubListIterator(List<?> whole, int itemsEach) {
this.whole = whole;
this.elementsEachPart = itemsEach;
this.fromIndex = 0;
this.toIndex = elementsEachPart;
}
#Override
public boolean hasNext() {
return fromIndex < toIndex;
}
#Override
public List<?> next() {
List<?> nextSubList = whole.subList(fromIndex, toIndex);
fromIndex = toIndex;
toIndex = Math.min(toIndex + elementsEachPart, whole.size());
return nextSubList;
}
#Override
public void remove() {
throw new UnsupportedOperationException("This method is not supported");
}
#Override
public Iterator<List<?>> iterator() {
return this;
}
}
Thanks for your support
You need to generalize your SubListIterator.
public class SubListIterator<T> implements Iterator<List<T>>, Iterable<List<T>> {
public static <C> SubListIterator<C> subList(List<C> given, int itemsEachSubList) {
return new SubListIterator<C>(given, itemsEachSubList);
}
private final List<T> whole;
private final int elementsEachPart;
private int fromIndex;
private int toIndex;
public SubListIterator(List<T> whole, int itemsEach) {
this.whole = whole;
this.elementsEachPart = itemsEach;
this.fromIndex = 0;
this.toIndex = elementsEachPart;
}
#Override
public boolean hasNext() {
return fromIndex < toIndex;
}
#Override
public List<T> next() {
List<T> nextSubList = whole.subList(fromIndex, toIndex);
fromIndex = toIndex;
toIndex = Math.min(toIndex + elementsEachPart, whole.size());
return nextSubList;
}
#Override
public void remove() {
throw new UnsupportedOperationException("This method is not supported");
}
#Override
public Iterator<List<T>> iterator() {
return this;
}
}
I'm creating an ArraySetIterator Class and having trouble with the next() method.
I have done some research but nothing seems to work for me. I'm sure its a simple piece of code but I can't seem to figure it out....
private class ArraySetIterator <E> implements Iterator <E> {
private ArraySet<E> set;
private int index = 0;
public ArraySetIterator(ArraySet<E> set) {
this.set = set;
}
public boolean hasNext() {
return (index + 1) < set.size();
}
public E next() {
???
}
public void remove() {
set.remove(index);
}
}
next() should increase the index and return the current element. I addition, it should throw NoSuchElementException if there are no more elements left to iterate over.
This works:
public E next() {
return set.get(index++);
}
You might also want to think about checking to see if hasNext() is true.
EDIT: Based on your comment, it sounds like your ArraySet is only implementing the Set interface. So you can't use .get(). I think you need do do something like this instead:
private class ArraySetIterator <E> implements Iterator <E> {
private E[] set;
private int index = 0;
public ArraySetIterator(ArraySet<E> set) {
this.set = (E[]) set.toArray();
}
public boolean hasNext() {
return (index + 1) < set.length;
}
public E next() {
if(hasNext) {
return set[index++];
} else {
throw new NoSuchElementException();
}
}
public void remove() {
throw new UnsupportedOperationException();
}
}
The question but in C#. So does Java have C#'s command? I need it for Matches-SearchTerm-Files-relationship.
foreach(var i in BunchOfItems.SelectMany(k => k.Items)) {}
[Why not for-loops?]
I have done such structures in nested for loops but they soon become bloated. So I prefer something more succint like the above.
public static Stack<Integer[]> getPrintPoss(String s,File f,Integer maxViewPerF)
{
Stack<File> possPrint = new Stack<File>();
Integer[] poss = new Integer[4]();
int u,size;
for(File f:files)
{
size = f2S(f).length();
u = Math.min(maxViewsPerF,size);
for(int i=0; i<u;i++)
{
// Do something --- bloated, and soon out of control
// wants more succintly
}
}
return possPrint;
}
for (List<Object> lo : list) {
for (Object o : lo) {
// etc etc
}
}
I don't think there's a simpler solution.
If you can get the data into an Iterable<Iterable<T>>, then you can get from that to a flattened Iterable<T> using Guava's Iterables.concat method. If what you have is really an Iterable<S>, with some way to get from an S to an Iterable<T>, well, then you have to first use Iterables.transform to view that as the Iterable<Iterable<T>> needed by concat.
All this will look a lot nicer if and when Java has something resembling closures, but at least today it's possible.
http://guava-libraries.googlecode.com
With Java 8, you can say
Collection bunchOfItems = ...;
bunchOfItems.stream().flatMap(k::getItems).forEach(i -> /* operate on i */);
or
Item[] bunchOfItems = ...;
Stream.of(bunchOfItems).flatMap(k::getItems).forEach(i -> /* operate on i */);
depending upon whether you have a Collection or an Array.
Have about half a year patience until JDK7 is final which will include Closures. This provides simliar syntax and the same possibilities as LINQ which was demonstrated in the answer you're talking about.
I have my own version. Waiting desperately for Closures in Java :
public static <T, E> Iterable<T> transformMany(Iterable<E> iterable, Func<E, Iterable<T>> f) {
if (null == iterable)
throw new IllegalArgumentException("null iterable");
if (null == f)
throw new IllegalArgumentException("null f");
return new TransformManyIterable<E, T>(iterable, f);
}
public interface Func<E, T> {
T execute(E e);
}
public class TransformManyIterable<TOriginal, TResult> implements Iterable<TResult> {
private Iterable<TOriginal> iterable;
private Func<TOriginal, Iterable<TResult>> func;
public TransformManyIterable(Iterable<TOriginal> iterable,
Func<TOriginal, Iterable<TResult>> func) {
super();
this.iterable = iterable;
this.func = func;
}
class TransformIterator implements Iterator<TResult> {
private Iterator<TOriginal> iterator;
private Iterator<TResult> currentIterator;
public TransformIterator() {
iterator = iterable.iterator();
}
#Override
public boolean hasNext() {
if (currentIterator != null && currentIterator.hasNext())
return true;
else {
while (iterator.hasNext()) {
Iterable<TResult> iterable = func.execute(iterator.next());
if (iterable == null)
continue;
currentIterator = iterable.iterator();
if (currentIterator.hasNext())
return true;
}
}
return false;
}
#Override
public TResult next() {
if (currentIterator != null && currentIterator.hasNext())
return currentIterator.next();
else {
while (iterator.hasNext()) {
Iterable<TResult> iterable = func.execute(iterator.next());
if (iterable == null)
continue;
currentIterator = iterable.iterator();
if (currentIterator.hasNext())
return currentIterator.next();
}
}
throw new NoSuchElementException();
}
#Override
public void remove() {
throw new UnsupportedOperationException();
}
}
#Override
public Iterator<TResult> iterator() {
return new TransformIterator();
}
}
Usage:
Iterable<SomeType> result = transformMany(input, new Func<InputType, Iterable<SomeType>>() {
#Override
public Iterable<SomeType> execute(InputType e) {
return new ArrayList<SomeType>();
}
});
The SelectMany method is part of LINQ which is .Net-specific. This question asks about a LINQ equilvalent for java. Unfortunately, it doesn't look like there is a direct equivalent.