001/* 002 * Java Genetic Algorithm Library (jenetics-7.2.0). 003 * Copyright (c) 2007-2023 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 */ 020package io.jenetics.util; 021 022import static java.lang.String.format; 023import static io.jenetics.internal.util.Hashes.hash; 024import static io.jenetics.internal.util.SerialIO.readLong; 025import static io.jenetics.internal.util.SerialIO.writeLong; 026 027import java.io.DataInput; 028import java.io.DataOutput; 029import java.io.IOException; 030import java.io.InvalidObjectException; 031import java.io.ObjectInputStream; 032import java.io.Serial; 033import java.io.Serializable; 034import java.util.stream.LongStream; 035 036/** 037 * Long range class. 038 * 039 * @implNote 040 * This class is immutable and thread-safe. 041 * 042 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a> 043 * @version 6.0 044 * @since 3.2 045 */ 046public final /*record*/ class LongRange implements Serializable { 047 048 @Serial 049 private static final long serialVersionUID = 2L; 050 051 private final long _min; 052 private final long _max; 053 054 private LongRange(final long min, final long max) { 055 if (min > max) { 056 throw new IllegalArgumentException(format( 057 "Min greater than max: %s > %s", min, max 058 )); 059 } 060 061 _min = min; 062 _max = max; 063 } 064 065 /** 066 * Return the minimum value of the long range. 067 * 068 * @return the minimum value of the long range 069 */ 070 public long min() { 071 return _min; 072 } 073 074 /** 075 * Return the maximum value of the long range. 076 * 077 * @return the maximum value of the long range 078 */ 079 public long max() { 080 return _max; 081 } 082 083 /** 084 * Returns a sequential ordered {@code LongStream} from {@link #min()} 085 * (inclusive) to {@link #max()} (exclusive) by an incremental step of 086 * {@code 1}. 087 * <p> 088 * An equivalent sequence of increasing values can be produced sequentially 089 * using a {@code for} loop as follows: 090 * <pre>{@code 091 * for (long i = range.min(); i < range.max(); ++i) { 092 * ... 093 * } 094 * }</pre> 095 * 096 * @since 3.4 097 * 098 * @return a sequential {@link LongStream} for the range of {@code long} 099 * elements 100 */ 101 public LongStream stream() { 102 return LongStream.range(_min, _max); 103 } 104 105 /** 106 * Create a new {@code LongRange} object with the given {@code min} and 107 * {@code max} values. 108 * 109 * @param min the lower bound of the long range 110 * @param max the upper bound of the long range 111 * @return a new {@code LongRange} object 112 * @throws IllegalArgumentException if {@code min > max} 113 */ 114 public static LongRange of(final long min, final long max) { 115 return new LongRange(min, max); 116 } 117 118 /** 119 * Return a new (half-open) range, which contains only the given value: 120 * {@code [value, value + 1)}. 121 * 122 * @since 4.0 123 * 124 * @param value the value of the created (half-open) integer range 125 * @return a new (half-open) range, which contains only the given value 126 */ 127 public static LongRange of(final long value) { 128 return of(value, value + 1); 129 } 130 131 @Override 132 public int hashCode() { 133 return hash(_min, hash(_max, hash(getClass()))); 134 } 135 136 @Override 137 public boolean equals(final Object obj) { 138 return obj == this || 139 obj instanceof LongRange other && 140 _min == other._min && 141 _max == other._max; 142 } 143 144 @Override 145 public String toString() { 146 return "[" + _min + ", " + _max + "]"; 147 } 148 149 150 /* ************************************************************************* 151 * Java object serialization 152 * ************************************************************************/ 153 154 @Serial 155 private Object writeReplace() { 156 return new SerialProxy(SerialProxy.LONG_RANGE, this); 157 } 158 159 @Serial 160 private void readObject(final ObjectInputStream stream) 161 throws InvalidObjectException 162 { 163 throw new InvalidObjectException("Serialization proxy required."); 164 } 165 166 void write(final DataOutput out) throws IOException { 167 writeLong(_min, out); 168 writeLong(_max, out); 169 } 170 171 static LongRange read(final DataInput in) throws IOException { 172 return of(readLong(in), readLong(in)); 173 } 174 175}