Implementing the Java Iterable<E> interface - java

public class C1 implements Iterable {
private LinkedList list;
public static class NC1 {
...
}
...
x public Iterator iterator() {
return list.iterator();
}
}
but eclipse whines (at the x-ed line):
- The return type is incompatible with Iterable<NC1>.iterator()
- implements java.lang.Iterable<NC1>.iterator
I don't understand where the mistake is. Can someone help?

You need to change NC1 to C1.NC1. The following compiles:
import java.util.*;
public class C1 implements Iterable<C1.NC1> {
private LinkedList<NC1> list;
public static class NC1 {
}
public Iterator<C1.NC1> iterator() {
return list.iterator();
}
}
Alternatively, you could import static yourpackage.C1.NC1.

this code compiles just fine:
public class C1 implements Iterable<NC1> {
public static class NC1 {
}
private LinkedList<NC1> list;
public Iterator<NC1> iterator() {
return this.list.iterator();
}
}
, so there must be an error in a part you omitted
EDIT:
after seeing the other answer:
yes, I have auto-imports switched on, so you need this line:
import com.yourpackage.C1.NC1;

Related

How to implement an interface for two classes with an iterator

I'm trying out Interfaces in java and I want to implement a common interface for a really simple stack, with pop() and push() methods and an iterator.
The problem is that I don't know how to specify the iterator in the interface. No matter which way I try, I get
Main.java:32: error: for-each not applicable to expression type
for (Integer i : ss)
^
required: array or java.lang.Iterable
found: Stack<Integer>
The code is as follows:
interface Stack<T> {
boolean push(T t);
boolean pop();
//Iterator<T> iterator(); // How to indicate it needs, and will have, an iterator?
}
public class DynamicStack<T> implements Iterable<T>, Stack<T>
{
// implementation-specific variables go here
public DynamicStack() {
//...
}
public boolean push(T t) {
//...
}
public boolean pop() {
//...
}
private class StackIterator implements Iterator<T> {
DynamicStack<T> stk;
//...
// Iterator constructor
private StackIterator(DynamicStack<T> stk)
{
//...
}
public boolean hasNext()
{
//...
}
public T next() throws NoSuchElementException
{
//...
}
public void remove() throws UnsupportedOperationException
{
throw new UnsupportedOperationException(); // I chose not to implement this one
}
}
// Iterator method
public Iterator<T> iterator()
{
return new StackIterator(this);
}
}
public class StaticStack<T> implements Iterable<T>, Stack<T>
{
// implementation-specific variables go here
public StaticStack()
{
//...
}
public boolean push(T t)
{
//...
}
public boolean pop()
{
//...
}
private class StackIterator implements Iterator<T>
{
StaticStack<T> stk;
//...
private StackIterator(StaticStack<T> stk)
{
//...
}
public boolean hasNext()
{
//...
}
public T next() throws NoSuchElementException
{
//...
}
public void remove() throws UnsupportedOperationException
{
//...
}
}
// Iterator method
public Iterator<T> iterator()
{
return new StackIterator(this);
}
}
Main simply does this, after creating a few stacks of each type and adding a few elements:
public static void showStuff(Stack<Integer> ss)
{
for (Integer i : ss)
System.out.print(i+" ");
System.out.println();
}
In your test class, you are operating against Stack interface, so that is the one that needs to conform to Iterable. In this case it doesn't help if StaticStack or DynamicStack implement it if Stack does not.
To get Stack to be able to be used as Iterable just change your Stack to extend Iterable:
public interface Stack<T> extends Iterable<T> {
boolean push(T t);
boolean pop();
}
and
public class StaticStack<T> implements Stack<T>
and the code runs just fine:
public class Tester {
public static void main(String args[]) {
Stack<Integer> ss = new StaticStack<>();
for (Integer i : ss)
System.out.print(i+" ");
System.out.println();
}
}
You need you class to implement Iterable<T>, which has the iterator() method, which returns Iterator<T>.

I don't understand why my generic type declaration doesn't match

