2011-03-26 66 views
5

我有大約10多個類,每個類都有一個LUMP_INDEX和SIZE靜態常量。 我想要這些類中的每一個的數組,其中使用這兩個常量來計算數組的大小。 目前我有一個函數爲每個類創建陣列,沿着線的東西:重複此java代碼複製

private Plane[] readPlanes() 
{ 
    int count = header.lumps[Plane.LUMP_INDEX].filelen/Plane.SIZE; 
    Plane[] planes = new Plane[count]; 
    for(int i = 0; i < count; i++) 
     planes[i] = new Plane(); 

    return planes; 
} 

private Node[] readNodes() 
{ 
    int count = header.lumps[Node.LUMP_INDEX].filelen/Node.SIZE; 
    Node[] nodes = new Node[count]; 
    for(int i = 0; i < count; i++) 
     nodes[i] = new Node(); 

    return nodes; 
} 

private Leaf[] readLeaves() 
{ 
    int count = header.lumps[Leaf.LUMP_INDEX].filelen/Leaf.SIZE; 
    Leaf[] leaves = new Leaf[count]; 
    for(int i = 0; i < count; i++) 
     leaves[i] = new Leaf(); 

    return leaves; 
} 

等 有這些功能中的10,唯一的差別是類的類型,從而你可以看到,有很多重複。

有沒有人有任何想法如何避免這種重複? 謝謝。 (我之前問過類似的問題,但我猜我的方式有點偏離)

+0

你在void方法中有return語句嗎? – 2011-03-26 19:21:24

+0

這些方法中的'header'對象是什麼? – 2011-03-26 19:36:05

+0

爲什麼不使用ArrayList? – bancer 2011-03-26 21:25:08

回答

1

Okey doke ...我已經測試了這個以確保它,並且我相信它能做到您要找的。

您需要的接口:

public interface MyInterface 
{ 
    public int getSize(); 
    public int getLumpIndex(); 
} 

你的類實現該接口:

public class Plane implements MyInterface 
{ 

    ... 
    public int getSize() 
    { 
     return SIZE; 
    } 

    public int getLumpIndex() 
    { 
     return LUMP_INDEX; 
    } 

} 

在類header是,你有一個實例...

public <E extends MyInterface> E[] 
    getArray(Class<E> c, MyInterface foo) 
{ 
    int count = lumps[foo.getLumpIndex()].filelen/foo.getSize(); 
    E[] myArray = (E[]) Array.newInstance(c, count); 
    for(int i = 0; i < count; i++) 
     myArray[i] = c.newInstance(); 
    return myArray; 
} 

你可以說,你的飛機班如下:

Plane[] p = header.getArray(Plane.class, this); 

認爲? :)有人可以看看這個,看看我是否關閉?

編輯: Becasue我現在已經測試了它 - 這工作)

在附加的註釋,你可以通過使getArray()採取的規模和指標作爲參數消除每一類干將:

public <E extends MyInterface> E[] 
    getArray(Class<E> c, int size, int index) 
{ 
    int count = lumps[index].filelen/size; 
    E[] myArray = (E[]) Array.newInstance(c, count); 
    for(int i = 0; i < count; i++) 
     myArray[i] = c.newInstance(); 
    return myArray; 
} 

,並調用它爲:

Plane p[] = header.getArray(Plane.class, SIZE, LUMP_INDEX); 

從你的類裏面。接口只是變空以提供泛型類型,而不必定義getter方法。

OR(最後編輯我答應了,但是這確實給你的選擇,並解釋了一些關於仿製藥)

溝的接口。這是什麼去除一些健全檢查,因爲該方法不關心你給什麼類型的對象是:

public <E> E[] 
    getArray(Class<E> c, int size, int index) 
{ 
    ... 

現在,你不必定義接口或者實現它,你只要致電:

Plane p[] = header.getArray(Plane.class, SIZE, LUMP_INDEX); 
+0

謝謝,我認爲這可能是最好的方法(除了getArray函數不需要在頁眉內)。然而,當我嘗試它,c.newInstance()拋出一個InstantiationException,我不知道爲什麼,所以我很難過。 – terryhau 2011-03-27 04:20:35

+0

你從來沒有發佈你的構造函數是你的對象。你有沒有參數的構造函數? – 2011-03-27 04:22:56

+0

是的,他們沒有任何爭論。我想出了爲什麼拋出異常。謝謝 – terryhau 2011-03-27 05:18:00

3

使用Java generics。這樣,您可以只編寫一個泛型方法,並在每次使用時指定一個類型參數。

+0

你的意思是像私人無效閱讀(類 clazz)?我無法通過clazz參數訪問2個常量。 – terryhau 2011-03-26 19:10:18

+2

請注意,您不能使用泛型來執行'new T [x]'。你可以繞過它,但答案並不那麼簡單。 – 2011-03-26 19:13:42

+0

@布萊恩羅奇:提示什麼使用呢?通用容器? – xtofl 2011-03-26 19:15:32

0

使用泛型,但你需要在某種工廠對象傳遞給構建實例放入您的收藏中,如:

public class MyClass { 

public <E> E[] getArray(IObjectFactory builder, int index, int size){ 
    ArrayList<E> arrayList = new ArrayList<E>(); 
    int count = header.lumps[index].filelen/size;//wasn'tsure where header was coming from... 
    for(int i = 0; i< count; i++){ 
     E newInstance = builder.getNewInstance(); 
     arrayList.add(newInstance); 
    } 
    return (E[]) arrayList.toArray(); 
    } 
}  

interface IObjectFactory { 
<E> E getNewInstance(); 
} 
2

巴拉的解決方案是密切。儘管你不能訪問泛型類型的常量,所以我會創建一個getCount()(或者任何你想命名它的東西),並讓每個子類型用適當的常量來實現它。

interface LumpySize<L extends LumpySize> { 
    int getCount(); // subtypes return the appropriate header.lumps[Plane.LUMP_INDEX].filelen/Plane.SIZE; 

    T[] initializeArray(); 

    abstract <T extends LumpySize> static class Base implements LumpySize<T> { 
     protected T[] initializeArray(Class<T> cls) { 
      int count = getCount(); 
      T[] lumps = (T[]) Array.newInstance(cls, count); 
      for(int i = 0; i < count; i++) { 
       try { 
        lumps[i] = cls.newInstance(); 
       } catch (Exception e) { // obviously this isn't good practice. 
        throw new RuntimeException(e); 
       } 
      } 
      return lumps; 
     }  
    }    
} 

class Plane extends LumpySize.Base<Plane> { 
    public int getCount() { 
     return header.lumps[Plane.LUMP_INDEX].filelen/Plane.SIZE; // assuming header is available somewhere 
    } 
    public Plane[] initializeArray() { return initializeArray(Plane.class); } 
} 
+0

您誤解了代碼。它是一個抽象基類,可以擴展,例如'class Plane extends LumpySize.Base '。 – 2011-03-26 19:53:55

+0

Doh,對不起 - 我誤解了它。刪除我的評論。 – 2011-03-26 19:55:17

+0

+1。是的。這是將實現相關常量變爲泛型代碼的方式。非常有用的知道。 – extraneon 2011-03-26 20:35:37