如何以更简单的方式使用泛型定义/实现此接口?

时间:2010-11-29 13:44:36

标签: java

我正在使用遗传算法,我希望它尽可能抽象,以便能够重用GA。我定义并实现了一个人口界面,它很有效,但我确信这不是最好的方法。我没有Java Generics的丰富经验。是否有更简单的方法来定义和实现Population接口(例如,可以避免转换转换?避免在getChromosomes()中使用新列表?)

public interface Population
{
    void addChromosomes(List<? extends Chromosome> chromosomes);

    List<Chromosome> getChromosomes();

    // More code here ...
}

public class TSPPopulation implements Population
{
    private List<TSPChromosome> chromosomes;

    @Override
    public void addChromosomes(List<? extends Chromosome> chromosomes) {
        for (Chromosome chromosome : chromosomes) {
            this.chromosomes.add((TSPChromosome) chromosome);
        }
    }

    @Override
    public List<Chromosome> getChromosomes() {
        List<Chromosome> newList = new ArrayList<Chromosome>();
        for (TSPChromosome chromosome : chromosomes) {
            newList.add(chromosome);
        }
        return newList;
    }
}

5 个答案:

答案 0 :(得分:7)

在界面中使用有界通配符:

public interface Population<T extends Chromosome>{
    void addChromosomes(List<T> chromosomes);

    List<T> getChromosomes();
}

public class TSPPopulation implements Population<TSPChromosome>
{
    private List<TSPChromosome> chromosomes;

    @Override
    public void addChromosomes(List<TSPChromosome> chromosomes) {
...
    }

    @Override
    public List<TSPChromosome> getChromosomes() {
...    
    }

}

答案 1 :(得分:2)

最简单的解决方案是扩展列表(然后使用addAll(...)将Chromosoms列表添加到列表中):

class Population<T extends Chromosome> extends ArrayList<T> {
}

但是如果你想要相同的结构,我会将Population变成通用列表类。这样,add...get...方法都可以在通用基类中处理。如果您确实要覆盖任何其他功能,只需展开Populationclass TSPPopulation extends Population<TSPChromosome>

用法:

public static void main(String... args) {
    Population<TSPChromosome> tspPopulation = new Population<TSPChromosome>();
    ... 
}

实现:

class Population<T extends Chromosome> {

    private List<T> chromosomes = new ArrayList<T>();

    public void addChromosomes(List<T> chromosomes) {
        this.chromosomes.addAll(chromosomes);
    }

    public List<T> getChromosomes() {
        return new ArrayList<T>(this.chromosomes);
    }
}

答案 2 :(得分:1)

如果你自己制作人口通用会更安全:

public interface Population<T extends Chromosome> {

    void addChromosomes(List<T> chromosomes);

    List<T> getChromosomes();

}

public class TspPopulation implements Population<TspChromosome>{

    @Override
    public void addChromosomes(List<TspChromosome> chromosomes){
        // 
    }

    @Override
    public List<TspChromosome> getChromosomes(){
        //
    }

}

这样你就不需要在客户端代码中进行任何转换。

答案 3 :(得分:1)

我知道GA,我会质疑你的Population实现是否真的需要知道你放入了哪种Chromosome。你真的有不同的Population实现,具体取决于{ {1}}子类?或者您真正想要的是确保Chromosome中的Chromosome子类相同?在最后一种情况下,您可以像其他人建议的那样定义Population接口,并创建一个通用实现(或者完全跳过接口):

Population

小心不要放太多的仿制品,否则你最终会遇到仿制药的地狱,或者大量的演员阵容会让仿制品更加烦人而不是有用。

答案 4 :(得分:0)

是的,例如:

public interface Population<T extends Chromosome>
{
    void addChromosomes(List<T> chromosomes);

    List<T> getChromosomes();

    // More code here ...
}

public class TSPPopulation implements Population<TSPChromosome>
{
    private List<TSPChromosome> chromosomes;

    @Override
    public void addChromosomes(List<TSPChromosome> chromosomes) {
        this.chromosomes.addAll(chromosomes);
    }

    @Override
    public List<TSPChromosome> getChromosomes() {
        return new ArrayList<TSPChromosome>(chromosomes);
    }
}