简体   繁体   English

如何从通用数组列表中找到最小值?

[英]How to find the minimum value from a generic arraylist?

I am having trouble trying to write a method to return the object that has the least volume in a generic ArrayList. 我在尝试编写一种方法来返回通用ArrayList中体积最小的对象时遇到麻烦。 These are the guidelines I was given to write the code: 这些是我编写代码的指导原则:

min() - This method takes an ArrayList of Bounded Generic Type which only allows Shape objects and its subclasses. min()-此方法采用ArrayList of Bounded Generic Type,该列表仅允许Shape对象及其子类。 - The method should return the object with the minimum volume from the list of objects. -该方法应从对象列表中返回最小体积的对象。

But I'm not entirely sure if I even followed it right. 但是我不确定自己是否正确。 Is there a way I could use the Collections.min (and Collections.max since I have to write a max volume method too)? 有没有一种方法可以使用Collections.min(和Collections.max,因为我也必须编写最大音量方法)? I get a bound mismatch error saying: The generic method min(Collection) of type Collections is not applicable for the arguments (ArrayList). 我收到一个绑定的不匹配错误消息:类型为Collections的通用方法min(Collection)不适用于参数(ArrayList)。 The inferred type Shape is not a valid substitute for the bounded parameter > 推断类型Shape不是有效替代边界参数>

My Shape class is simply an interface with a getVolume(); 我的Shape类只是一个带有getVolume()的接口; method where my other classes (Spheres, Ellipsoids, etc.) override this method: 我的其他类(球体,椭圆体等)覆盖此方法的方法:

public interface Shape {
    public double getVolume();
}

And here is my min method (in another class with other methods) I'm having problems with: 这是我的min方法(与其他方法一起在另一个类中),我遇到问题:

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

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

There are two options in java.utils.Collections . java.utils.Collections有两个选项。

  • static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> coll)
  • static <T> T max(Collection<? extends T> coll, Comparator<? super T> comp)

The first of these requires your Shape to implement Comparator<Shape> 其中的第一个要求您的Shape实施Comparator<Shape>

class Shape implements Comparable<Shape> {
    int compareTo(Shape other) {
       return Math.signum(getVolume()-other.getVolume);
    }
    ...
}

ArrayList<Shape> myShapes = ...
Shape minShape = Collections.min(myShapes);

The second requires you to create a custom comparator: 第二个要求您创建一个自定义比较器:

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

The first is less code, but the second is more adaptable if you want to sort on something else - say surface area, or position. 第一种是较少的代码,但是第二种是更可适应的,如果您想对其他内容(例如表面积或位置)进行排序。

To compare the volumes, you can make Shape Comparable or use a Comparator. 要比较体积,可以使“形状可比”或使用“比较器”。

Comparable 可比

This requires changes to all shapes, but none to the code using them. 这需要更改所有形状,但无需更改使用它们的代码。 I used an abstract class to easily put the comparing to all classes. 我使用抽象类轻松将比较对象与所有类进行比较。

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 { /* ... */ } 

And to use: 并使用:

Collections.min(collection);

Comparator 比较

This needs no modification to the shapes, but a bit more code to use them. 不需要修改形状,但是需要更多代码才能使用它们。

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

And to use: 并使用:

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

It's because Java erases type at runtime, so the Collection doesn't know what type it's actually dealing with. 这是因为Java在运行时会删除类型,因此Collection不知道它实际上在处理什么类型。 It's a limiting factor when using Java generics - I've bumped heads with it before a few years ago but I couldn't figure out a way to get around it and it turned out to be a language restriction. 在使用Java泛型时,这是一个限制因素-几年前,我曾碰到过它,但我想不出一种解决方法,结果证明它是语言限制。

The best thing to do is create a public T getMinVolume(ArrayList<T> list) method to iterate through each T. 最好的办法是创建一个public T getMinVolume(ArrayList<T> list)方法来遍历每个T。

eg. 例如。

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;
}

Something like that, my Java is a bit rusty but the logic should work. 像这样,我的Java有点生锈,但是逻辑应该起作用。

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;
}

You should this method http://www.tutorialspoint.com/java/util/collections_min_comparator.htm and provide a comparator : 您应该使用以下方法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());
            }
        });
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM