序
本文主要研究一下Elasticsearch的Iterables
Iterables
elasticsearch-7.0.1/server/src/main/java/org/elasticsearch/common/util/iterable/Iterables.java
public class Iterables {
public static <T> Iterable<T> concat(Iterable<T>... inputs) {
Objects.requireNonNull(inputs);
return new ConcatenatedIterable<>(inputs);
}
static class ConcatenatedIterable<T> implements Iterable<T> {
private final Iterable<T>[] inputs;
ConcatenatedIterable(Iterable<T>[] inputs) {
this.inputs = Arrays.copyOf(inputs, inputs.length);
}
@Override
public Iterator<T> iterator() {
return Stream
.of(inputs)
.map(it -> StreamSupport.stream(it.spliterator(), false))
.reduce(Stream::concat)
.orElseGet(Stream::empty).iterator();
}
}
/** Flattens the two level {@code Iterable} into a single {@code Iterable}. Note that this pre-caches the values from the outer {@code
* Iterable}, but not the values from the inner one. */
public static <T> Iterable<T> flatten(Iterable<? extends Iterable<T>> inputs) {
Objects.requireNonNull(inputs);
return new FlattenedIterables<>(inputs);
}
static class FlattenedIterables<T> implements Iterable<T> {
private final Iterable<? extends Iterable<T>> inputs;
FlattenedIterables(Iterable<? extends Iterable<T>> inputs) {
List<Iterable<T>> list = new ArrayList<>();
for (Iterable<T> iterable : inputs) {
list.add(iterable);
}
this.inputs = list;
}
@Override
public Iterator<T> iterator() {
return StreamSupport
.stream(inputs.spliterator(), false)
.flatMap(s -> StreamSupport.stream(s.spliterator(), false)).iterator();
}
}
public static <T> T get(Iterable<T> iterable, int position) {
Objects.requireNonNull(iterable);
if (position < 0) {
throw new IllegalArgumentException("position >= 0");
}
if (iterable instanceof List) {
List<T> list = (List<T>)iterable;
if (position >= list.size()) {
throw new IndexOutOfBoundsException(Integer.toString(position));
}
return list.get(position);
} else {
Iterator<T> it = iterable.iterator();
for (int index = 0; index < position; index++) {
if (!it.hasNext()) {
throw new IndexOutOfBoundsException(Integer.toString(position));
}
it.next();
}
if (!it.hasNext()) {
throw new IndexOutOfBoundsException(Integer.toString(position));
}
return it.next();
}
}
}
- Iterables提供了concat、flatten、get三个静态方法,其中concat返回的是ConcatenatedIterable;flatten返回的是FlattenedIterables;get方法会先判断是否是List类型是的话直接通过position取值返回,不是则遍历iterable获取指定index的元素
实例
elasticsearch-7.0.1/server/src/test/java/org/elasticsearch/common/util/iterable/IterablesTests.java
public class IterablesTests extends ESTestCase {
public void testGetOverList() {
test(Arrays.asList("a", "b", "c"));
}
public void testGetOverIterable() {
Iterable<String> iterable = () ->
new Iterator<String>() {
private int position = 0;
@Override
public boolean hasNext() {
return position < 3;
}
@Override
public String next() {
if (position < 3) {
String s = position == 0 ? "a" : position == 1 ? "b" : "c";
position++;
return s;
} else {
throw new NoSuchElementException();
}
}
};
test(iterable);
}
public void testFlatten() {
List<List<Integer>> list = new ArrayList<>();
list.add(new ArrayList<>());
Iterable<Integer> allInts = Iterables.flatten(list);
int count = 0;
for(@SuppressWarnings("unused") int x : allInts) {
count++;
}
assertEquals(0, count);
list.add(new ArrayList<>());
list.get(1).add(0);
// changes to the outer list are not seen since flatten pre-caches outer list on init:
count = 0;
for(@SuppressWarnings("unused") int x : allInts) {
count++;
}
assertEquals(0, count);
// but changes to the original inner lists are seen:
list.get(0).add(0);
for(@SuppressWarnings("unused") int x : allInts) {
count++;
}
assertEquals(1, count);
}
private void test(Iterable<String> iterable) {
try {
Iterables.get(iterable, -1);
fail("expected IllegalArgumentException");
} catch (IllegalArgumentException e) {
assertThat(e, hasToString("java.lang.IllegalArgumentException: position >= 0"));
}
assertEquals("a", Iterables.get(iterable, 0));
assertEquals("b", Iterables.get(iterable, 1));
assertEquals("c", Iterables.get(iterable, 2));
try {
Iterables.get(iterable, 3);
fail("expected IndexOutOfBoundsException");
} catch (IndexOutOfBoundsException e) {
assertThat(e, hasToString("java.lang.IndexOutOfBoundsException: 3"));
}
}
}
- flatten用于将Iterable类型的Iterable进行flat操作;get方法则获取iterable中指定index的元素
小结
Iterables提供了concat、flatten、get三个静态方法,其中concat返回的是ConcatenatedIterable;flatten返回的是FlattenedIterables;get方法会先判断是否是List类型是的话直接通过position取值返回,不是则遍历iterable获取指定index的元素
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。