[英]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. 要比较体积,可以使“形状可比”或使用“比较器”。
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);
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.