【问题标题】:Getting the maximum from a list of objects从对象列表中获取最大值
【发布时间】:2020-03-10 13:56:55
【问题描述】:

我正在尝试从我的国家列表中获取最大值(例如,最大值)是否可以尝试在对象列表中使用 for each 循环?我真的很想用最大的方法来做。我知道这种方法是错误的,但我正在尝试一些东西以充分利用它

这是我的代码

class Main {
    public static void main(String args[]) {
        Measurable[] countries = new Measurable[3];
        countries[0] = new Country("Uruguay", 176220);
        countries[1] = new Country("Thailand", 514000);
        countries[2] = new Country("Belgium", 30510);
        Measurable maximum = maximum(countries);
    }


   public static Measurable maximum(Measurable[] objects) {
        if (objects.length == 0) { return 0; }
        for (Measurable obj : objects)
        {
            int area = obj.getMeasure();
        }

        return area;
    }
}
class Country implements Measurable
{
    private String name;
    private int area;

    public Country(String name, int area)
    {
        this.name = name;
        this.area = area;

    }

    @Override
    public double getMeasure() {
        return area;
    }
}
interface Measurable {
    double getMeasure();
}

【问题讨论】:

  • 我建议你使用 Comparator 而不是你的 Measurable 接口
  • 您的maximum() 方法被声明为返回一个Measurable 对象,调用者似乎也希望如此,但是您的代码返回的是int 值,那么它是什么?该方法应该返回Measurable 对象还是int 值,如果是对象,您想要什么值而不是0null 或带有measure = 0Measurable
  • 你想得到最大面积,还是面积最大的国家

标签: java oop interface


【解决方案1】:

使用 Java 8 Streams,maximum() 方法的主体可能如下所示:

Arrays.stream(objects).max(Comparator.comparingInt(Measurable::getMeasure))

但请记住,上述行将返回可选项,因此要么更改方法签名以返回可选项,要么(如果您坚持保持“原样”),请考虑如何解决可选项时的情况不存在(例如抛出异常或返回一些虚拟对象,如new Country("dummy", 0);

【讨论】:

    【解决方案2】:

    创建一个Measurable 对象(max),该对象包含可能的面积最小值。

    max 的区域与objects 中的每个对象(obj) 进行比较。

    如果对象(obj)的面积较大,替换max;

    返回max

    public static Measurable maximum(Measurable[] objects) {
    
        if (objects == null || objects.length == 0){
    
            return new Country("", 0);
    
        }
    
        Measurable max = new Country("", 0);
    
        for (Measurable obj : objects){
    
            if(obj.getMeasure() > max.getMeasure()){
    
                max = obj;
    
            }
    
        }
    
        return max;
    
    }
    

    【讨论】:

      【解决方案3】:

      在比较 Java 中的两个对象时,我强烈建议让对象实现 Comparator(或 Comparable)。在我看来,这是在 Java 中比较两个对象的最佳方式。

      通过让您的 Country 类实现 Comparator<Country>,您可以在您的类中创建一个新的自定义比较方法。接口Comparator 包含一个名为compare(T o1, T o2) 的抽象方法,它将在您的 Country 类中继承。

      class Country implements Comparator<Country>
      {
          private String name;
          private int area;
      
          public Country(String name, int area) 
          {
              this.name = name;
              this.area = area;
      
          }
      
          public int compare(Country c1, Country c2) { //inherited from Comparator interface
              if(c1.area > c2.area) { //returns -1 if c1.area > c2.area
                  return -1;
              } else {
                  return 1; //returns 1 if c1.area < c2.area or c1.area == c2.area
              }
          }
      }
      

      对你的对象实现比较器的原因是你现在可以使用Arrays.sort 方法对包含Country 对象的数组进行排序,遵循Country 类中自定义的比较方法。

      通过使用包含{("Uruguay", 176220), ("Thailand", 514000), "Belgium", 30510}Arrays.sort(countries) 将数组排序到{("Thailand", 514000),("Uruguay", 176220),("Belgium", 30510)}

      请注意,您的数组包含 Country 对象,其中包含上述信息,但实际上并不包含元组(这样编写是为了使其更加可视化)。

      现在您可以通过Country max = countries[0]; 简单地获取最大面积的国家对象。

      通过实现 Comparator,您可以避免 for 循环,从而使代码更加简洁(如果您需要比较程序中多个不同位置的对象,这会产生很大的不同)。

      现在你的最大方法只包含两行代码。

      public static Country maximum(Country[] countries) {
              Arrays.sort(countries);
              return countries[0];
          }
      

      【讨论】:

      • 为什么要费尽千辛万苦才找到最大值?即使是最好的排序方法也比简单地遍历列表一次要重复得多。
      • 不知道替换类中的接口和一个方法算不算麻烦。此外,通过让比较发生在类本身而不是程序中的任何其他位置,我发现程序的结构更加稳定。现在可以在程序的其他位置进行其他或类似的比较。排序后的数组也可用于查找第 n 个最大的国家或按排序顺序打印所有国家。
      • 我并不反对您使用comparator。添加一个不一定是一个坏主意。但是在一个简单的循环中使用它来找到maximum。如果 OP 愿意,它将始终可以对数组进行排序。
      【解决方案4】:

      当您想要获得某个双精度的最大值时,最好将值 max 初始化为 Double.MIN_VALUE。这样,您可以确定将获得最大值,即使它是负数(在这种情况下不是这样,但这是一种很好的做法)。

      我还认为最好跳过 Measurable 界面并使用 Country 并相应地访问适当的值。所以我修改了这个例子来做到这一点。

         public static Country maximum(Country[] objects) {
             if (objects.length == 0) {
                      return null; // null for objects.
             }
             double max = Double.MIN_VALUE; 
             Country retVal = null;
             for (Country obj : objects) {
                  double area = obj.getMeasure();
                  // each time thru, see if current value
                  // is greater than current max. If so
                  // update the return value and max.
                  if  (area > max) {
                       max = area;
                       retVal = obj;
                  }
              }
              // return the object with the 
              // largest area.
              return retVal; 
          }
      

      你可以这样称呼它。

          public static void main(String args[]) {
              Country[] countries = new Country[3];
              countries[0] = new Country("Uruguay", 176220);
              countries[1] = new Country("Thailand", 514000);
              countries[2] = new Country("Belgium", 30510);
              Country maximum = maximum(countries);
          }
      

      您仍然可以参考该界面,但使用 Country 而不是 Measurable 更有意义(恕我直言),因为我认为您不仅想要一个数字,还想知道哪个国家/地区的面积最大。

      System.out.println("The largest country was " + maximum.getName());
      System.out.println("Its area is " + maximum.getMeasure());
      

      您需要将getName() 方法作为私有字段添加到您的Country 类中,没有getter 不是很有用。

      而且您始终可以使用流。这是一种变体。

              Country c = Arrays.stream(countries)
                      .max(Comparator.comparing(Country::getMeasure))
                      .orElseGet(() -> new Country("None Found", -1));
      
              System.out.println("The largest country was " + c.getName());
              System.out.println("Its area is " + c.getMeasure());
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-06-29
        • 1970-01-01
        • 2020-09-28
        • 2015-08-11
        • 1970-01-01
        • 2023-03-03
        • 2017-09-20
        相关资源
        最近更新 更多