繁体   English   中英

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

[英]How to define/implement this interface with generics in a simpler way?

我正在研究遗传算法,我希望它尽可能抽象,以便能够重用GA。 我定义并实现了一个人口接口,并且很好地工作了,但是我敢肯定这不是最好的方法。 我没有Java泛型的丰富经验。 有没有更简单的方法来定义和实现人口接口(例如,避免强制转换?避免在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;
    }
}

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

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() {
...    
    }

}

最简单的解决方案是扩展列表(然后使用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);
    }
}

如果您将“人口”设为通用,那将更加安全:

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(){
        //
    }

}

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

我知道GA,并且我会问您的“ Population实施方案是否实际上需要知道您所放入的哪种Chromosome 。根据“ Chromosome子类,您是否真的有不同的“ Population实施方案? 或者,您真正想要的是确保Population具有相同的Chromosome子类? 在后一种情况下,您可以按照其他建议的方式定义“ Population接口,并进行通用实现(或完全跳过该接口):

public class PopulationImpl implements Population<T extends Chromosome> {
    private List<T> chromosomes;

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

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

注意不要放置太多的泛型,否则最终将导致泛型地狱,或大量的强制转换,这将使泛型变得更烦人而不是有用。

是的,例如:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM