Остаток "трюк"
Вы можете использовать %
"трюк" (%
- оператор остатка JLS 15.17.3 ) для циклического индексирования. Здесь я проиллюстрирую общую идею, используя вместо этого String
.
String s = "ABCDE";
final int L = s.length();
for (int i = 0; i < L; i++) {
System.out.format("%c%c%c ",
s.charAt(i),
s.charAt((i + 1) % L),
s.charAt((i + 2) % L)
);
} // prints "ABC BCD CDE DEA EAB "
Ан Iterator
подход
Однако, если вы часто выполняете эту триплетную обработку, в целом будет лучше иметь Iterator<PointTriplet>
или что-то подобное.
Вот прототип, иллюстрирующий идею:
import java.util.*;
public class CircSubArray {
static <T> Iterator<T[]> circularIterator(final T[] arr, final int K) {
return new Iterator<T[]>() {
int index = 0;
final int L = arr.length;
T[] sub = Arrays.copyOf(arr, K); // let it do the dirty work!
@Override public boolean hasNext() {
return index < L;
}
@Override public T[] next() {
for (int i = 0; i < K; i++) {
sub[i] = arr[(index + i) % L];
}
index++;
return sub; // we always overwrite; no need to .clone()
}
@Override public void remove() {
throw new UnsupportedOperationException();
}
};
}
public static void main(String[] args) {
String[] arr = { "s1", "s2", "s3", "s4", "s5", "s6" };
Iterator<String[]> iter = circularIterator(arr, 4);
while (iter.hasNext()) {
System.out.println(Arrays.toString(iter.next()));
}
}
}
Это печатает:
[s1, s2, s3, s4]
[s2, s3, s4, s5]
[s3, s4, s5, s6]
[s4, s5, s6, s1]
[s5, s6, s1, s2]
[s6, s1, s2, s3]
A List
решение на основе
Как говорит Effective Java 2nd Edition , пункт 25: Предпочитать списки массивам. Вот решение, которое избыточно хранит первые K-1
элементов в конце List
, а затем просто использует subList
, чтобы получить K
элементов одновременно.
String[] arr = { "s1", "s2", "s3", "s4", "s5", "s6" };
final int L = arr.length;
final int K = 3;
List<String> list = new ArrayList<String>(Arrays.asList(arr));
list.addAll(list.subList(0, K-1));
for (int i = 0; i < L; i++) {
System.out.println(list.subList(i, i + K));
}
Это печатает:
[s1, s2, s3]
[s2, s3, s4]
[s3, s4, s5]
[s4, s5, s6]
[s5, s6, s1]
[s6, s1, s2]
Поскольку subList
является представлением, для этого не нужно выполнять смещение O(K)
, как это делает решение на основе массива. Это также показывает выразительность List
над массивами.