2014-01-24 60 views
14

我有兩個幾乎相同的方法,但我試圖避免代碼重複。通用方法參數 - 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; 

} 

我以前使用過泛型但尚未使用泛型參數。

有沒有解決這個辦法嗎?

+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(); 
+2

同意;由於方法名稱不同,使用泛型不能解決您的問題。 ObjectA和ObjectB需要有一些通用的接口。 – bstempi

+1

羅馬,你的筆記關於Comparable是好的,加上Comparator也是完整的... – Betlista

+1

@Raman這更好...謝謝兄弟... –

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

想法(與比較器)很好,實現不是,返回最大對象不是int,但是它是http://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#max(java.util.Collection,java.util.Comparator) – Betlista

+0

不要使用'Integer.parseInt(a.getB()) - Integer.parseInt(b.getB())',但是http://docs.oracle.com/javase/7/docs/api/java/lang/Integer。 html#compare(int,int)我認爲OP的索引不是你認爲的... – Betlista

+0

@Betista你是對的,索引是對象A和對象B中的一個變量。它可能類似於1 - 400用戶通過用戶界面 –

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

還是更好些?擴展CommonInterface> – user1428716

+0

-1:沒有'getIndex()'對象類 – Betlista

+0

@Betlista - 修改..謝謝 – user1428716

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