Here are the classes declarations:
public interface IPoint<N extends Number> {
...
}
public abstract class PointP<N extends Number> implements IPoint<N> {
...
}
public class Pointf extends PointP<Float> {
...
}
public interface ISegment<T extends Number, P extends IPoint<T>> {
...
}
public abstract class SegmentP<N extends Number, P extends IPoint<N>> implements ISegment<N, P> {
...
}
public class Segmentf extends SegmentP<Float, Pointf> {
...
}
public abstract class LinesPIterator<N extends Number, S extends ISegment<N, IPoint<N>>> implements Iterable<S>, Iterator<S> {
...
}
public class LinesfIterator extends LinesPIterator<Float, Segmentf> {
...
}
The compiler refuses the Segmentf type in the generic declaration of the LinesfIterator class with the error message:
Bound mismatch: The type Segmentf is not a valid substitute for the bounded parameter <S extends ISegment<N,IPoint<N>>> of the type LinesPIterator<N,S>
However for me everything seems correct. The declaration of the LinesfIterator class seems to me to have the same hierarchical schema as the Segmentf class which compiles without problem.
Is there a solution to this way of doing things?
As already said, your hierarchy seems to be unnecessarily complex and shall be simplified. For example, I see no meaning in Pointf -> PointP -> IPoint the hierarchy.
If you want to fix your issue, you have to allow a subtype ? extends IPoint<N> in the LinesPIterator class, so:
public abstract class LinesPIterator<N extends Number, S extends ISegment<N, ? extends IPoint<N>>>
implements Iterable<S>, Iterator<S>
{
// ...
}
Moreover, there would be better to implement only Iterable as long as it provides an Iterator and you might end up with duplicated implementation.
public static class LinesfIterator extends LinesPIterator<Segmentf, Pointf, Float> {
#Override
public Iterator<Segmentf> iterator() {
return new Iterator<Segmentf>() {
#Override
public boolean hasNext() { /* TO DO */ }
#Override
public Segmentf next() { /* TO DO */ }
};
}
}
This remark on the use of an anonymous class rather than a direct use really caught my attention because intuitively, when I can avoid going through an anonymous class I do. On the one hand because it is an additional instantiation and on the other hand because it is more difficult to identify at debug (when they are several in the same class).
And I can't see the reasons why I should prefer the use of an anonymous class for this case.
Maybe with my classes as an example the explanation will be easier.
for(Segmentf segment : new LinesfIterator(cube.getPoints(), cube.getIndices())) {
System.out.println(segment);
}
public abstract class LinesPIterator<N extends Number, S extends ISegment<N, ? extends IPoint<N>>> implements Iterable<S>, Iterator<S> {
private N[][] points;
private int[] indices;
private int count;
public LinesPIterator(N[][] points, int[] indices) {
super();
this.points = points;
this.indices = indices;
}
protected abstract S instanciateIteration(final N[] pointDeb, final N[] pointFin);
#Override
public Iterator<S> iterator() {
return this;
}
#Override
public boolean hasNext() {
return count < (indices.length - 1);
}
#Override
public S next() {
return instanciateIteration(points[indices[count++]], points[indices[count++]]);
}
}
public class LinesfIterator extends LinesPIterator<Float, Segmentf> {
public LinesfIterator(Float[][] points, int[] indices) {
super(points, indices);
}
#Override
protected Segmentf instanciateIteration(Float[] point1, Float[] point2) {
return new Segmentf(point1, point2);
}
}

Sort a Java TreeSet using Comparator

i am trying to sort a TreeSet of objects ("Etudiant") using Comparator interface . This the Comparator implementation:
import java.util.Comparator;
public class TriParNom implements Comparator<Etudiant>{
public int compare(Etudiant o1, Etudiant o2) {
return o1.getNom().compareTo(o2.getNom());
}
}
here is the the TreeSet declaration and the call of the comparator in the main :
TreeSet<Etudiant> University= new TreeSet<Etudiant>(new TriParNom());
the error i get in the main class when i declare the TreeSet and call the comparator ,is : no suitable constructor found for TreeSet(TriParNom) .
Any solutions please ? thanks in advance .
I tried a very simple implementation based on the information you provided, and I give you my results:
The Etudiant class is a very simple pojo
public class Etudiant {
private String nom;
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
} }
The TriParNom class is the plain Comparator you described:
import java.util.Comparator;
public class TriParNom implements Comparator<Etudiant> {
#Override
public int compare(Etudiant o1, Etudiant o2) {
return o1.getNom().compareTo(o2.getNom());
}
}
And here is a simple class with an entry point and a sample method to exercise the newly created treeset
import java.util.TreeSet;
public class Main {
public static void main(String[] args) {
TreeSet<Etudiant> u = new TreeSet<>(new TriParNom());
System.out.printf("size? %d%n", u.size());
}
}
Execution results follow:
Apparently, there are no compilation errors either.
If your code matches to the snippet given below, then it should run fine without problems. The moment you remove the part implements Comparator<Etudiant> from class TriParNom, you will get the error indicating suitable constructor not found. Now, one another silly way it could happen if you haven't recompiled your classes after you implemented the comparator to your TriParNom - but that's too obvious. Have your class that contins main method(that declares Treeset) imported java.util.TreeSet ?
import java.util.Comparator;
import java.util.TreeSet;
public class TreesetCheck {
public static void main(String[] args) {
TreeSet<Etudiant> University= new TreeSet<Etudiant>(new TriParNom());
}
}
class TriParNom implements Comparator<Etudiant>{
public int compare(Etudiant o1, Etudiant o2) {
return o1.getNom().compareTo(o2.getNom());
}
}
class Etudiant {
public String getNom() {
// TODO Auto-generated method stub
return "some";
}
}

