| 
001 /*002  * Java Genetic Algorithm Library (jenetics-3.0.0).
 003  * Copyright (c) 2007-2014 Franz Wilhelmstötter
 004  *
 005  * Licensed under the Apache License, Version 2.0 (the "License");
 006  * you may not use this file except in compliance with the License.
 007  * You may obtain a copy of the License at
 008  *
 009  *      http://www.apache.org/licenses/LICENSE-2.0
 010  *
 011  * Unless required by applicable law or agreed to in writing, software
 012  * distributed under the License is distributed on an "AS IS" BASIS,
 013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 014  * See the License for the specific language governing permissions and
 015  * limitations under the License.
 016  *
 017  * Author:
 018  *    Franz Wilhelmstötter (franz.wilhelmstoetter@gmx.at)
 019  */
 020 package org.jenetics;
 021
 022 import static java.util.Objects.requireNonNull;
 023 import static org.jenetics.internal.util.Equality.eq;
 024
 025 import java.util.Iterator;
 026 import java.util.Objects;
 027 import java.util.RandomAccess;
 028
 029 import org.jenetics.internal.util.Equality;
 030 import org.jenetics.internal.util.Hash;
 031 import org.jenetics.internal.util.reflect;
 032
 033 import org.jenetics.util.ISeq;
 034 import org.jenetics.util.Verifiable;
 035
 036 /**
 037  * The abstract base implementation of the Chromosome interface. The implementors
 038  * of this class must assure that the protected member {@code _genes} is not
 039  * {@code null} and the length of the {@code genes} > 0.
 040  *
 041  * @param <G> the gene type.
 042  *
 043  * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
 044  * @since 1.0
 045  * @version 2.0 — <em>$Date: 2014-12-28 $</em>
 046  */
 047 public abstract class AbstractChromosome<G extends Gene<?, G>>
 048     implements
 049         Chromosome<G>,
 050         RandomAccess
 051 {
 052     private static final long serialVersionUID = 1;
 053
 054     /**
 055      * Array of genes which forms the chromosome. This array must
 056      * be initialized by the derived classes.
 057      */
 058     protected transient ISeq<G> _genes = null;
 059
 060     /**
 061      * Indicates whether this chromosome is valid or not. If the variable is
 062      * {@code null} the validation state hasn't been calculated yet.
 063      */
 064     protected transient Boolean _valid = null;
 065
 066     /**
 067      * Create a new {@code AbstractChromosome} from the given {@code genes}
 068      * array. The genes array is not copied, but sealed, so changes to the given
 069      * genes array doesn't effect the genes of this chromosome.
 070      *
 071      * @param genes the genes that form the chromosome.
 072      * @throws NullPointerException if the given gene array is {@code null}.
 073      * @throws IllegalArgumentException if the length of the gene array is
 074      *          smaller than one.
 075      */
 076     protected AbstractChromosome(final ISeq<? extends G> genes) {
 077         requireNonNull(genes, "Gene array");
 078         assert (genes.forAll(Objects::nonNull)) : "Found at least on null gene.";
 079
 080         if (genes.length() == 0) {
 081             throw new IllegalArgumentException(
 082                 "The genes sequence must contain at least one gene."
 083             );
 084         }
 085
 086         _genes = reflect.cast(genes);
 087     }
 088
 089     @Override
 090     public G getGene(final int index) {
 091         return _genes.get(index);
 092     }
 093
 094     @Override
 095     public ISeq<G> toSeq() {
 096         return _genes;
 097     }
 098
 099     @Override
 100     public boolean isValid() {
 101         if (_valid == null) {
 102             _valid = _genes.forAll(Verifiable::isValid);
 103         }
 104
 105         return _valid;
 106     }
 107
 108     @Override
 109     public Iterator<G> iterator() {
 110         return _genes.iterator();
 111     }
 112
 113     @Override
 114     public int length() {
 115         return _genes.length();
 116     }
 117
 118     @Override
 119     public int hashCode() {
 120         return Hash.of(getClass()).and(_genes).value();
 121     }
 122
 123     @Override
 124     public boolean equals(final Object obj) {
 125         return Equality.of(this, obj).test(ch -> eq(_genes, ch._genes));
 126     }
 127
 128     @Override
 129     public String toString() {
 130         return _genes.toString();
 131     }
 132
 133 }
 |