I have a little problem connected with interfaces, classes and generics in Java.
First of all, I have an interface which is meant to represent the idea of Priority Queue:
public interface PriorityQueue<T> {
// insert object o of class T into priority queue with appropriate element
public void insert(T o);
// remove an element with the highest priority
public T remove();
}
As we know we can implement a priority queue by heap or list. Here's my class of heap:
public class Heap <T implements Comparable> implements PriorityQueue<T>
I want to have an ArrayList which will have elements of type T. I want my heap to be prepared for all types which are comparable (classes which implement interface Comparable). T could be a String, Double, Integer or just my own type (then I know that I have to write a compareTo method...).
How can I do that? I have a lot of errors in my NetBeans...
Instead of
public class Heap <T implements Comparable> implements PriorityQueue<T>
write:
public class Heap<T extends Comparable> implements PriorityQueue<T>
It works (Of course implement inherited methods). See here for more information.
You're pretty close. Try: public class Heap<T extends Comparable>...
This is one of the many weird and, IMO, unfortunate things about Java Generics. You never use the implements keyword inside of the < >, only extends. Here's a JUnit test showing it in action:
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import static org.junit.Assert.*;
public class CalcIEProjectTreeTest {
public static interface Priority<T> {
public void insert(T item);
public T remove();
}
public static class Heap<T extends Comparable> implements Priority<T> {
private List<T> storage = new ArrayList<T>();
public void insert(T item){
storage.add(item);
}
public T remove() {
return storage.remove(0);
}
}
#Test
public void testStuff() throws Exception {
Heap h = new Heap<String>();
h.insert("testString");
assertEquals("testString", h.remove());
}
}
never mind the bogus formatting.
Related
I have several classes . Generic order makes its collection from the things in product class which are just some objects like fruit and computerParts. Computer order extends GenericOrder where it makes its own collection with some objects from Product class and so Computer order has its own collection called computerOrder. Now there is a third collection called orderProcessor for which i think the use of Queues is good with its first in first out ways.
what is the best way to add genericOrder and computerOrder to orderProcessor ? i am getting an error while adding computerOrder to orderProcessor. Is there a better way or i am on the right track ?
import java.util.*;
public class GenericOrder <T extends Product> {
List<Product> genericOrder;
public void compPrice(float comPrice){
genericOrder.add(new ComputerPart(comPrice));
Product a = genericOrder.get(0);
}
}
import java.util.*;
public class ComputerOrder extends GenericOrder<Product> {
ArrayList<Product> computerOrder;
public void addDrive (String dType, int dSpeed, float price) {
computerOrder.add(new Drive(dType ,dSpeed ,price));
}
import java.util.ArrayList;
public class OrderProcessor extends GenericOrder<Product>{
ArrayList<Product> orderProcessor;
protected int queSize=0;
protected int front=0, rear;
public void accept()// this method accepts a GenericOrder or any of its subclass objects and stores it in any internal collection of OrderProcessor.
{
orderProcessor.addAll(genericOrder);
orderProcessor.addAll(genericOrder.computerOrder);
orderProcessor.addAll(partyTrayOrder);
}
Maybe you are looking something like this:
public class Order<T extends Product> {
List<T> products;
public void add(T productItem) {
}
}
public class ComputerOrder extends Order<ComputerPart> {
//I think, you don't need collection of ComputerParts here, cause you have it in the parent class
//Maybe you either don't need method like addDrive — you can use add(new Drive()) instead
}
//It's better to prefer composition over inheritance
public class OrderProcessor {
List<Product> products;
public void accept(List<? extends Product> products) {
this.products.addAll(products);
}
}
You can use OrderProcessor in this manner:
OrderProcessor orderProcessor = new OrderProcessor();
orderProcessor.accept(new ArrayList<Product>());
orderProcessor.accept(new LinkedList<ComputerPart>());
orderProcessor.accept(new CopyOnWriteArrayList<SomethingExtendingProduct>());
I'm working on a project for class that involves generics.
public interface Keyable <T> {public String getKey();}
public interface DataElement extends Comparable<Keyable<DataElement>>, Keyable<DataElement>, Serializable {...}
public class Course implements DataElement {...}
public interface SearchTree<K extends Comparable<Keyable<K>> & Keyable<K>> extends Serializable {...}
public class MySearchTree implements SearchTree<Course> {
...
private class Node {
public Course data;
public Node left;
public Node right;
...
}
}
When trying to use the Course class within the declaration of MySearchTree, I receive a type argument error stating that "Course is not within the bounds of type-variable K". I spent a good amount of time trying to figure out what attributes Course might be lacking to make it not fit the bill, but came up empty.
Any ideas?
In MySearchTree the K of the base type is Course. So K must "extend" Comparable<Keyable<Course>> & Keyable<Course>. But it doesn't, it extends Comparable<Keyable<DataElement>> & Keyable<DataElement>.
I guess DataElement should be generified in a similar manner to Comparable or Enum.
public interface Keyable <T> {public String getKey();}
public interface DataElement<THIS extends DataElement<THIS>> extends Comparable<Keyable<THIS>>, Keyable<THIS>, Serializable {...}
public class Course implements DataElement<Course> {...}
public interface SearchTree<K extends Comparable<Keyable<K>> & Keyable<K>> extends Serializable {...}
public class MySearchTree implements SearchTree<Course> {
In addition to implementing a Bag & List for an assignment, the next step is to create an ordered version. A requirement is to specify the parametric interface OrderedCollection with the correct type parameters and constraints. My problem is with implementing it.
An interface Collection <E> exists and is defined as
public interface Collection<E> extends Iterable<E>{
public void add(E e);
public void remove(E e);
public boolean contains(Object e);
public void clear();
public int size();
public boolean isEmpty();
public Object[] toArray();
}
It is implemented by the classes
public class UnorderedList<E> implements Collection<E>
public class UnorderedBag<E> extends UnorderedList<E> implements Collection<E>
I have the structures working, and am now trying to implement the sorted version. To do this and satisfy part of the requirements, I created OrderedCollection as
public interface OrderedCollection <E extends Comparable<E>> {
public int compareTo(E e);
}
because it is extending the methods already defined in Collection, and the only new functionality required is a compareTo() method.
However, when I try to implement OrderedList by the declaration
public class OrderedList<E> extends UnorderedList<E> implements OrderedCollection<E>
I get an error stating that
Bound mismatch: The type E is not a valid substitute for the bounded parameter <E
extends Comparable<E>> of the type OrderedCollection<E>
As I understand the error message, I need to specify a parameter type that is a valid substitute for the one given in the interface declaration. However, I've tried
OrderedCollection<E extends Comparable<E>>
as the implements declarer, but then I get a warning that a syntax error exists on extends.
How do I satisfy the requirements here?
In your declaration of the OrderedList class, the generic type of OrderedList needs to match the restriction that OrderedCollection expects.
public class OrderedList<E extends Comparable<E>>
extends UnorderedList<E>
implements OrderedCollection<E>
Suppose I have the following interface:
public interface Interface<T extends Number>{
public Vector<Interface<T>> getVector();
}
and the following class implementing that interface:
public abstract class C<T extends Number> implements Interface<T>{
private Vector<C<T>> vector;
public Vector<Interface<T>> getVector(){ //errror
return this.vector;
}
}
Why is not legal returning a Vector<C<T>> meanwhile is legal ( obviously) returning a Vector<Interface<T>>. C is actually implementing Interface, so it should be possible, right? What am I missing?
EDIT:
why this work for non generics interface? Is this actually a generic related problem?
public interface Interface{
public Interface getVector();
}
public abstract class C implements Interface {
private C;
public Interface getVector(){ //errror
return this.c;
}
}
Because the Vector is explicitly made up of Interface<T>, not things that extend Interface<T>, I believe this would work if you changed the definition to
public Vector<? extends Interface<T>> getVector();
The problem is that for some V implements T or V extends T that Foo<V> is not a supertype of Foo<T>. The compiler does not test inheritance on the generic arguments unless you explicitly indicate that extension point.
Using Vector<? extends Interface<T>> means "allow any class that implements or extends Interface<T>, whereas Vector<Interface<T>> means a vector consisting only of Interface<T> items.
Perhaps it's more concrete to consider that List<Integer> is not an acceptable replacement for List<Number> despite Integer extending Number for precisely the same reason.
update:
I tested this and the following compiles without any errors or warnings
interface Interface<T extends Number>{
public Vector<? extends Interface<T>> getVector();
}
abstract class C<T extends Number> implements Interface<T>{
private Vector<C<T>> vector;
public Vector<? extends Interface<T>> getVector(){
return this.vector;
}
}
It's the way generics work. They are not "covariant": if you have class AClass and its subclass SubAClass, Vector<SubAClass> is not a subclass of Vector<A>. (Note however that SubAClass[] is a subclass of AClass[].)
EDIT:
The seemingly obvious:
public ArrayList<Object> blah() {
return new ArrayList<String>();
}
won't compile because ArrayList<String> is not a subclass ArrayList<Object>. So in your case you can't return a Vector<C<T>> instance for a Vector<Interface<T>>.
I tried to create an interface ISortableStack using <E extends comparable <E>> but I can't move forward. What does the following do?
<E extends Comparable<E>>
I've tried this, but it doesn't help.
<E extends Comparable<E>> means that E must be a type that knows how to compare to itself, hence, the recursive type definition.
public class Comparables {
static class User implements Comparable<User> {
#Override
public int compareTo(User user) {
return 0;
}
}
/**
* This class cannot be used with Collections.sort because an
* UncomparableUser is not comparable with itself. However, notice
* that you get no compiler error just for implementing
* Comparable<String>.
*/
static class UncomparableUser implements Comparable<String> {
#Override
public int compareTo(String user) {
return 0;
}
}
public static void main(String[] args) {
List<User> users = Arrays.asList(new User());
// Using this would cause a compiler error
// List<UncomparableUser> users = Arrays.asList(new UncomparableUser());
Collections.sort(users);
}
}
If you're asking what does this mean:
<E extends Comparable<E>>
It means that the class 'E' passed in must implement the Comparable interface.
The < and > characters are part of the "generic" syntax. The standard library is choke full of "generic" interfaces; take a look at the Set interface for an example.