Java Generic Misbound - java

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Collections;
public interface Comparable<T> {
int compareTo(T other);
}
public class Joueur implements Comparable<Joueur> {
private int points;
private int idJoueur;
public Joueur(int aIdJoueur, int aPoints)
{
points= aPoints;
idJoueur = aIdJoueur;
}
public Joueur(int aIdJoueur, int aPoints)
{
points= aPoints;
idJoueur = aIdJoueur;
}
public int getIdJoueur()
{
return idJoueur;
}
public int compareTo(Joueur autre) {
// TODO Auto-generated method stub
if (points < autre.points) return -1;
if (points > autre.points) return 1;
return 0;
}
public class CollectionJoueur {
ArrayList<Joueur> j = new ArrayList<Joueur>();
public CollectionJoueur(int aIdJoueur, int aPoints)
{
Joueur ajouterJ = new Joueur(aIdJoueur, aPoints);
ajouter(ajouterJ);
}
public void ajouter(Joueur joueur)
{
j.add(joueur);
}
public iterateurJoueur creerIterateur()
{
Collections.sort(j);
Iterator<Joueur> itrJoueur = j.iterator();
while(itrJoueur.hasNext())
{
}
}
}
So here's my problem, I have been trying to do comparable sort, but in the collections sort it gave me an error of generic misbound. I have a class collection to put the player into the arraylist then i have to sort them out in ascending order.

You should implement java.lang.Comparable interface, not your own Comparable interface.
http://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html

You'll notice that Collections.sort(..) is defined as
public static <T extends Comparable<? super T>> void sort(List<T> list) {
In other words, it expects a type that is a sub type of java.lang.Comparable. Your class is not a sub type of java.lang.Comparable. What you are trying to do with Collections.sort(..) is not possible.
Get rid of your Comparable type and use java.lang.Comparable.
Or write your own sorting method.

Related

Implementing a functional interface via method reference

First I got a class named after my Chinese name
public class Yxj<T> {
private T[] data;
private int size = 0;
private final Comparator<? super T> comparator;
public Yxj(Comparator<? super T> c) {
data= (T[]) new Object[16];
comparator = c;
}
public void addItem(T t){
data[size++] = t;
}
public int sort(){
return comparator.compare(data[0], data[1]);
}
public T[] getData(){
return data;
}
}
in which a Comparator resides,then I defined a Norwich keeping a field order and setter and getter of it, finally there's a method used to implement the compare(T t1,T t2) in Comparator.
public class Norwich {
private int order;
public Norwich(int o) {
order = o;
}
public int getOrder() {
return order;
}
public void setOrder(int order) {
this.order = order;
}
public int compareOrder(Norwich n) {
if (order > n.getOrder()) {
return 2;
} else if (order == n.getOrder()) {
return 0;
} else {
return -3;
}
}
}
then here comes the main method
Yxj<Norwich> norwichYxj = new Yxj<>(Norwich::compareOrder);
norwichYxj.addItem(new Norwich(9));
norwichYxj.addItem(new Norwich(1));
System.out.println(norwichYxj.sort());
so what I'm interested in is that, why does not the method compareOrder keep the same parameters as the compare in Comparator but it can still work correctly?
It is simple. You have passed through the constructor your implementation of the Comparator to be used for comparing.
Yxj<Norwich> norwichYxj = new Yxj<>(Norwich::compareOrder);
Remember Comparator is nothing else than an interface. Since it is a functional interface, it can be represented through a lambda expression or a
method reference (as you did). The way you can pass the Comparator in the full form is as follows. Note the usage of the compareOrder method:
Yxj<Norwich> norwichYxj = new Yxj<>(new Comparator<>() {
#Override
public int compare(Norwich o1, Norwich o2) {
return o1.compareOrder(o2); // usage of compareOrder
}
});
This can be shortened to a lambda expression:
Yxj<Norwich> norwichYxj = new Yxj<>((o1, o2) -> o1.compareOrder(o2));
It can be shortened again to a method reference:
Yxj<Norwich> norwichYxj = new Yxj<>(Norwich::compareOrder);
Now you can see it can be represented in this way though the method compareOrder accepts only one formal parameter. The first parameter of the Comparator#compare method is the one invoking the compareOrder method and the second parameter is the one being passed to the compareOrder method.
Learn more here: https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html
Additionally, the classes you have constructed look a bit odd. Though the other answer doesn't in fact answer your question, it can lead you to a better code: Implementing a functional interface via method reference
class Yxj
The paramter T of your class Yxj should have more restrictions if you want to compare/sort in this class with T then say T must be comparable.
If your T array grows then don't implement your own growing array but use ArrayList instead which does that for you
If you do the first you don't need the Comperator anymore
Your methode sort only sorts the first and second element so you will get problems. If the data is shorter you will get an ArrayIndexOutOfBoundsException if it is longer it won't sort the rest of elements. So with a Collection you could simple use Collections.sort(data);
public class Yxj<T extends Comparable<T>> {
private final List<T> data;
public Yxj() {
this.data = new ArrayList<>();
}
public void addItem(T t){
data.add(t);
}
public void sort(){
Collections.sort(data);
}
public List<T> getData(){
return data;
}
public void print(){
System.out.println(data);
}
}
class Norwich
If you done the above know your Norwich class must implement the Comparable interface so you can compare Norwich instances with the methode compareTo which also will be called each time you or the API ask directly or indirectly to compare to Norwich instances like for sorting ect.
public class Norwich implements Comparable<Norwich> {
private int order;
public Norwich(int o) {
this.order = o;
}
public int getOrder() {
return this.order;
}
public void setOrder(int order) {
this.order = order;
}
#Override
public int compareTo(Norwich other) {
return this.order - other.order;
}
#Override
public String toString() {
return "Norwich{" +
"order=" + order +
'}';
}
}
Main
Done? Perfect, then your main could be looks like this
public static void main(String[] args) {
Yxj<Norwich> norwichYxj = new Yxj<>();
norwichYxj.addItem(new Norwich(9));
norwichYxj.addItem(new Norwich(1));
norwichYxj.sort();
norwichYxj.print();
}

How to override compareTo Double method?

I tried to override compareTo method however I see compiler uses Java.lang.Double.compareTo method instead of my compareTo.
What is wrong here and what should I fix and change so my own compareTo method will be used?
package GenerecEx;
import java.util.ArrayList;
import java.util.Collections;
public class ArraySort implements Comparable{
double val;
static ArrayList<Double> a=new ArrayList<Double>();
public static void main(String[] args) {
a.add(2.4);
a.add(8.4);
a.add(9.4);
a.add(4.4);
a.add(6.4);
sort(a);
printList(a);
}
public static void printList(ArrayList a1)
{
System.out.println(a1.toString());
}
static public void sort(ArrayList <Double> a1)
{
for (int i=0;i<a1.size();i++){
for(int j=0;j<a1.size()-i-1;j++){
if (a1.get(j).compareTo(a1.get(j+1))>0){
double temp = a1.get(j);
a1.set(j,a1.get(j+1) );
a1.set(j+1, temp);
}
}
}
}
#Override
public int compareTo(Object element)
{
if (this.val < (Double) element)
return -1;
else return 1;
}
}
Implementing the Comparable interface allows you to override the compareTo method on the implementing class. Having implemented Comparable on the ArraySort class, your compareTo method should actually be comparing objects of type ArraySort, not generic Objects cast as Double.

java return abstract class in abstract method

I got some problem with java's interfaces and abstract classes.
I have interface
public interface IVector <T extends IVector>{
public IVector add(IVector vector);
public IVector sub(IVector vector);
public double dotProduct(IVector vector);
public IVector scalar(double scalar);
}
and abstract class like this:
public abstract class Vector implements IVector{
final ArrayList<Double> coordinates;
public Vector(ArrayList<Double> list){
coordinates = list;
}
public IVector add(Vector v){
ArrayList<Double> newCoordinates = new ArrayList<>();
if (v.coordinates.size() == this.coordinates.size()){
for (int i = 0; i < this.coordinates.size(); i++) {
newCoordinates.add(v.coordinates.get(i)+this.coordinates.get(i));
}
}
else return null;
return new IVector(newCoordinates);
}
Its just addition of vectors with n coordinates, how can i return result? I wanna use child classes (like 2dVector or 3dVector) in future?
You cannot create an abstract object directly - you need concrete class or override the required methods defined by the abstract.
Something like this may be what you are looking for.
public interface IVector<T extends IVector> {
public T add(T vector);
public T sub(T vector);
public double dotProduct(T vector);
public T scalar(double scalar);
}
public abstract class Vector<T extends Vector> implements IVector<T> {
final ArrayList<Double> coordinates;
public Vector(ArrayList<Double> list) {
coordinates = list;
}
}
public class AVector extends Vector<AVector> {
public AVector(ArrayList<Double> list) {
super(list);
}
#Override
public AVector add(AVector v) {
ArrayList<Double> newCoordinates = new ArrayList<>();
if (v.coordinates.size() == this.coordinates.size()) {
for (int i = 0; i < this.coordinates.size(); i++) {
newCoordinates.add(v.coordinates.get(i) + this.coordinates.get(i));
}
} else return null;
return new AVector(newCoordinates);
}
#Override
public AVector sub(AVector vector) {
return null;
}
#Override
public double dotProduct(AVector vector) {
return 0;
}
#Override
public AVector scalar(double scalar) {
return null;
}
}
Note that using public abstract class Vector implements IVector in your code introduces Raw Types and should be avoided. Notice I have used public abstract class Vector<T extends Vector> implements IVector<T> instead.
To achieve your aim of making the add method generic to all Vector objects as you seem to be trying to do you need some form of factory method.
Something like this may be a fair attempt at that.
public interface IVector<T extends IVector> {
public T add(T vector);
}
public interface Factory<T> {
public T makeNew (ArrayList<Double> coordinates);
}
public abstract class Vector<T extends Vector<T> & Factory<T>> implements IVector<T> {
final ArrayList<Double> coordinates;
public Vector(ArrayList<Double> list) {
coordinates = list;
}
#Override
public T add(T v) {
if (v.coordinates.size() == this.coordinates.size()) {
ArrayList<Double> newCoordinates = new ArrayList<>();
for (int i = 0; i < this.coordinates.size(); i++) {
newCoordinates.add(v.coordinates.get(i) + this.coordinates.get(i));
}
// Use the passed parameter as a factory.
return v.makeNew(coordinates);
}
return null;
}
}
public class AVector extends Vector<AVector> implements Factory<AVector> {
public AVector(ArrayList<Double> list) {
super(list);
}
#Override
public AVector makeNew(ArrayList<Double> coordinates) {
return new AVector(coordinates);
}
}
An abstract class cannot be instantiated: nor can an interface. You have to return either a subclass of Vector or an implementation of IVector.

howto handle objects of private class, got as parameter

I learn Java at university and I have to do following excercise.
(simplified example)
import java.util.*;
public class A{
private static class B{
Integer b;
private B(int b){this.b = b;}
}
private static class B_Comparable extends B implements Comparable<B_Comparable> {
private B_Comparable(int b){super(b);}
#Override
public int compareTo(B_Comparable that) {
return this.b.compareTo(that.b);
}
}
private static class C<T> implements myList<T> { // see below
private ArrayList<T> lst = new ArrayList<>();
private static C<B_Comparable> createComparable() {
C<B_Comparable> ust = new C<B_Comparable>();
for (int i =0; i < 9; i++)
ust.lst.add(new B_Comparable(i));
return ust;
}
#Override
public T fetch(int index){
return lst.get(index);
}
}
private void test(){
C<B_Comparable> ustComparable = C.createComparable();
A result = ClassD.handle(ustComparable,3,4);
}
}
//--------------------------------------------------------
public class ClassD{
public static <T, S> T handle( S ustC, int pos1, int pos2 ){
// how can I compare elems of object ustC ?
ustC.fetch(pos1).compareTo(ustC.fetch(pos2));
//how can I fetch obj at pos1 ?
return ustC.fetch(pos1);
}
}
//-----------------------------------------
public interface myList<T> {
T fetch(int index);
}
static method handle gets an object (ustC) which is private. How can I
use methods, compareTo and fetch for this object? I have tried parametrisation, but if its the right way, I don't know how to solve.
Thanks for any help.
As discussed in comments, ustC, by virtue of the way handle is called in this context is of type C, which implements the myList interface. This interface exposes the fetch method, and is visible to your handle method.
The modification you arrived at in your comments would allow you to call fetch:
//Solution
public class ClassD {
public static <S extends Comparable> S handle(myList<S> ustC, int pos1, int pos2 ){
int y = ustC.fetch(pos1).compareTo(ustC.fetch(pos2));
return ustC.fetch(pos1);
}
}

Protected fields and generics

I have an abstract class MotorFahrzeug and an extending class LKW as shown below. I wrote a generic class with type parameter <T extends MotorFahrzeug> implementing a comparator. I'm wondering why the method compare( T m1, T m2 ) in this generic class has access to the protected fields. Can someone explain this, please?
package de.bauer;
public abstract class MotorFahrzeug {
protected int id;
protected int hubraum;
protected int leistung;
// some stuff
}
}
package de.bauer;
public class LKW extends MotorFahrzeug {
private String kategorie = "Nutzfahrzeug";
// Konstruktor
LKW(int i, int l, int h) {
// some stuff
}
// some stuff
}
package de.bauer;
import java.util.Comparator;
public class VergleichHubraum<T extends MotorFahrzeug> implements Comparator<T> {
#Override
public int compare(T m1, T m2) {
int retValue = -1;
if( m1.hubraum == m2.hubraum)
retValue = 0;
if( m1.hubraum > m2.hubraum)
retValue = 1;
return retValue;
}
}
With a declaration like
package de.bauer;
public class VergleichHubraum<T extends MotorFahrzeug> implements Comparator<T> {
The type T is guaranteed to be bound to a subtype of MotorFahrzeug. Since MotorFahrzeug is in the same package as the class declared above, you can access any of its protected members through a reference of type T.

Categories

Resources