"Universelle" Datenstruktur anlegen

Hallo,

wenn du eine Generics basierte Implementierung verwendest musst du darauf auf passen, dass die Performance nicht zu sehr unter dem impliziten Auto Boxing leidet...
Hier würde es sich schon anbieten getypte Indivdual Klassen (wie du schon gemacht hast) anzulegen. Eine weitere Implementierungsmöglichkeit könnte man auf einem Direct ByteBuffer anstatt eines einfachen Arrays aufbauen. Das wär nochmal ein wenig schneller (IMHO).

Ansonsten hier noch eine generische Version von Individual:

Java:
/**
 * 
 */
package de.tutorials;

import java.lang.reflect.Array;
import java.lang.reflect.ParameterizedType;

/**
 * @author Thomas.Darimont
 */
public class IndividualExample {
  public static void main(String[] args) {
    Individual<Integer> individual0 = new Individual<Integer>(5) {
    };
    individual0.set(0, 1);
    individual0.set(1, 2);
    individual0.set(2, 3);
    individual0.set(3, 4);
    individual0.set(4, 5);
    System.out.println(individual0);

    Individual<Integer> individual1 = new Individual<Integer>(new Integer[] { 1, 2, 3, 4, 5 });
    System.out.println(individual1);

  }

  static class Individual<TGenoType> implements Comparable<Individual<TGenoType>> {
    double fitness;
    int size;
    Class<?> type;
    TGenoType[] genoType;


    @SuppressWarnings("unchecked")
    public Individual(int size) {
      this.size = size;
      this.type = (Class<?>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
      this.genoType = (TGenoType[]) Array.newInstance(this.type, size);
    }


    public Individual(TGenoType[] genoType) {
      this.genoType = genoType;
      this.size = genoType.length;
      type = genoType.getClass().getComponentType();
    }


    public double getFitness() {
      return fitness;
    }


    public void setFitness(double fitness) {
      this.fitness = fitness;
    }


    public TGenoType get(int index) {
      return this.genoType[index];
    }


    public void set(int index, TGenoType value) {
      this.genoType[index] = value;
    }


    public TGenoType[] get() {
      return this.genoType;
    }


    public void set(TGenoType[] genoType) {
      this.genoType = genoType;
    }


    public int getSize() {
      return size;
    }


    public void setSize(int size) {
      this.size = size;
    }


    public int compareTo(Individual<TGenoType> o) {
      return (int) (getFitness() - o.getFitness());
    }


    @Override
    public String toString() {
      StringBuilder stringBuilder = new StringBuilder();
      int currentIndex = 0;
      for (TGenoType genoType : this.genoType) {
        stringBuilder.append(genoType);
        if ( ++currentIndex < this.genoType.length) {
          stringBuilder.append(",");
        }
      }
      return stringBuilder.toString();
    }
  }
}

Gruß Tom
 
Ich habe die IndividualKlasse so übernommen wie von Thomas geschrieben. Nun wollte ich den Genotyp in einer Enumeration ablegen und dann "dynamisch" beim Erzeugen des Individual-Objekts sagen zu können, dass der Genotyp Double oder Integer etc. sein kann.

Enum soll in etwa so aussehen:
Java:
public enum Genotype {
	Binary("Binary String",Boolean.class), 
	Real("Real Value String",Double.class);
private String name;
private Object dataType = null;
Genotype(String name,Object dataType){
		this.name = name;
		this.dataType = dataType;
	...
   public Object getDataType(){
   return datatype;}
...
Der zweite Parameter is nur beispielhaft. Kann also zur Lösung des Problems geändert werden falls nötig.

Beispiel: nichtdynamisch sieht es wie folgt aus ->
Java:
Individual<Boolean> ind = new Individual<Boolean>(16);
dynamisch ->
Java:
Individual<Boolean> ind = new Individual<genotype.getDataType()>(16);

Kann mir jemand bitte erklären / zeigen wie ich die Enumeration bzw. die getDataType-Methode konstruieren muss?
 
Zuletzt bearbeitet:
Generics sind nicht meine Lieblinge, also bitte berichtigt mich, wenn ich jetzt was falsches Schreibe.

Aber ist es in Java denn nicht so, dass alle Datentypen zur "Kompilierzeit" bekannt sein müssen?

Demzufolge würde das was du vorhast (den Datentyp des Generic vom Programm selbst bestimmten zu lassen) so nicht funktionieren, sondern du müsstest mit "instance of" überprüfen welches Generic GENAU denn nun angelegt werden soll.

Aber da bin ich mir jetzt nicht mehr sicher und bin auf weitere Kommentare gespannt.
 
Zurück