共计 3988 个字符,预计需要花费 10 分钟才能阅读完成。
序
本文主要研究一下 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 的元素
doc
- Iterables
正文完
发表至:无分类
2019-06-06