重复数据消除此java代码重复

重复数据消除此java代码重复,java,code-duplication,deduplication,Java,Code Duplication,Deduplication,我有大约10+个类,每个类都有一个LUMP_索引和大小静态常量。 我想要每个类的数组,其中数组的大小是使用这两个常量计算的。 目前,我为每个类创建了一个函数来创建数组,大致如下: private Plane[] readPlanes() { int count = header.lumps[Plane.LUMP_INDEX].filelen / Plane.SIZE; Plane[] planes = new Plane[count]; for(int i = 0; i

我有大约10+个类,每个类都有一个LUMP_索引和大小静态常量。 我想要每个类的数组,其中数组的大小是使用这两个常量计算的。 目前,我为每个类创建了一个函数来创建数组,大致如下:

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;
}
专用平面[]读平面()
{
int count=header.lumps[Plane.LUMP\u INDEX].filelen/Plane.SIZE;
平面[]平面=新平面[计数];
for(int i=0;i
等等。 其中有10个函数,唯一的区别是类类型,所以正如您所看到的,有大量的重复

有人对如何避免这种重复有什么想法吗? 谢谢
(我以前问过类似的问题,但我想我问的方式有点不对劲)

使用。这样,您可以只编写一个泛型方法,并在每次使用时指定一个类型参数。

使用泛型,但您需要传入某种类型的factory对象来构造实例以放入集合中,例如:

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();
}
公共类MyClass{
public E[]getArray(IObjectFactory生成器,int索引,int大小){
ArrayList ArrayList=新的ArrayList();
int count=header.lumps[index].filelen/size;//头不是从哪里来的。。。
for(int i=0;i
巴拉的解决方案很接近。但是,您无法从泛型类型访问常量,因此我将创建一个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); }
}
接口集总化{
int getCount();//子类型返回适当的头。lumps[Plane.LUMP_INDEX].filelen/Plane.SIZE;
T[]初始化array();
抽象静态类基类实现了集总化{
受保护的T[]初始值设定RAY(类别cls){
int count=getCount();
T[]lumps=(T[])Array.newInstance(cls,count);
for(int i=0;i
好的,多克。。。我已经测试过了,我相信它能满足你的需求

您需要一个接口:

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

}
您的类实现该接口:

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;
}
我想……)谁能看看这个,看看我是不是走了

编辑:因为我现在已经对它进行了测试-这很有效)

另外,您可以通过使
getArray()
将大小和索引作为参数来消除每个类中的getter:

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;
}
从你的课堂里。接口只是变为空以提供泛型类型,您不必定义getter方法

(我保证最后一次编辑,但这确实给了您一些选择,并解释了一些泛型)

放弃接口。这将删除一些健全性检查,因为该方法不关心您给它的对象类型:

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

你的意思是用一些像私人的虚空阅读(课堂教学)?我无法通过clazz参数访问这两个常量。请注意,您不能使用泛型执行
newt[x]
。你可以绕开它,但答案并不是那么简单。@Brian Roach:那就给点提示吧?泛型容器?@Bala的泛型示例展示了如何解决
T[]
问题。个人我想我应该使用一种结合了
ArrayList
的方法,而不是直接使用数组。在void方法中有返回语句?这些方法中的
头对象是什么?为什么不使用ArrayList?你误读了代码。它是您扩展的抽象基类,例如,
类平面扩展了LumpySize.base
+1。是的。这是将依赖于实现的常量放入通用代码的方法。知道很有用。是的。。。我只是不知道我喜欢它。您可以在接口之外轻松地定义同一个抽象类,实际上不需要它,因为
可以封装所有功能。每个类(平面、节点等)的数学运算仍在进行中。我处理它的方式将所有这些都转移到类中,
header
是一个实例。谢谢,我认为这可能是最好的方法(除了getArray函数不需要在header中)。然而,当我尝试时,c.newInstance()抛出了一个InstanceException,我不知道为什么,所以我很困惑。你从来没有公布过你的对象的构造函数是什么。你有无参数构造函数吗?是的,他们没有参数。我已经弄明白了为什么它会抛出异常。谢谢
Plane p[] = header.getArray(Plane.class, SIZE, LUMP_INDEX);