在通用 ArrayList 中查找最小值
Finding smallest value in generic ArrayList
我不断收到一条消息,告诉我运算符 <
对于类型 T,T
是未定义的。这发生在
左右
if(index<lowest)
我将如何修改我的程序,以便我可以使用通用方法获取数组列表的最小值和最大值?
package p07;
import java.util.ArrayList;
public class MyList<T extends Number> {
private ArrayList<T> l;
public MyList(ArrayList<T> l) {
this.l=l;
}
public void add(T x) {
l.add(x);
}
public static <T> void smallest(ArrayList<T> l) {
T lowest=l.get(0);
for(T index:l) {
if(index<lowest) {
}
}
}
}
编译器是对的:运算符<
只适用于原始数值类型。引用 JLS 的 section 15.20.1:
The type of each of the operands of a numerical comparison operator must be a type that is convertible (§5.1.8) to a primitive numeric type, or a compile-time error occurs.
因此,它没有为对象定义,甚至没有为数字定义,因为它们不能被拆箱为原始类型:JLS 的 section 5.1.8:
A type is said to be convertible to a numeric type if it is a numeric type (§4.2), or it is a reference type that may be converted to a numeric type by unboxing conversion.
你需要的是使用一个Comparator
or make your objects Comparable
。 Comparator
负责比较两个相同类型的对象。由于这里的对象是数字,而不是Comparable
,你需要使用自定义的Comparator
,像这样:
Comparator<Number> myComparator = new Comparator<Number>() {
@Override
public int compareTo(Number n1, Number n2) {
// implement logic here.
// Return -1 if n1 < n2, 0 if n1 = n2, 1 if n1 > n2
}
};
然后你可以像这样使用这个比较器:
public static <T extends Number> T smallest(List<T> l) {
T lowest = l.get(0);
for (T index : l) {
if (myComparator.compareTo(index, lowest) < 0) {
index = lowest;
}
}
return lowest;
}
(请注意,我将 T extends Number
添加到方法的类型中 - 那是因为该方法是静态的,所以它实际上声明了另一种类型 T
而 class是)。
这里有几处错误,但让我们从容易实现的语法水果开始。
算术运算符仅适用于原始值,而T
非常类似于Object
,因此您将无法使用它们这里。
您的语法的另一个细微差别是您 T
的静态函数 与 不同T
绑定到您的 class.
您可以通过自己添加绑定来解决这个问题...
public static <T extends Number> void smallest(ArrayList<T> l)
...但这让我想问,为什么你希望这个方法完全是静态的?
您正在使用参数 l
隐藏字段 l
的名称,因此虽然您可能认为这对提供的实例 l
有效,但它不会,因为方法本身已声明 static
,如果不是,您仍然会隐藏字段的名称。
您应该做的是从该方法中删除 static
,并从函数中删除参数。
public void smallest() {}
但是现在,您遇到了一个问题,您实际上 return 不知道最小值是多少。你应该 return 它而不是什么都没有:
public T smallest() {}
如果您能够排序,从数组中取出最后一个值是很简单的。您只需要确保所有元素都是 Comparable
以便可以对它们进行排序,以及您最关心的值 - 例如 Integer
、Double
、Float
, Long
- 是.
public class MyList<T extends Number & Comparable<T>> {}
如果你可以排序,那么得到最小的就是直截了当:
public T smallest() {
// Don't mutate the order of the original array.
ArrayList<T> listCopy = new ArrayList<>(l);
Collections.sort(listCopy);
return listCopy.get(0);
}
通过这种方法获得最高我留作 reader 的练习。
我不断收到一条消息,告诉我运算符 <
对于类型 T,T
是未定义的。这发生在
if(index<lowest)
我将如何修改我的程序,以便我可以使用通用方法获取数组列表的最小值和最大值?
package p07;
import java.util.ArrayList;
public class MyList<T extends Number> {
private ArrayList<T> l;
public MyList(ArrayList<T> l) {
this.l=l;
}
public void add(T x) {
l.add(x);
}
public static <T> void smallest(ArrayList<T> l) {
T lowest=l.get(0);
for(T index:l) {
if(index<lowest) {
}
}
}
}
编译器是对的:运算符<
只适用于原始数值类型。引用 JLS 的 section 15.20.1:
The type of each of the operands of a numerical comparison operator must be a type that is convertible (§5.1.8) to a primitive numeric type, or a compile-time error occurs.
因此,它没有为对象定义,甚至没有为数字定义,因为它们不能被拆箱为原始类型:JLS 的 section 5.1.8:
A type is said to be convertible to a numeric type if it is a numeric type (§4.2), or it is a reference type that may be converted to a numeric type by unboxing conversion.
你需要的是使用一个Comparator
or make your objects Comparable
。 Comparator
负责比较两个相同类型的对象。由于这里的对象是数字,而不是Comparable
,你需要使用自定义的Comparator
,像这样:
Comparator<Number> myComparator = new Comparator<Number>() {
@Override
public int compareTo(Number n1, Number n2) {
// implement logic here.
// Return -1 if n1 < n2, 0 if n1 = n2, 1 if n1 > n2
}
};
然后你可以像这样使用这个比较器:
public static <T extends Number> T smallest(List<T> l) {
T lowest = l.get(0);
for (T index : l) {
if (myComparator.compareTo(index, lowest) < 0) {
index = lowest;
}
}
return lowest;
}
(请注意,我将 T extends Number
添加到方法的类型中 - 那是因为该方法是静态的,所以它实际上声明了另一种类型 T
而 class是)。
这里有几处错误,但让我们从容易实现的语法水果开始。
算术运算符仅适用于原始值,而T
非常类似于Object
,因此您将无法使用它们这里。
您的语法的另一个细微差别是您 T
的静态函数 与 不同T
绑定到您的 class.
您可以通过自己添加绑定来解决这个问题...
public static <T extends Number> void smallest(ArrayList<T> l)
...但这让我想问,为什么你希望这个方法完全是静态的?
您正在使用参数 l
隐藏字段 l
的名称,因此虽然您可能认为这对提供的实例 l
有效,但它不会,因为方法本身已声明 static
,如果不是,您仍然会隐藏字段的名称。
您应该做的是从该方法中删除 static
,并从函数中删除参数。
public void smallest() {}
但是现在,您遇到了一个问题,您实际上 return 不知道最小值是多少。你应该 return 它而不是什么都没有:
public T smallest() {}
如果您能够排序,从数组中取出最后一个值是很简单的。您只需要确保所有元素都是 Comparable
以便可以对它们进行排序,以及您最关心的值 - 例如 Integer
、Double
、Float
, Long
- 是.
public class MyList<T extends Number & Comparable<T>> {}
如果你可以排序,那么得到最小的就是直截了当:
public T smallest() {
// Don't mutate the order of the original array.
ArrayList<T> listCopy = new ArrayList<>(l);
Collections.sort(listCopy);
return listCopy.get(0);
}
通过这种方法获得最高我留作 reader 的练习。