2010-11-29 35 views
1

我正在使用遗传算法,我希望它尽可能抽象以重用遗传算法。我定义并实现了一个人口接口,它的工作原理很好,但我相信这不是最好的方法。我对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; 
    } 
} 
+1

好老AI,我记得几年前写了一个类似于这个的代码。 – 2010-11-29 14:05:27

回答

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

} 
+0

为什么不在界面中实现这些功能(例如,把它变成一个类...)? – dacwe 2010-11-29 14:08:55

+0

@dacwe:我不明白? (你不能在界面中实现任何东西 - 但我相信这不是你的意思。) – Ralph 2010-11-29 14:20:33

+0

我的意思是说`addChromosoms(..)`和`getChromosoms()`可以被抽象基类处理。 (看我的解决方案) – dacwe 2010-11-29 14:22:26

2

最简单的办法是扩大列表(然后使用addAll(...)到Chromosoms列表添加到列表):

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

但是,如果你想的一样ST我会使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); 
    } 
} 
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); 
    } 
} 
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(){ 
     // 
    } 

} 

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

1

我知道气,我会质疑你的Population的实施是否真的需要知道你把哪一种Chromosome。切勿你真的有不同Population的实现取决于Chromosome子类?或者你真正想要的是确保你在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); 
    } 
} 

要小心,不要放太多的仿制药,否则会落得与泛型地狱,或铸造将使泛型更恼人,而不是有用的吨铸造。

相关问题