如何修复比较字符串与compareTo()的代码

时间:2019-08-10 17:52:04

标签: java string sorting comparable

我已经编写了这段代码,以按名称(字符串)对电影进行排序,但未对它进行排序。

此外,我应该如何根据year属性比较两个movies

//public int compareTo(Movies m) { return this.year-m.year; } 

我很困惑,因为我们已经通过排序方法传递了整个列表,所以正在比较哪个m对象。

import java.util.*;

class Movies implements Comparable<Movies> {
    private double rating;
    private String name;
    private int year;

    // Used to sort movies by year
    public int compareTo(Movies m) {
        return this.getName().compareTo(m.getName());

    }

    // Constructor
    public Movies(String nm, double rt, int yr) {
        this.name = nm;
        this.rating = rt;
        this.year = yr;
    }

    public void thisee() {
        System.out.println(this.year);
    }

    // Getter methods for accessing private data
    public double getRating() {
        return rating;
    }

    public String getName() {
        return name;
    }

    public int getYear() {
        return year;
    }

    public static void main(String[] args) {
        ArrayList<Movie> list = new ArrayList<Movie>();
        list.add(new Movie("Force Awakens", 8.3, 2015));
        list.add(new Movie("Star Wars", 8.7, 1977));
        list.add(new Movie("Empire Strikes Back", 8.8, 1980));
        list.add(new Movie("Return of the Jedi", 8.4, 1983));

        Collections.sort(list);

        System.out.println("Movies after sorting : ");
        for (Movie movie : list) {
            System.out.println(movie.getName() + " " + movie.getRating() + " " + movie.getYear());
        }
    }
}

2 个答案:

答案 0 :(得分:1)

如果您希望能够有时按名称排序,有时又按年份排序,而不必修改Movie类来做到这一点,则可以将订单嵌入到单独的“比较器”对象中,而不是嵌入到被比较。

public class MoviesByName implements Comparator<Movie> {
   public int compare(Movie m1, Movie m2) {
       return m1.getName().compareTo(m2.getName());
   }
}

public class MoviesByYear implements Comparator<Movie> {
   public int compare(Movie m1, Movie m2) {
       return m1.getYear() - m2.getYear(); 
   }
}

然后

Collections.sort(list, new MoviesByName());

Collections.sort(list, new MoviesByYear());

这种方法是说没有适用于“电影”的单个顺序-您在进行排序时定义您想要的顺序(通过比较器)。

MoviesByRating当然可以用相同的方式完成。

P.S。我注意到我错误地认为该班级叫电影而不是电影。我认为,“电影”更好,因为单个实例代表单个电影。 (比较:它是Integer而不是Integers)。

答案 1 :(得分:0)

Comparable.compareTo(o)的一般合同要返回

  • 如果this(Comparable)大于另一个对象(o),则为正整数。
  • 一个负整数,如果它小于另一个对象。
  • 如果等于另一个对象,则为0。

因此,要比较两部电影的年份,您需要为两部电影创建Integer对象,然后进行比较。

from itertools import chain
from math import pi

class Cylinder:

    _dependencies = {
        "length": ["volume"],
        "radius": ["volume"],
        "volume": ["mass"],
        "density": ["mass"]
    }
    _dependent_vars = set(chain(*list(_dependencies.values())))

    def __init__(self, radius, length, density):
        self._radius = radius
        self._length = length
        self._density = density
        self._volume = None
        self._mass = None

    def _reset_dependent_vars(self, name):
        for var in self._dependencies[name]:
            super().__setattr__(f"_{var}", None)
            if var in self._dependencies:
                self._reset_dependent_vars(var)

    def __setattr__(self, name, value):
        if name in self._dependent_vars:
            raise AttributeError("Cannot set this value.")
        if name in self._dependencies:
            self._reset_dependent_vars(name)
            name = f"_{name}"
        super().__setattr__(name, value)

    @property
    def volume(self):
        if self._volume is None:
            self._volume = self.length*pi*self.radius**2
            print("Volume calculated")
        return self._volume

    @property
    def mass(self):
        if self._mass is None:
            self._mass = self.volume*self.density
            print("Mass calculated")
        return self._mass

    @property
    def length(self):
        return self._length

    @property
    def radius(self):
        return self._radius

    @property
    def density(self):
        return self._density

输出(按年份排序):

// Used to sort movies by year
public int compareTo(Movies m) {
    Integer movie1 = Integer.valueOf(this.getYear());
    Integer movie2 = Integer.valueOf(m.getYear());
    return movie1.compareTo(movie2);
}

P.S如果您想按名称排序,只需更改主代码即可。

Movies after sorting : 
Star Wars 8.7 1977
Empire Strikes Back 8.8 1980
Return of the Jedi 8.4 1983
Force Awakens 8.3 2015

输出(按名称排序):

public static void main(String[] args) {
    // The class you created is Movies not Movie (IDK if that was typo)
    ArrayList<Movies> list = new ArrayList<Movies>();
    list.add(new Movies("Force Awakens", 8.3, 2015));
    list.add(new Movies("Star Wars", 8.7, 1977));
    list.add(new Movies("Empire Strikes Back", 8.8, 1980));
    list.add(new Movies("Return of the Jedi", 8.4, 1983));

    Collections.sort(list);

    System.out.println("Movies after sorting : ");
    for (Movies movie : list) {
       System.out.println(movie.getName() + " " + movie.getRating() + " " + 
       movie.getYear());
    }
}