簡體   English   中英

通用方法參數 - Java

[英]Generic method arguments - Java

我有兩個幾乎相同的方法,但我試圖避免代碼重復。

它們中的每一個都將一個唯一的對象作為參數,並從中找出最高的值。

這是一個例子:

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

有辦法解決這個問題嗎?

可以將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();

拉曼補充說:

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;
}

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));
}

您可以在一個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);
}

如果你想使這個代碼通用,那么使用整數的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));
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM