我正在使用遗传算法,我希望它尽可能抽象,以便能够重用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;
}
}
答案 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...
方法都可以在通用基类中处理。如果您确实要覆盖任何其他功能,只需展开Population
(class 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);
}
}