Is this forbidden in Java Generics? - java

class Collator<S extends Stream<E extends Comparable<E>>> {
S s;
E e;
public <S> Collator(List<S> streams){
s = streams.get(0);
e = s.read();
}
public <E> E next(){
return e;
}
}
interface Stream<E extends Comparable<E>>{
public E read();
}
class Record implements Comparable<Record>{
public Integer time;
public int compareTo(Record r){
return this.time.compareTo(r.time);
}
}
Especially 1st line:
class Collator<S extends Stream<E extends Comparable<E>>>
I expect to say:
Define a collator that works on Streams of Entries where each Entry implements comparable.

you miss-qualified the generic parameters
class Collator<S extends Stream<E>,E extends Comparable<E>> {
S s;
E e;
public Collator(List<S> streams){
s = streams.get(0);
e = s.read();
}
public E next(){
return e;
}
}
interface Stream<E extends Comparable<E>>{
public E read();
}
class Record implements Comparable<Record>{
public Integer time;
public int compareTo(Record r){
return this.time.compareTo(r.time);
}
}
this compiles
in particular the line class Collator<S extends Stream<E>,E extends Comparable<E>> it means a Collator that works on a S that is a Stream of E and E implement Comparable

Some glass ball guessing, since you don't show your error message:
Your constructor and method are declaring new type parameters <E> and <S> which are shadowing the type parameters of your class. Remove them.
Then, E should be a type parameter of your class, too.
class Collator<E extends Comparable<E>, S extends Stream<E>> {
S s;
E e;
public Collator(List<S> streams){
s = streams.get(0);
e = s.read();
}
public E next(){
return e;
}
}
interface Stream<E extends Comparable<E>>{
public E read();
}
class Record implements Comparable<Record>{
public Integer time;
public int compareTo(Record r){
return this.time.compareTo(r.time);
}
}

The problem is E extends Comparable
Define a collator that works on Streams of Entries where each Entry implements comparable of a given type:
public class Collator<T,E extends Comparable<T>, S extends Stream<E>>

Related

ArrayList does not satisfy generic serializable list type

Given the following java code:
public static <I extends Serializable, L extends List<I> & Serializable> L getList() {
return new ArrayList<I>(); // <-- Compile error
}
Given that ArrayList do extend both Serializable and List, why does it produce a compile error?
Incompatible types. Found: 'java.util.ArrayList<I>', required: 'L'
I came up with this solution:
public interface SerializableList<T> extends List<T>, Serializable {
}
public class SerializableArrayList<T> extends ArrayList<T> implements SerializableList<T> {
public SerializableArrayList(int initialCapacity) {
super(initialCapacity);
}
public SerializableArrayList() {
}
public SerializableArrayList(Collection<? extends T> c) {
super(c);
}
}
Then whenever I need a Serializable List type, I can use the SerializableList interface and its implementation SerializableArrayList

Java Bound mismatch error but I extended Comparable interface

I am trying to implement a binary tree which has heaps as nodes. But I couldn't figure out why this error shows up.
First, these are the classes:
BinaryTree:
public class MyBinarySearchTree<E extends Comparable<E>> implements Serializable{...}
Heap:
public class MyHeap<E extends Comparable<E>> implements Comparable<E>{...}
ValueOccurance:
public class ValueOccurance<E extends Comparable<E>> implements Comparable<E> {
private E data;
private int occur;
#Override
public int compareTo(E o) {
return data.compareTo(o);
}
}
So , here is the problem: In main I can't create x and y.
MyHeap<ValueOccurance<Integer>> x = new MyHeap<>();
MyBinarySearchTree<ValueOccurance<Integer>> y = new MyBinarySearchTree<>();
Can you please tell me where is my fault and a little explanation too?
Regards.
MyHeap and ValueOccurence need to be comparable to instances of themselves, not instances of E.
Note the differences between the following and your code (highlighted below):
public static class MyBinarySearchTree<E extends Comparable<E>> implements Serializable{ };
public static class MyHeap<E extends Comparable<E>> implements Comparable<MyHeap<E>>{
^^^^^^^^^
public int compareTo(MyHeap<E> other) {
return 0;
}
}
public class ValueOccurance<E extends Comparable<E>> implements Comparable<ValueOccurance<E>> {
^^^^^^^^^^^^^^^^^
private E data;
private int occur;
#Override
public int compareTo(ValueOccurance<E> o) {
^^^^^^^^^^^^^^^^^^^
return data.compareTo(o.data);
^^^^^^
}
}
public static void main(String[] args) throws IOException
{
MyHeap<ValueOccurance<Integer>> x = new MyHeap<>();
MyBinarySearchTree<ValueOccurance<Integer>> y = new MyBinarySearchTree<>();
}
ValueOccurance<E> is Comparable<E>, not Comparable<ValueOcurrence<E>>. i.e. it cannot compare instances of itself.

Is there a way to use a generic argument's own generic argument in Java?

