EphemeralConst.java
001 /*
002  * Java Genetic Algorithm Library (jenetics-4.3.0).
003  * Copyright (c) 2007-2018 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@gmail.com)
019  */
020 package io.jenetics.prog.op;
021 
022 import static java.lang.String.format;
023 import static java.util.Objects.requireNonNull;
024 import static io.jenetics.internal.util.Hashes.hash;
025 
026 import java.io.Serializable;
027 import java.util.Objects;
028 import java.util.function.Supplier;
029 
030 import io.jenetics.internal.util.Lazy;
031 
032 /**
033  * Implementation of an <em>ephemeral</em> constant. It causes the insertion of
034  * a <em>mutable</em> constant into the operation tree. Every time this terminal
035  * is chosen a, different value is generated which is then used for that
036  * particular terminal, and which will remain fixed for the given tree. The main
037  * usage would be to introduce random terminal values.
038  *
039  <pre>{@code
040  * final Random random = ...;
041  * final Op<Double> val = EphemeralConst.of(random::nextDouble());
042  * }</pre>
043  *
044  *  @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
045  @version 4.1
046  @since 3.9
047  */
048 public final class EphemeralConst<T> implements Op<T>, Serializable {
049 
050     private static final long serialVersionUID = 1L;
051 
052     private final String _name;
053     private final Supplier<T> _supplier;
054     private final Lazy<T> _value;
055 
056     private EphemeralConst(final String name, final Supplier<T> supplier) {
057         _name = name;
058         _supplier = requireNonNull(supplier);
059         _value = Lazy.of(_supplier);
060     }
061 
062     @Override
063     public String name() {
064         return _name;
065     }
066 
067     @Override
068     public int arity() {
069         return 0;
070     }
071 
072     /**
073      * Return a newly created, uninitialized constant of type {@code T}.
074      *
075      @return a newly created, uninitialized constant of type {@code T}
076      */
077     @Override
078     public Op<T> get() {
079         return new EphemeralConst<>(_name, _supplier);
080     }
081 
082     @Override
083     public T apply(final T[] ts) {
084         return _value.get();
085     }
086 
087     @Override
088     public int hashCode() {
089         return hash(_name, hash(_value));
090     }
091 
092     @Override
093     public boolean equals(final Object obj) {
094         return obj == this ||
095             obj instanceof EphemeralConst &&
096             Objects.equals(((EphemeralConst)obj)._name, _name&&
097             Objects.equals(((EphemeralConst)obj)._value, _value);
098     }
099 
100     @Override
101     public String toString() {
102         return _name != null
103             ? format("%s(%s)", _name, _value.get())
104             : Objects.toString(_value.get());
105     }
106 
107     /**
108      * Create a new ephemeral constant with the given {@code name} and value
109      * {@code supplier}. For every newly created operation tree, a new constant
110      * value is chosen for this terminal operation. The value is than kept
111      * constant for this tree.
112      *
113      @param name the name of the ephemeral constant
114      @param supplier the value supplier
115      @param <T> the constant type
116      @return a new ephemeral constant
117      @throws NullPointerException if one of the arguments is {@code null}
118      */
119     public static <T> EphemeralConst<T> of(
120         final String name,
121         final Supplier<T> supplier
122     ) {
123         return new EphemeralConst<>(requireNonNull(name), supplier);
124     }
125 
126     /**
127      * Create a new ephemeral constant with the given value {@code supplier}.
128      * For every newly created operation tree, a new constant value is chosen
129      * for this terminal operation. The value is than kept constant for this tree.
130      *
131      @param supplier the value supplier
132      @param <T> the constant type
133      @return a new ephemeral constant
134      @throws NullPointerException if the {@code supplier} is {@code null}
135      */
136     public static <T> EphemeralConst<T> of(final Supplier<T> supplier) {
137         return new EphemeralConst<>(null, supplier);
138     }
139 
140 }