我有两个几乎相同的方法,但我正在努力避免代码重复。
每个人都将一个唯一的对象作为参数,并从中找出最高值。
以下是一个例子:
public Integer getHighestIndexValue(List<ObjectA> list) {
int highestValue;
List<Integer> indexes = new ArrayList<Integer>();
for (ObjectA a: list) {
indexes.add(Integer.parseInt(a.getA()));
}
highestValue = Collections.max(indexes);
return highestValue;
}
或者:
public Integer getHighestIndexValue(List<ObjectB> list) {
int highestValue;
List<Integer> indexes = new ArrayList<Integer>();
for (ObjectB b: list) {
indexes.add(Integer.parseInt(b.getB()));
}
highestValue = Collections.max(indexes);
return highestValue;
}
如何使用通用参数组合这两个?
我尝试创建一个包含这两个类的BaseClass
并将其扩展到方法签名中。还是需要铸造。
public <T extends BaseClass> Integer getHighestIndexValue(List<T> objectList) {
int highestValue;
List<Integer> indexes = new ArrayList<Integer>();
for (T objects: objectList) {
indexes.add(Integer.parseInt(objects.getAorB())); ------ this line needs casting
}
highestValue = Collections.max(indexes);
return highestValue;
}
我之前使用过Generics但尚未使用泛型参数。
有没有办法解决这个问题?
答案 0 :(得分:28)
可以将getA
和getB
合并为一个接口方法吗?
例如:
interface ProvidesIndex {
Integer getIndex();
}
现在,您只需致电getIndex
,您的方法签名就是:
public Integer getHighestIndexValue(List<? extends ProvidesIndex> list)
作为旁注,如果您将接口定义为扩展Comparable<ProvidesIndex>
,即:
interface ProvidesIndex extends Comparable<ProvidesIndex>
然后您可以直接在初始列表中使用Collections.max
:
List<ProvidesIndex> list = new ArrayList<ProvidesIndex>();
list.add(new ObjectA());
list.add(new ObjectB());
Integer max = Collections.max(list).getIndex();
答案 1 :(得分:4)
拉曼回答:
public Integer getHighestIndexValue(List<? extends CommonInterface> list) {
int highestValue;
List<Integer> indexes = new ArrayList<Integer>();
for (CommonInterface a: list) {
indexes.add(Integer.parseInt(a. getIndex()));
}
highestValue = Collections.max(indexes);
return highestValue;
}
答案 2 :(得分:3)
Guava有一个优雅的解决方案:
//general purpose function to get A, can be used in transform(), etc
private static final Function<ObjectA, Integer> GET_A = new Function<>() {
@Override
public Integer apply(ObjectA a) {
return a.getA();
}
}
Integer highestIndex = Collections.max(Collections2.transform(list, GET_A));
或者,如果您需要索引最高的元素,
ObjectA highest = Ordering.natural().onResultOf(GET_A).max(list);
然后将其扩展为ObjectB
,您只需要实现GET_B
函数。
回到你的助手方法(现在基本上无关紧要了):
public <T> Integer getHighestIndex(List<? extends T> list, Function<? super T, Integer> indexPlucker) {
return Collections.max(Collections2.transform(list, indexPlucker));
}
答案 3 :(得分:1)
您可以在一个Java命令中执行此操作。这是Java 5和更紧凑的Java 8:
public static class ObjectA {
public String getA() { return "1"; /* test */ }
}
public static class ObjectB {
public String getB() { return "1"; /* test */ }
}
// Java 5+ versions
public static void sampleA7(List<ObjectA> list) {
int maxValue = Integer.parseInt(Collections.max(list, new Comparator<ObjectA>() {
@Override
public int compare(ObjectA a, ObjectA b) {
return Integer.parseInt(a.getA()) - Integer.parseInt(b.getA());
}
}).getA());
}
public static void sampleB7(List<ObjectB> list) {
int maxValue = Integer.parseInt(Collections.max(list, new Comparator<ObjectB>() {
@Override
public int compare(ObjectB a, ObjectB b) {
return Integer.parseInt(a.getB()) - Integer.parseInt(b.getB());
}
}).getB());
}
// Java 8+ versions
public static void sampleA8(List<ObjectA> list) {
Optional<Integer> maxValue = list.stream().map(a -> Integer.parseInt(a.getA())).max((a, b) -> a - b);
}
public static void sampleB8(List<ObjectB> list) {
Optional<Integer> maxValue = list.stream().map(a -> Integer.parseInt(a.getB())).max((a, b) -> a - b);
}
答案 4 :(得分:1)
所以我尝试这样的方法
import java.util.List;
public abstract class MathMax<E> {
public abstract boolean isGreaterThan(E x1, E x2);
public E getHighestIndexValue(List<E> list){
E highestValue = null;
for (E a: list) {
if (isGreaterThan(a,highestValue)){
highestValue = a;
}
}
return highestValue;
}
}
和
import java.util.ArrayList;
import java.util.List;
public class MathMaxA extends MathMax<ObjectA> {
@Override
public boolean isGreaterThan(ObjectA x1, ObjectA x2) {
// do your comparison here, careful with null values
return false;
}
public static void main(String[] args) {
MathMaxA m = new MathMaxA();
List<ObjectA> list = new ArrayList<ObjectA>();
System.out.println(m.getHighestIndexValue(list));
}
}