Почему в guava joiner реализован закрытый метод с повторяемостью (первый объект "окончание", второй объект "окончание", остальное "конечный объект" [])?
private static Iterable<Object> iterable(
final Object first, final Object second, final Object[] rest) {
checkNotNull(rest);
return new AbstractList<Object>() {
@Override
public int size() {
return rest.length + 2;
}
@Override
public Object get(int index) {
switch (index) {
case 0:
return first;
case 1:
return second;
default:
return rest[index - 2];
}
}
};
}
Какова цель автора?
Я предполагаю, что он хочет использовать массив, сгенерированный компилятором, а не новый ArrayList.
Но все же запутанный вопрос, почему бы не написать, как показано ниже?
private static Iterable<Object> iterable(final Object[] rest) {
checkNotNull(rest);
return new AbstractList<Object>() {
@Override
public int size() {
return rest.length;
}
@Override
public Object get(int index) {
return rest[index];
}
};
}
1 ответ
Решение
Дело в том, что этот метод вызывается из открытых методов, которые выглядят как ( источник):
public final String join(
@NullableDecl Object first, @NullableDecl Object second, Object... rest) {
return join(iterable(first, second, rest));
}
Использование таких подписей - хитрость, чтобы заставить вас передать как минимум два аргумента - в конце концов, если у вас нет двух аргументов, присоединяться нечего.
Например:
Joiner.on(':').join(); // Compiler error.
Joiner.on(':').join("A"); // Compiler error.
Joiner.on(':').join("A", "B"); // OK.
Joiner.on(':').join("A", "B", "C"); // OK.
// etc.
это iterable
Метод просто создает Iterable
без необходимости копировать все в новый массив. Это будет O(n)
по количеству аргументов; подход, принятый здесь O(1)
,