5

約 10 個以上のクラスがあり、それぞれに LUMP_INDEX と SIZE 静的定数があります。これらの各クラスの配列が必要です。配列のサイズは、これら 2 つの定数を使用して計算されます。現時点では、各クラスに配列を作成する関数があります。次のようなものです。

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 個ありますが、違いはクラスの型だけなので、ご覧のとおり、大量の重複があります。

この重複を回避する方法について何かアイデアはありますか? ありがとう。(以前も似たような質問をしたのですが、ちょっと言い方が違っていた気がします)

4

4 に答える 4

3

Java ジェネリックを使用します。そうすれば、ジェネリック メソッドを 1 つ記述し、それを使用するたびに型パラメーターを指定するだけで済みます。

于 2011-03-26T19:06:36.763 に答える
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); }
}
于 2011-03-26T19:36:59.153 に答える
1

わかりました...確認するためにこれをテストしましたが、あなたが探しているものを実行すると信じています.

インターフェースが必要です:

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 クラスから次のように呼び出すことができます。

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

は思う?:) 誰かがこれを見て、私がオフになっているかどうかを確認できますか?

編集:私は今それをテストしたので - それは動作します)

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

あなたのクラスの中から。ジェネリック型を提供するためにインターフェイスが空になるだけで、ゲッター メソッドを定義する必要はありません。

または(最後の編集をお約束しますが、これにより選択肢が与えられ、ジェネリックについて少し説明されます)

インターフェイスを捨てます。メソッドは与えられたオブジェクトのタイプを気にしないため、これによって削除されるのはいくつかの健全性チェックです。

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

インターフェイスを定義したり実装したりする必要はありません。次のように呼び出すだけです。

Plane p[] = header.getArray(Plane.class, SIZE, LUMP_INDEX);
于 2011-03-26T20:11:08.220 に答える
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();
}
于 2011-03-26T19:16:35.010 に答える