简体   繁体   中英

Alphabetically Sorting List with multiple different objects using different attributes in Java

For a school project, i have to make a card game. The cards can have different types (Joker, PuntenKaart, KleurKaart). Each player has a hand with multiple different combinations of cards (obviously).

i have an abstract class Kaart (card), with 3 subclasses: Joker, KleurKaart (ColourCard), PuntenKaart (PointsCard). All subclasses have an attribute "type" (Joker, KleurKaart, PuntenKaart), but KleurKaart has a second attribute called kleur (colour).

Here's the question: how can I sort a player's hand alphabetically in this situation? Joker and PuntenKaart are easy, just compare type, but with KleurKaart, i'd first have to check if the given Kaart is an instance of KleurKaart and then compare other cards' type to kleur? i don't understand.

class Kaart

package domein;

public abstract class Kaart implements Comparable<Kaart>{

     private String type;

     public Kaart(String type){
         this.type = type;
     }

     public String getType(){
         return type;
     }

     @Override
     public int compareTo(Kaart vergelijkingsKaart) {
         return type.compareTo(vergelijkingsKaart.type);
     }

     @Override
     public String toString(){
         return this.type;
     } 
}

class Joker

package domein.kaarten; 
import domein.Kaart;

public class Joker extends Kaart {
     public Joker() {
         super("JokerKaart");
     }  
}

class PuntenKaart

package domein.kaarten; 
import domein.Kaart;

public class PuntenKaart extends Kaart {
    public PuntenKaart() {
        super("PuntenKaart");
    } 
}

class KleurKaart

package domein.kaarten; 
import domein.Kaart;

public class KleurKaart extends Kaart {
     private String kleur;

     public KleurKaart(String kleur) {
         super("KleurKaart");
         this.kleur = kleur;
     }

     public String getKleur(){
         return this.kleur;
     }

     @Override
     public String toString(){
         return this.kleur;
     } 
}

Add this code to your KleurKaart class:

 @Override
 public int compareTo(Kaart vergelijkingsKaart) {
     int superReturn = super.compareTo(vergelijkingsKaart);//check how the types of the two cards compare.
     if(superReturn == 0){//if they are the same then do some more checking otherwise return the output of the first check.
        if(vergelijkingsKaart isinstanceof KleurKaart){//if the other card is also a colored card then compare the colours otherwise return the result of the first check.
            KleurKaart otherKaart = ((KleurKaart) vergelijkingsKaart);//cast the other card
            return kleur.compareTo(otherKaart.getgetKleur());//compare the colours.
        }
     }
     return superReturn
 }

This is will override your compareTo() method in the superclass. So when you call compareTo() on an instance of KleurKaart even if you don't know that it is a KleurKaart when executing the code then the new compareTo() method will be used.

So essentially check the types of the two cards. If the types are the same AND the other card is a coloured card * , then compare the two colours of the two cards and return that result, otherwise return the result of super.compareTo() method.

Tip: There is actually a class called Color that is usually used for graphics , so if there is extra functionality, such as printing the cards, then i suggest you change type of color to Color.

* (no need to check for this card since it is already an instance of KleurKaart since this compareTo() method only exists in the KleurKaart)

Another way to solve this is to change the toString() method of KleurKaart to

 @Override
 public String toString(){
     return super.toString() + "  " +  this.type;
 } 

And the compareTo() method of the Kaart superclass

 @Override
 public int compareTo(Kaart vergelijkingsKaart) {
     return this.toString().compareTo(vergelijkingsKaart.toString());
 }

So you fully write everything you need in the toString() class and the compareTo() method can check which string goes first.

You should ovverride the compareTo in the KleurKaart class as below:

 @Override
 public int compareTo(Kaart vergelijkingsKaart) {
     int result = super.compareTo(vergelijkingsKaart.type);
     if(result==0) { //they are both KleurKaart objects
         return ((KleurKaart)this).kleur.compareTo(((KleurKaart)vergelijkingsKaart).kleur);
     }
     return result;
 }

I think you should be able to add anothor compareTo in KleurKaart which accepts KleurKaart as a type. It can do the special two-level (color and type) comparison.

Depends what you want to compare. Color name for KleurKaart (RED) vs. type JOKER for instance?

Say I have hand JOKER, BLUE, RED, PuntenKaart. How to you expect to be sorted? BLUE, JokerKaart, PuntenKaart, RED ?

If so, just compare the toString() you already have in place (although it's probably better to define a clearly named method for this).

this.toString().compareTo(vergelijkingsKaart.toString())

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM