英文:
Java how to compare two generic type parameters
问题
import java.util.ArrayList;
public class MyList<T extends Number> {
private ArrayList<T> list;
public MyList() {
list = new ArrayList<T>();
}
public void add(T obj) {
list.add(obj);
}
public T largest() {
boolean onFirstObj = true;
T largestVal = null;
for (int i = 0; i < list.size(); i++) {
if (onFirstObj) {
largestVal = list.get(i);
onFirstObj = false;
}
else {
if (list.get(i).doubleValue() > largestVal.doubleValue()) {
largestVal = list.get(i);
}
}
}
return largestVal;
}
public T smallest() {
boolean onFirstObj = true;
T smallestVal = null;
for (int i = 0; i < list.size(); i++) {
if (onFirstObj) {
smallestVal = list.get(i);
onFirstObj = false;
}
else {
if (list.get(i).doubleValue() < smallestVal.doubleValue()) {
smallestVal = list.get(i);
}
}
}
return smallestVal;
}
}
Note: I've made changes to your code to properly compare and find the largest and smallest values using the doubleValue()
method for numeric comparison. Also, I initialized the largestVal
and smallestVal
variables to null
to handle potential cases where the list might be empty.
英文:
The problem is to write generic method, with T constrained to extends Number. Only have a single field variable ArrayList<T>. Have an add method that adds objects to the ArrayList, and then two methods, one that returns the largest in the ArrayList and the other the smallest. My problem is in the largest and smallest methods where I am comparing successive items in the list with each other searching for the largest and smallest, but they are of generic type T and I cannot use < and >, and compareTo() does not work either (I put both errors in the code provided). Can someone take a look and let me know where I am going wrong?
import java.util.ArrayList;
public class MyList<T extends Number> {
private ArrayList<T> list;
public MyList() {
list = new ArrayList<T>();
}
public void add(T obj) {
list.add(obj);
}
public T largest() {
boolean onFirstObj = true;
T largestVal;
for (int i = 0; i < list.size(); i++) {
if (onFirstObj) {
largestVal = list.get(i);
onFirstObj = false;
}
else {
if (list.get(i) > largestVal) {
largestVal = list.get(i);
}
}
}
return largestVal;
}
public T smallest() {
boolean onFirstObj = true;
T smallestVal;
for (int i = 0; i < list.size(); i++) {
if (onFirstObj) {
smallestVal = list.get(i);
onFirstObj = false;
}
else {
if (list.get(i).compareTo(smallestVal) < 0) {
smallestVal = list.get(i);
}
}
}
return smallestVal;
}
}
答案1
得分: 3
< 和 > 运算符只能用于原始类型,并且 `Number` 类本身没有实现 `Comparable` 接口,因此无法使用 compareTo 方法。
然而,如果将 `Comparable<T>` 添加为类型限定:
```java
public class MyList<T extends Number & Comparable<T>> {
...
}
那么您就可以使用 compareTo
方法:
public T largest() {
boolean onFirstObj = true;
T largestVal = null;
for (T t : list) {
if (onFirstObj) {
largestVal = t;
onFirstObj = false;
} else {
if (t.compareTo(largestVal) > 0) {
largestVal = t;
}
}
}
return largestVal;
}
<details>
<summary>英文:</summary>
The < and > operators can only be used with primitive types, and the `Number` class does not implement `Comparable` itself, so you can't use compareTo.
However if you add `Comparable<T>` as a type bound:
public class MyList<T extends Number & Comparable<T>> {
...
}
then you can use the `compareTo` method:
public T largest() {
boolean onFirstObj = true;
T largestVal = null;
for (T t : list) {
if (onFirstObj) {
largestVal = t;
onFirstObj = false;
} else {
if (t.compareTo(largestVal) > 0) {
largestVal = t;
}
}
}
return largestVal;
}
</details>
# 答案2
**得分**: 1
你可以这样做。
Number拥有用于访问原始值的方法(例如:doubleValue())。因此,你可以使用 doubleValue()
进行比较,从而处理整数和浮点数类型。
这是有效的,因为 int、double、float 和 long 方法
被声明为 abstract
,所以任何继承了 Number
的类都必须为它们提供实现。byteValue()
和 shortValue()
仅是调用 intValue()
并适当进行类型转换的方法。
如评论中所述,BigInteger 和 BigDecimal
可能具有超出 doubleValue
范围的精度,因此对于这些数据类型,这种解决方案注定会失败。
class MyList<T extends Number> {
private ArrayList<T> list;
public MyList() {
list = new ArrayList<T>();
}
public void add(T obj) {
list.add(obj);
}
public T largest() {
T largestVal = list.get(0);
for (int i = 1; i < list.size(); i++) {
if (list.get(i).doubleValue() > largestVal.doubleValue()) {
largestVal = list.get(i);
}
}
return largestVal;
}
public T smallest() {
T smallestVal = list.get(0);
for (int i = 1; i < list.size(); i++) {
if (list.get(i).doubleValue() < smallestVal.doubleValue()) {
smallestVal = list.get(i);
}
}
return smallestVal;
}
}
英文:
You could do it like this.
Number has the methods for accessing primitive values (e.g. doubleValue()). So you can use doubleValue()
for the compare to handle both integer and floating types.
It works because the int, double, float and long methods
are declared abstract
so any class that extends Number
must provide implementations for them. byteValue()
and shortValue()
are simply methods that call intValue()
and are cast appropriately.
As mentioned in the comments, BigInteger and BigDecimal
can have precisions that exceed what the doubleValue
can accommodate so for those datatypes this
solution is destined to fail.
class MyList<T extends Number> {
private ArrayList<T> list;
public MyList() {
list = new ArrayList<T>();
}
public void add(T obj) {
list.add(obj);
}
public T largest() {
T largestVal = list.get(0);
for (int i = 1; i < list.size(); i++) {
if (list.get(i).doubleValue() > largestVal.doubleValue()) {
largestVal = list.get(i);
}
}
return largestVal;
}
public T smallest() {
T smallestVal = list.get(0);
for (int i = 1; i < list.size(); i++) {
if (list.get(i).doubleValue() < smallestVal.doubleValue()) {
smallestVal = list.get(i);
}
}
return smallestVal;
}
}
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论