001/* 002 * Java Genetic Algorithm Library (jenetics-8.3.0). 003 * Copyright (c) 2007-2025 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; 023 024import java.io.Serializable; 025import java.util.Optional; 026import java.util.stream.LongStream; 027 028/** 029 * Long range class. 030 * 031 * @param min the minimum value of the range 032 * @param max the maximum value of the range 033 * 034 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a> 035 * @version 8.3 036 * @since 3.2 037 */ 038public record LongRange(long min, long max) implements Serializable { 039 040 /** 041 * Create a new {@code LongRange} object with the given {@code min} and 042 * {@code max} values. 043 * 044 * @param min the lower bound of the long range 045 * @param max the upper bound of the long range 046 * @throws IllegalArgumentException if {@code min > max} 047 */ 048 public LongRange { 049 if (min > max) { 050 throw new IllegalArgumentException(format( 051 "Min greater than max: %s > %s", min, max 052 )); 053 } 054 } 055 056 /** 057 * Create a new (half-open) range, which contains only the given value: 058 * {@code [value, value + 1)}. 059 * 060 * @param value the value of the created (half-open) integer range 061 */ 062 public LongRange(final long value) { 063 this(value, value + 1); 064 } 065 066 /** 067 * Checks whether the given {@code value} is within the range 068 * {@code [min, max)}. 069 * 070 * @since 8.0 071 * 072 * @param value the value to check 073 * @return {@code true} if the {@code value} is with the range 074 * {@code [min, max)}, {@code false} otherwise 075 */ 076 public boolean contains(final long value) { 077 return value >= min && value < max; 078 } 079 080 /** 081 * Return the intersection of {@code this} range with the {@code other}. 082 * 083 * @since 8.0 084 * 085 * @param other the intersection range or {@link Optional#empty()} if there 086 * is none 087 * @return the range intersection 088 */ 089 public Optional<LongRange> intersect(final LongRange other) { 090 if (max <= other.min || min >= other.max) { 091 return Optional.empty(); 092 } else { 093 return Optional.of( 094 new LongRange( 095 Math.max(min, other.min), 096 Math.min(max, other.max) 097 ) 098 ); 099 } 100 } 101 102 /** 103 * Returns a sequential ordered {@code LongStream} from {@link #min()} 104 * (inclusive) to {@link #max()} (exclusive) by an incremental step of 105 * {@code 1}. 106 * <p> 107 * An equivalent sequence of increasing values can be produced sequentially 108 * using a {@code for} loop as follows: 109 * {@snippet lang="java": 110 * for (long i = range.min(); i < range.max(); ++i) { 111 * // ... 112 * } 113 * } 114 * 115 * @since 3.4 116 * 117 * @return a sequential {@link LongStream} for the range of {@code long} 118 * elements 119 */ 120 public LongStream stream() { 121 return LongStream.range(min, max); 122 } 123 124 /** 125 * Create a new {@code LongRange} object with the given {@code min} and 126 * {@code max} values. 127 * 128 * @param min the lower bound of the long range 129 * @param max the upper bound of the long range 130 * @return a new {@code LongRange} object 131 * @throws IllegalArgumentException if {@code min > max} 132 * 133 * @deprecated Class is a record now, and this factory method will be 134 * removed in the next major version. Use 135 * {@link #LongRange(long, long)} instead. 136 */ 137 @Deprecated(since = "8.2", forRemoval = true) 138 public static LongRange of(final long min, final long max) { 139 return new LongRange(min, max); 140 } 141 142 /** 143 * Return a new (half-open) range, which contains only the given value: 144 * {@code [value, value + 1)}. 145 * 146 * @since 4.0 147 * 148 * @param value the value of the created (half-open) integer range 149 * @return a new (half-open) range, which contains only the given value 150 * 151 * @deprecated Class is a record now, and this factory method will be 152 * removed in the next major version. Use {@link #LongRange(long)} 153 * instead. 154 */ 155 @Deprecated(since = "8.2", forRemoval = true) 156 public static LongRange of(final long value) { 157 return of(value, value + 1); 158 } 159 160 @Override 161 public String toString() { 162 return "[" + min + ", " + max + "]"; 163 } 164 165}