2015-03-17 2 views
1

У меня есть класс объектовПоиск макс/мин значения с помощью Сопоставимые

public class Film implements Comparable<Film> 

Я использую Eclipse, и хотел бы знать, почему Film подчеркнут красным цветом с ошибкой, говоря:

The type Film must implement the inherited abstract method Comparable<Film>.compareTo<Film>

И теперь, на мой главный вопрос:

Как получить максимальную/минимальную длину и длину изображения пользователя е?

Мой класс объектов Фильм имеет методы получения и сеттера для названия пленки и длины пленки и метода toString. После this статьи (# 3) Я создал еще два метода в моем классе объекта:

public int max(Film maxLength){ 
    int compareLength = ((Film) maxLength).getLength(); 

    return this.length - compareLength; 
} 

public int min(Film minLength){ 
    int compareLength = ((Film) minLength).getLength(); 

    return compareLength - this.length; 
} 

Могу ли я использовать их, чтобы найти и распечатать макс/мин значения присланного пользователя длины пленки?

Если да, то как?

Если нет, то каков правильный способ сделать это?

Класс тест выглядит следующим образом:

import java.util.Scanner; 
public class test { 
    public static void main (String[] args){ 
     Film[] f = new Film[3]; 
     Scanner input = new Scanner(System.in); 
     for (int i=0;i<3;i++){ 
      f[i] = new Film(); 

      System.out.println("Enter Film Length:"); 
      f[i].setLength(input.nextInt()); 
      input.nextLine(); 
      System.out.println("Enter Title:"); 
      f[i].setTitle(input.nextLine()); 
     } 
     input.close(); 
     for (int i = 0; i < 3; i++) { 
      System.out.println(f[i].toString()); 
     } 
    } 
} 
+2

Компилятор говорит вам, что вам нужно реализовать необходимый метод интерфейса 'compareTo' в ваш класс «Фильм». Вы могли бы использовать свои методы «min/max» в этой реализации, чтобы достичь того, чего вы хотите. –

+0

Я проиграл относительно того, как я буду это делать @RyanJ –

ответ

2

Класс Film класс реализует Comparable<Film>. Это означает, что вы должны реализовать метод с именем compareTo() в классе Film, который обеспечит заказ для объектов этого класса.

@Override 
public int compareTo(Film that) { 
    // Order by film length 
    return Integer.compare(this.length, that.length); 
} 

Если вам нужно только, чтобы отсортировать объекты по длине пленки вы можете просто использовать Arrays.sort():

Film[] films = new Film[3]; 
// put the objects into the array 
Arrays.sort(films); 

Тогда films[0] будет содержать пленку с самой короткой длиной, в то время как последний элемент будет фильм с самой длинной длиной.

Если вам нужно сравнить другие поля, такие как название фильма, вы можете создать собственный компаратор:

class FilmTitleComparator implements Comparator<Film> { 
    public int compare(Film a, Film b) { 
     return Integer.compare(a.getTitle().length(), b.getTitle().length()); 
    } 
} 

И передать его Arrays.sort()

FilmTitleComparator titleComparator = new FilmTitleComparator(); 
Arrays.sort(films, titleComparator); 

Тогда films[0] будет содержать фильм с самым коротким названием, в то время как последним элементом будет фильм с самым длинным названием.

+0

Спасибо, это было просто и понятно. Быстрый вопрос, хотя, Arrays.sort в сопоставимом классе? –

+1

Рад помочь. Arrays.sort следует вызывать в массиве сопоставимого класса, а не внутри него. В опубликованном вами коде я бы поставил его в основной метод теста класса. –

+0

Есть ли способ, который я мог бы отдельно сортировать для max или min? Как два разных метода? –

0

Для простоты я погасил свой Film класс, чтобы показать тривиальный пример того, как осуществлять Comparable

public class Film implements Comparable<Film> { 
    int maxLength; 
    int minLength; 
    String title; 

    public Film() { 
     this.maxLength = 0; 
     this.minLength = 0; 
     this.title = ""; 
    }  

    // implement this method to accomplish comparison 
    public int compareTo(Film f) { 
     int result = 0; // the result to compute. 

     if (this.equals(f)) { 
      result = 0; // these objects are actually equal 
     } 

     // compare using meaningful data 
     else if (f != null) { 
      // check to see if this film is greater than the specified film 
      if (this.getMaxLength() > f.getMaxLength()) { 
       // this film is comparatively greater, return > 0 
       result = 1; 
      } 
      else if (this.getMaxLength() == f.getMaxLength()) { 
       // these two films are comparatively equal 
       result = 0; 
      } 
      else { 
       // this film is comparatively less than the specified film 
       result = -1; 
      } 

      // similarly, you could also check min, but there's really no reason to do that unless your implementation calls for it. 
     } 
     else { 
      throw new IllegalArgumentException("null Film object not allowed here..."); 
     } 

     return result; 
    } 

    @Override 
    public boolean equals(Object o) { 
     if (this == o) return true; 
     if (o == null || getClass() != o.getClass()) return false; 

     Film film = (Film) o; 

     if (maxLength != film.maxLength) return false; 
     if (minLength != film.minLength) return false; 
     if (!title.equals(film.title)) return false; 

     return true; 
    } 

    @Override 
    public int hashCode() { 
     int result = maxLength; 
     result = 31 * result + minLength; 
     result = 31 * result + title.hashCode(); 
     return result; 
    } 

    public int getMaxLength() { 
     return maxLength; 
    } 

    public void setMaxLength(int maxLength) { 
     this.maxLength = maxLength; 
    } 

    public int getMinLength() { 
     return minLength; 
    } 

    public void setMinLength(int minLength) { 
     this.minLength = minLength; 
    } 

    public String getTitle() { 
     return title; 
    } 

    public void setTitle(String title) { 
     this.title = title; 
    }  
} 

Чтобы исправить тест, чтобы реально использовать такая реализация (на самом деле это ничего не проверяет ...), вы можете сделать:

import java.util.Scanner; 
public class test { 
    public static void main (String[] args){ 
     Film lastFilm = null; // arbitrary reference to film 
     Film[] f = new Film[3]; 
     Scanner input = new Scanner(System.in); 
     for (int i=0;i<3;i++){ 
      f[i] = new Film(); 

      System.out.println("Enter Film Length:"); 
      f[i].setLength(input.nextInt()); 
      input.nextLine(); 
      System.out.println("Enter Title:"); 
      f[i].setTitle(input.nextLine()); 
     } 
     input.close(); 
     for (int i = 0; i < 3; i++) { 
      if (lastFilm != null) { 
       // compare the films to test. current to last film 
       if (f[i].compareTo(lastFilm) > 0) { 
        System.out.println(f[i].getTitle() + " is greater than " + lastFilm.getTitle()"); 
       } 
       else if (f[i].compareTo(lastFilm) < 0) { 
        System.out.println(f[i].getTitle() + " is less than " + lastFilm.getTitle()"); 
       } 
       else { 
        System.out.println(f[i].getTitle() + " is equal to " + lastFilm.getTitle()"); 
       } 
      } 
      System.out.println(f[i].toString()); 
      lastFilm = f[i]; 
     } 
    } 
} 

Что-то вроде этого может вас начать ... удачи

+1

Удивительный ответ, это действительно плохо. MinBy/maxBy не отправляет стандарт в java – JakeWilson801

0

Другим решением было бы реализовать Comparable<Film>:

@Override 
public int compareTo(Film that) { 
    return this.length - that.length; 
} 

И использовать org.apache.commons.lang3.ObjectUtils#min или org.apache.commons.lang3.ObjectUtils#max как:

Film min = ObjectUtils.min(film1, film2); 
Film max = ObjectUtils.max(film1, film2);