简体   繁体   中英

Using Comparable interface for primitive data types

Apologies if this is a silly question, i am relatively new to programming.

Basically i had a homework question to create a post office scenario that supports two types of items: items sent by the air, and items that are sent by the sea. for each type, i used a calcFee method to calculate the total shipping costs.

The second part of the homework asks to extend the Item class so that it implements the Comparable interface, where items are sorted on their calcFee value. Now i understand that primitive data types cannot be sorted from the Comparable interface. Because the question specifically asks to use the Comparable interface am i doing something wrong or am i just creating the program incorrectly

Any help would be greatly appreciated.

package homework3;
    import java.util.ArrayList;
    import java.util.Collections;
/**
 *
 * @author Josh
 */
public class Homework3 {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
            ArrayList<Item> items = new ArrayList();
            items.add(new airItems(11, "josh", "sam", 295));
            items.add(new airItems(11, "zosh", "sam", 295));
            items.add(new seaItems(11, "aosh", "sam", 11, 12, 15));

            Collections.sort(items);

            for (Item i : items){
                i.calcFee();
                i.print();

            }
    }

}

class Item implements Comparable<Item>{

    int id;
    String from;
    String to;
    double fee;

    public Item(int id, String from, String to){
        this.id = id;
        this.from = from;
        this.to  = to;


    }

    public void print(){
        System.out.println("id: " + id + "\tFrom: " + from + "\tTo: " + to + "\tFee: " + fee);
    }

    public double calcFee(){
        return 0;
    }


    @Override
    public int compareTo (Item item1){
        return this.fee.compareTo(item1.calcFee());
    }
}

class airItems extends Item{
    long weight;

    public airItems(int id, String from, String to, int weight){
        super(id, from, to);
        this.weight = weight;
    }

    public void print(){
        super.print();
        System.out.println("Weight: " + weight);
        System.out.println("");

    }

    @Override
    public double calcFee(){
        if (weight < 100){
            fee = 2.5;
        }
        else if (weight < 200) {
            fee = 5;
        }
        else if (weight < 300) {
            fee = 7.5;
        }
    return fee;    
    }

}


class seaItems  extends Item{
    int length;
    int width;
    int depth;

    public seaItems(int id, String from, String to, int length, int width, int depth){
        super(id, from, to);
        this.length = length;
        this.width = width;
        this.depth = depth;
    }

    @Override
    public double calcFee(){
        if  (length <= 10 && width <= 10 && depth <= 10){
            fee = 5;
        }
        else if  (length <= 20 && width <= 20 && depth <= 20){
            fee = 10;
        }
        if  (length <= 50 && width <= 50 && depth <= 50){
            fee = 5;
        }
        else if (length > 50 && width > 50 && depth > 50 ){
            fee = 0;
        }
        return fee;
    }

    @Override
    public void print(){
        super.print();
        System.out.println("Length: " + length + "\tWidth:" + width + "\tdepth" + depth);
        System.out.println("");
    }



}

Primitive data types can be used together with Comparable interface as far as I am concerned, but it is discouraged as it's too complicated and unnecessary, often requiring some hacks to be made (though I am not completely sure so don't take my word for it).

As for your task, the easiest way to accomplish this would be to create a new List<Item> and to sort it using with Comparable interface, using .stream :

        List<Item> collect = items.stream()
            .sorted(Comparator.comparingDouble((Item it) -> it.calcFee()).reversed()) 
            .collect(toList());
    collect.forEach(it-> System.out.println(it));

I have used lambda expression over here, but member reference is also acceptable: (Item::calcFee)

Now, this will not work with your @Override of print function, you have to override toString as the function requires String to be returned. This can be accomplished by doing this:

    @Override
    public String toString() {
        return "id: " + id + "\tFrom: " + from + "\tTo: " + to + "\tFee: " + fee;
    }

The result is this:

id: 11  From: josh  To: sam Fee: 7.5
id: 11  From: josh  To: sam Fee: 5.0

Use the compare() method of Double :

@Override
public int compareTo (Item item){
    return Double.compare(calcFee(), item.calcFee());
}

Better to use calcFee() rather than fee in case fee hasn't been initialized. Unless you have zillions of items, it won't make much performance difference.

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