Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a Java interface that extends Iterable with two different generic types?

Ideally, it would look like this (the context doesn't matter):

public interface myInterface extends Iterable<Point>, Iterable<Segment> { ... }

But this is not allowed in Java. How can I achieve this behaviour?

like image 698
user2460978 Avatar asked Jun 06 '13 18:06

user2460978


4 Answers

Unfortunately you cannot. In Java you cannot have two methods with following signatures:

Iterator<Point> iterator();
Iterator<Segment> iterator();

in one class or interface.

like image 156
Grzegorz Żur Avatar answered Oct 17 '22 18:10

Grzegorz Żur


As other said before, this is impossible. Better use delegation instead of multiple implementation like this:

public interface MyInterface {
  Iterable<Point> points();
  Iterable<Segment> segments();
}

So you can iterate using for:

MyInterface my = ...;
for (Point p : my.points()) {
  ...
}
for (Segment s : my.segments()) {
  ...
}
like image 28
Arne Burmeister Avatar answered Oct 17 '22 20:10

Arne Burmeister


You cannot. Due to type erasure, in the bytecode, and therefore at run time, Iterable<Whatever> becomes Iterable.

So, at run time, your class' prototype would be:

public interface myInterface extends Iterable, Iterable { ... }

Considering that, how do you determine what class was meant to be iterated over?

like image 9
fge Avatar answered Oct 17 '22 18:10

fge


As a possible workaround, you could create interfaces for the iterations you want.

public interface SegmentIterable{
    public Iterator<Segment> segmentIterator();
}

public interface PointIterable{
    public Iterator<Point> pointIterator();
}

It's not ideal, but would be passable as long as you had a limited number of things you wanted to iterate over.

like image 5
greedybuddha Avatar answered Oct 17 '22 19:10

greedybuddha