通用方法参数 - Java

时间:2014-01-24 17:38:52

标签: java generics collections generic-collections

我有两个几乎相同的方法,但我正在努力避免代码重复。

每个人都将一个唯一的对象作为参数,并从中找出最高值。

以下是一个例子:

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但尚未使用泛型参数。

有没有办法解决这个问题?

5 个答案:

答案 0 :(得分:28)

可以将getAgetB合并为一个接口方法吗?

例如:

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)

如果你想使这个代码通用,那么使用整数的ArrayList进行实际比较可能不是一个好主意。如果其中一个对象是Long,大于你的最大整数怎么办?相反,您的对象必须以某种方式进行比较,因此您可以找到“最大值”(一组字符串的最大值是多少?)

所以我尝试这样的方法

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));
    }
}
相关问题