I have this interface, with two generic parameters, and a Descriptor<T> class:
public interface DescriptorFinder<D extends Descriptor<T>, T> {
D find(Class<? extends T> describedClass);
}
public abstract class Descriptor<T> {
private final Class<? extends T> describedClass;
public Descriptor(Class<? extends T> describedClass) {
this.describedClass = describedClass;
}
public Class<? extends T> getDescribedClass() {
return describedClass;
}
}
Using those foundations I can create an NumberDescriptor to describe a number:
public class NumberDescriptor extends Descriptor<Number> {
private boolean handlesDecimalPart;
public NumberDescriptor(Class<? extends Number> describedClass) {
super(describedClass);
}
public boolean handlesDecimalPart() {
return handlesDecimalPart;
}
public void setHandlesDecimalPart(boolean handlesDecimalPart) {
this.handlesDecimalPart = handlesDecimalPart;
}
}
And then have a DescriptorFinder for it:
public class NumberDescriptorFinder implements DescriptorFinder<NumberDescriptor, Number> {
#Override
public NumberDescriptor find(Class<? extends Number> describedClass) {
NumberDescriptor descriptor = new NumberDescriptor(describedClass);
if (describedClass == Double.class || describedClass == Float.class) {
descriptor.setHandlesDecimalPart(true);
}
return descriptor;
}
}
Well, that DescriptorFinder<NumberDescriptor, Number> is pretty weird to use, I would like to remove the second generic parameter and reduce it to DescriptorFinder<NumberDescriptor>. So I tried something like this:
public interface DescriptorFinder<D extends Descriptor<?>> {
D find(Class<? extends T> describedClass); // How to get T?
}
But I couldn't find a way to get D's T argument, for example, if I had D as Descriptor<Number>, I want to get Number so I can have Class<? extends Number>.

Implementing compareTo() method in a Generic class

I have a project I'm working on and this is what I have started with:
public class Pair<T extends Comparable, E extends Comparable> implements Comparable{
private E e;
private T t;
public int compareTo(Pair arg0) {
// TODO Auto-generated method stub
return 0;
}
}
I need to use this class to sort ordered pairs in ascending order. If the first ones are equal, then it should sort by the send point.
Could you guys please help me get a start on this?
In your class definition, your T and E generics lack the comparison against themselves. This also happens for your Pair class. The definition of the class should be:
public class Pair<T extends Comparable<T>, E extends Comparable<E>> implements Comparable<Pair<T, E>> {
}
Now you can define how to compare the pair. Here's an example:
public class Pair<T extends Comparable<T>, E extends Comparable<E>> implements Comparable<Pair<T, E>> {
private E e;
private T t;
public int compareTo(Pair<T, E> pair) {
int result = t.compareTo(pair.t);
return (result == 0) ? e.compareTo(pair.e) : result;
}
}

Error with collections.sort (Bound mismatch)

I have to make an especific sort in a object. I read a lot of tutorials and utilized the class Comparable.
My Class:
public class PaAcao implements Serializable, IAcao, Comparable<PaAcao> /* Ordenar */ {
#Override
public int compareTo(PaAcao acaoCompara) {
//return this.aresta - outro.aresta;
int i = 0;
String[] array1 = this.cnrAcao.split(".");
String[] array2 = acaoCompara.cnrAcao.split(".");
for(String c : array1){
if (array2.length > i){
if (Integer.parseInt(c) > Integer.parseInt(array2[i]))
{
return 1;
}
if (Integer.parseInt(c) < Integer.parseInt(array2[i]))
{
return -1;
}
}
i++;
}
return -1;
}
For this Class i have an interface:
package br.com.agraria.qualidade.model.entity;
public interface IAcao{
public abstract String getCnmUsuarResp();
public abstract Usuario getusuarResp();
public abstract void setusuarResp(Usuario usuarResp);
public abstract PaStatusAcao getIcdStatus();
public abstract String getCnrAcao();
public abstract Boolean getLpublico();
}
And i get the error below:
public class PaAcaoServiceImpl extends HibernateGenericServiceImpl<PaAcao> implements PaAcaoService {
#Override
public List<? extends IAcao> processarAcoes(List<? extends IAcao> acoesProcessar) {
SessaoPrivilegiosGerente sessaoPrivilegiosGerente = sessaoService.getSessaoPrivilegiosGerente();
List<IAcao> macroRemover = new ArrayList<IAcao>();
Collections.sort(acoesProcessar);
...
}
}
The problem is in the line Collections.sort(acoesProcessar);
I get the message:
Bound mismatch: The generic method sort(List<T>) of type Collections
is not applicable for the arguments (List<capture#14-of ? extends IAcao>). The inferred type capture#14-of ? extends IAcao is not a
valid substitute for the bounded parameter <T extends Comparable<? super T>>
The resolution was (Thanks Deactivator2 for helping me with this):
Extends Comparable on the interface IAcao:
package br.com.agraria.qualidade.model.entity;
public interface IAcao extends Comparable<IAcao>{
public abstract String getCnmUsuarResp();
public abstract Usuario getusuarResp();
public abstract void setusuarResp(Usuario usuarResp);
public abstract PaStatusAcao getIcdStatus();
public abstract String getCnrAcao();
public abstract Boolean getLpublico();
}
And in my class PaAcao, I remove the implements of Comparable because it'll be duplicated and change the type os compareTo to IAcao and not PaAcao:
public class PaAcao implements Serializable, IAcao /* Ordenar */ {
#Override
public int compareTo(IAcao acaoCompara) {
//return this.aresta - outro.aresta;
int i = 0;
String[] array1 = this.cnrAcao.split(".");
String[] array2 = acaoCompara.cnrAcao.split(".");
for(String c : array1){
if (array2.length > i){
if (Integer.parseInt(c) > Integer.parseInt(array2[i]))
{
return 1;
}
if (Integer.parseInt(c) < Integer.parseInt(array2[i]))
{
return -1;
}
}
i++;
}
return -1;
}

Categories