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.internal.collection; 021 022import static java.lang.Math.min; 023import static java.lang.String.format; 024 025import java.io.Serial; 026import java.util.Comparator; 027import java.util.Iterator; 028import java.util.ListIterator; 029import java.util.function.Function; 030import java.util.function.Supplier; 031import java.util.random.RandomGenerator; 032 033import io.jenetics.util.ISeq; 034import io.jenetics.util.MSeq; 035 036/** 037 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a> 038 * @since 1.4 039 * @version 3.4 040 */ 041public class ArrayMSeq<T> extends ArraySeq<T> implements MSeq<T> { 042 043 @Serial 044 private static final long serialVersionUID = 1L; 045 046 public ArrayMSeq(final Array<T> array) { 047 super(array); 048 } 049 050 @Override 051 public MSeq<T> copy() { 052 return isEmpty() 053 ? this 054 : new ArrayMSeq<>(array.copy()); 055 } 056 057 @Override 058 public Iterator<T> iterator() { 059 return listIterator(); 060 } 061 062 @Override 063 public ListIterator<T> listIterator() { 064 return new BaseMSeqIterator<>(array); 065 } 066 067 @Override 068 public void set(final int index, final T value) { 069 array.set(index, value); 070 } 071 072 @Override 073 public MSeq<T> setAll(final Iterator<? extends T> it) { 074 for (int i = 0; i < array.length() && it.hasNext(); ++i) { 075 array.set(i, it.next()); 076 } 077 return this; 078 } 079 080 @Override 081 public MSeq<T> setAll(final Iterable<? extends T> values) { 082 return setAll(values.iterator()); 083 } 084 085 @Override 086 public MSeq<T> setAll(final T[] values) { 087 for (int i = 0, n = min(array.length(), values.length); i < n; ++i) { 088 array.set(i, values[i]); 089 } 090 return this; 091 } 092 093 public MSeq<T> fill(final Supplier<? extends T> supplier) { 094 for (int i = 0; i < array.length(); ++i) { 095 array.set(i, supplier.get()); 096 } 097 return this; 098 } 099 100 @Override 101 public ArrayMSeq<T> sort( 102 final int start, 103 final int end, 104 final Comparator<? super T> comparator 105 ) { 106 array.sort(start, end, comparator); 107 return this; 108 } 109 110 @Override 111 public MSeq<T> shuffle(final RandomGenerator random) { 112 for (int j = length() - 1; j > 0; --j) { 113 swap(j, random.nextInt(j + 1)); 114 } 115 return this; 116 } 117 118 @Override 119 public void swap(final int i, final int j) { 120 final T temp = array.get(i); 121 array.set(i, array.get(j)); 122 array.set(j, temp); 123 } 124 125 @Override 126 public void swap(int start, int end, MSeq<T> other, int otherStart) { 127 checkIndex(start, end, otherStart, other.length()); 128 129 if (start < end) { 130 for (int i = end - start; --i >= 0;) { 131 final T temp = array.get(i + start); 132 array.set(i + start, other.get(otherStart + i)); 133 other.set(otherStart + i, temp); 134 } 135 } 136 } 137 138 protected void checkIndex( 139 final int start, final int end, 140 final int otherStart, final int otherLength 141 ) { 142 array.checkIndex(start, end); 143 if (otherStart < 0 || (otherStart + (end - start)) > otherLength) { 144 throw new ArrayIndexOutOfBoundsException(format( 145 "Invalid index range: [%d, %d)", 146 otherStart, otherStart + end - start 147 )); 148 } 149 } 150 151 @Override 152 public MSeq<T> subSeq(final int start, final int end) { 153 if (start > end) { 154 throw new ArrayIndexOutOfBoundsException(format( 155 "start[%d] > end[%d]", start, end 156 )); 157 } 158 if (start < 0 || end > length()) { 159 throw new ArrayIndexOutOfBoundsException(format( 160 "Indexes (%d, %d) range: [%d..%d)", start, end, 0, length() 161 )); 162 } 163 164 return start == end 165 ? Empty.mseq() 166 : new ArrayMSeq<>(array.slice(start, end)); 167 } 168 169 @Override 170 public MSeq<T> subSeq(final int start) { 171 if (start < 0 || start > length()) { 172 throw new ArrayIndexOutOfBoundsException(format( 173 "Index %d range: [%d..%d)", start, 0, length() 174 )); 175 } 176 177 return start == length() 178 ? Empty.mseq() 179 : new ArrayMSeq<>(array.slice(start, length())); 180 } 181 182 @Override 183 public <B> MSeq<B> map(final Function<? super T, ? extends B> mapper) { 184 final Array<B> mapped = Array.ofLength(length()); 185 for (int i = 0; i < length(); ++i) { 186 mapped.set(i, mapper.apply(array.get(i))); 187 } 188 return new ArrayMSeq<>(mapped); 189 } 190 191 @Override 192 public MSeq<T> append(final Iterable<? extends T> values) { 193 return new ArrayMSeq<>(__append(values)); 194 } 195 196 @Override 197 public MSeq<T> prepend(final Iterable<? extends T> values) { 198 return new ArrayMSeq<>(__prepend(values)); 199 } 200 201 @Override 202 public ISeq<T> toISeq() { 203 return isEmpty() 204 ? Empty.iseq() 205 : new ArrayISeq<>(array.seal()); 206 } 207 208}