Java generics wildcards

public interface UnivariateOperator<T> {
public TimeSeries<T> operateOn(TimeSeries<T> timeseries);
}
public class SamplingOperator<T> implements UnivariateOperator<T> {
#Override
public TimeSeries<T> sample(TimeSeries<T> timeseries) {
...
}
}
Is there a way to use wildcards so the sampling operator can work with any type? I don't really want to have to specify the type for the sampling operator...it should work with any typed timeseries.
What if you did something like this:
public class SamplingOperator<T> implements UnivariateOperator<T> {
private SamplingOperator(){
}
#Override
public TimeSeries<T> sample(TimeSeries<T> timeseries) {
...
}
public static SamplingOperator<? extends Object> getInstance() {
return new SamplingOperator<Object>();
}
}
This ensures that any instance of SamplingOperator will be able to accept any type of TimeSeries as an argument to its sample method.
There are probably better solutions out there, but this one will work.
You can't, because you need to specify the generic of UnivariateOperator. If you just want a generic method that samples TimeSeries, you will need something like
public class TimeSeriesSampler {
public static <T> TimeSeries<T> sample(TimeSeries<T> timeseries) {
...
}
}
but if you want a SamplingOperator to implements UnivariantOperator, you will need to specify the generic. If you still don't want to specify, you could use something as
public class SamplingOperator implements UnivariateOperatior<Object> {
private SamplingOperator(){
}
public <T> TimeSeries<T> sample(TimeSeries<T> timeseries) {
return null;
}
#Override
public TimeSeries<Object> operateOn(TimeSeries<Object> timeseries) {
...
}
}
but you will lose the power of the generic. Another way is
public class SamplingOperator<S> implements UnivariateOperatior<S> {
private SamplingOperator(){
}
public <T> TimeSeries<T> sample(TimeSeries<T> timeseries) {
return null;
}
#Override
public TimeSeries<S> operateOn(TimeSeries<S> timeseries) {
return timeseries;
}
}
but it "smells" bad, as the sample method gives a feeling of a class method, instead of an instance one. It's your choice what's bst to do.
implements UnivariateOperator<Object>

Java interface design

I had an interface initially as below.
public interface testMe {
public Set<String> doSomething();
}
public class A implements testMe {
public Set<String> doSomething() {
return // Set<String>
}
}
I had similar classes implementing testMe. Now I have to add one more class which returns Set<Some Object>
public class X implements testMe() {
public Set<Some OBject> doSomething() {
}
}
How could i add this method in the interface without breaking existing classes?
You can use
public interface testMe {
public Set<?> doSomething();
}
Or
public interface testMe {
public Set<? extends CommonSuperclass> doSomething();
}
You can't for two reasons.
A class or interface can't have two or more methods that have the same number and type of parameters with the same name but differing return types; and
Because of type erasure, all Set<...> instances are, at runtime, simply Set, so they would have the exact same return type anyway.
You will need to name the second something different.
The more complicated answer is that you can make the parameter type extensible:
public interface TestMe<T extends Serializable> {
Set<T> doSomething();
}
public class A implements TestMe<String> {
#Override
public Set<String> doSomething() { ... }
}
public class X implements TestMe<ASerializableObject> {
#Override
public Set<ASerializableObject> doSomething() { ... }
}
I don't believe you can, because type erasure will ruin the effect you have in mind.
You can parameterize the interface:
import java.util.Set;
public interface ISomething<T>
{
Set<T> doSomething(T [] data);
}
And the implementation:
import java.util.HashSet;
import java.util.Set;
public class Something<T> implements ISomething<T>
{
public static void main(String[] args)
{
Something<String> something = new Something<String>();
Set<String> set = something.doSomething(args);
System.out.println(set);
}
public Set<T> doSomething(T [] data)
{
Set<T> foo = new HashSet<T>();
for (T x : data)
{
foo.add(x);
}
return foo;
}
}
I'm not sure this accomplishes what you have in mind, though.

Categories

Resources