【问题标题】:How to find the minimum value from a generic arraylist?如何从通用数组列表中找到最小值?
【发布时间】:2014-06-01 06:54:42
【问题描述】:

我在尝试编写一种方法来返回泛型 ArrayList 中体积最小的对象时遇到问题。这些是我编写代码的指导方针:

分钟() - 此方法采用有界通用类型的 ArrayList,它只允许 Shape 对象及其子类。 - 该方法应返回对象列表中体积最小的对象。

但我不完全确定我是否正确地遵循了它。有没有办法可以使用 Collections.min(和 Collections.max,因为我也必须编写最大音量方法)?我收到一个绑定不匹配错误说:集合类型的通用方法 min(Collection) 不适用于参数 (ArrayList)。推断的类型 Shape 不是有界参数的有效替代品>

我的 Shape 类只是一个带有 getVolume() 的接口;我的其他类(球体、椭圆体等)覆盖此方法的方法:

public interface Shape {
    public double getVolume();
}

这是我的 min 方法(在具有其他方法的另一个类中)我遇到了问题:

public static <T> T  min() {
    ArrayList<? extends Shape> list;    

     T min = Collections.min(list));
        return min;

【问题讨论】:

  • 您的 Shape 接口必须扩展 Comparable,或者您必须将 Comparator 传递给 Collections.min()(这将是我的首选解决方案)。
  • 投票赞成你的评论,你是对的,但如果不可能,你仍然需要实现某种compareTo() 方法。这是可比较的文档docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html

标签: java generics arraylist min


【解决方案1】:

这是因为 Java 在运行时擦除类型,所以 Collection 不知道它实际处理的是什么类型。这是使用 Java 泛型时的一个限制因素 - 几年前我曾遇到过它,但我无法找到绕过它的方法,结果证明这是一种语言限制。

最好的办法是创建一个public T getMinVolume(ArrayList&lt;T&gt; list) 方法来遍历每个 T。

例如。

public T getMinVolume(ArrayList<T> list) {
    T min = null;
    for(T item: list) {
        if (min == null) {
            min = item;
        }

        if (min > item) {
            min = item;
        }
    }

    return min;
}

类似的,我的 Java 有点生疏,但逻辑应该可以工作。

【讨论】:

    【解决方案2】:

    要比较体积,您可以使 Shape Comparable 或使用 Comparator。

    可比

    这需要更改所有形状,但不需要更改使用它们的代码。我使用了一个抽象类来轻松地比较所有类。

    public interface Shape extends Comparable<Shape> {
        public double getVolume();
    }
    
    public abstract class BaseShape implements Shape {
        public int compareTo(Shape other) {
            return Double.compare(getVolume(), other.getVolume());
        }
    } 
    
    public class Box extends BaseShape {
        public double getVolume() {
            return volume;
        } 
    } 
    public class Ball extends BaseShape { /* ... */ } 
    

    并使用:

    Collections.min(collection);
    

    比较器

    这不需要修改形状,但需要更多代码来使用它们。

    public class ShapeComparator implements Comparator<Shape> {
        public int compare(Shape a, Shape b) {
            return Double.compare(a.getVolume(), b.getVolume());
        } 
    } 
    

    并使用:

    Collections.min(collection, new ShapeComparator());
    

    【讨论】:

      【解决方案3】:

      java.utils.Collections 有两个选项。

      • static &lt;T extends Object &amp; Comparable&lt;? super T&gt;&gt; T min(Collection&lt;? extends T&gt; coll)
      • static &lt;T&gt; T max(Collection&lt;? extends T&gt; coll, Comparator&lt;? super T&gt; comp)

      第一个要求你的 Shape 实现Comparator&lt;Shape&gt;

      class Shape implements Comparable<Shape> {
          int compareTo(Shape other) {
             return Math.signum(getVolume()-other.getVolume);
          }
          ...
      }
      
      ArrayList<Shape> myShapes = ...
      Shape minShape = Collections.min(myShapes);
      

      第二个要求你创建一个自定义比较器:

      class Shape {
          ...
      }
      
      class ShapeVolumeComparator implements Comparator<Shape> {
          int compare(Shape s1, Shapes2) {
             return Math.signum(s1.getVolume()-s2.getVolume());
          }
      }
      
      ArrayList<Shape> myShapes = ...;
      Shape minShape = Collections.min(myShapes, new ShapeVolumeComparator() );
      

      第一个代码更少,但如果您想对其他内容(例如表面积或位置)进行排序,则第二个更具适应性。

      【讨论】:

        【解决方案4】:
        public <E extends Comparable> E getMin(List<E> list){
            E min = null;
            for(E element:list){
                if(min == null){
                    min = element;
                    continue;
                }
                if(element.compareTo(min) < 0){
                    min = element;
                }
            }
            return min;
        }
        

        【讨论】:

          【解决方案5】:

          你应该使用这个方法http://www.tutorialspoint.com/java/util/collections_min_comparator.htm 并提供一个比较器:

          import java.util.Collection;
          import java.util.Collections;
          import java.util.Comparator;
          
          public abstract class Shape {
              public abstract double getVolume();
          
              public Shape min(Collection<? extends Shape> col) {
                  return Collections.min(col, new Comparator<Shape> () {
                      public int compare(Shape l, Shape r) {
                          return ((Double) l.getVolume()).compareTo(r.getVolume());
                      }
                  });
              }
          }
          

          【讨论】:

            猜你喜欢
            • 2022-01-24
            • 2016-02-12
            • 2021-06-23
            • 2020-12-02
            • 2022-01-24
            • 2015-07-07
            • 2014-10-23
            • 2021-10-10
            相关资源
            最近更新 更多