【问题标题】:Using Comparable interface for primitive data types对原始数据类型使用 Comparable 接口
【发布时间】:2016-10-30 10:11:24
【问题描述】:

抱歉,如果这是一个愚蠢的问题,我对编程比较陌生。

基本上我有一个家庭作业问题,要创建一个支持两种类型物品的邮局场景:空运物品和海运物品。对于每种类型,我使用 calcFee 方法来计算总运费。

作业的第二部分要求扩展 Item 类,以便它实现 Comparable 接口,其中项目按其 calcFee 值排序。现在我明白原始数据类型不能从 Comparable 接口排序。因为问题特别要求使用 Comparable 接口我做错了什么还是我只是错误地创建了程序

任何帮助将不胜感激。

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("");
    }



}

【问题讨论】:

  • 我没有看到Comparable 接口在任何地方实现。你试过了吗?
  • 您没有在原始数据类型上使用Comparable,而是在您的Item 类上使用它。您的 Item 类需要扩展 Comparable 然后实现 compareTo 方法,该方法将比较每个 ItemcalcFee 值。
  • 抱歉,我取消了使用类似界面的尝试,因为它会导致错误。请参阅上面的代码,因为我已经编辑了代码以包含我的尝试。它基本上显示了 compareTo 方法的错误,指出“无法取消引用双精度”。我可以使用上面相同的方法对字符串进行排序,只是当我尝试对布尔值进行排序时出现错误。

标签: java comparable


【解决方案1】:

就我而言,原始数据类型可以与Comparable 接口一起使用,但不鼓励使用,因为它太复杂且不必要,通常需要进行一些黑客攻击(虽然我不完全确定所以不要'不要相信我的话)。

至于您的任务,完成此任务的最简单方法是创建一个新的List&lt;Item&gt; 并使用Comparable 接口对其进行排序,使用.stream

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

我在这里使用了 lambda 表达式,但成员引用也是可以接受的: (Item::calcFee)

现在,这不适用于您的 @Overrideprint 函数,您必须覆盖 toString,因为该函数需要返回字符串。这可以通过这样做来完成:

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

结果是这样的:

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

【讨论】:

    【解决方案2】:

    使用Doublecompare()方法:

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

    如果fee 尚未初始化,最好使用calcFee() 而不是fee。除非您拥有数以万计的项目,否则不会产生太大的性能差异。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-21
      相关资源
      最近更新 更多