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