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(_name) + 37;
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 }
|