Кажется, что под давлением nginx попытался вытащить angular.js
из своего кэша и не смог из-за проблем с разрешениями. Вот что решило эту проблему:
root@amac-2:/usr/local/var/run/nginx $ chown -R _www:admin proxy_temp
_www:admin
может отличаться в вашем случае, в зависимости от того, какой пользователь владеет процессом nginx. Дополнительная информация о ServerFault:
https://serverfault.com/questions/534497/why-do-nginx-process-run-with-user-nobody
Что я, вероятно, сделал бы, так это просто сделал бы вспомогательный класс под названием Deques
, который мог бы поддерживать это, наряду с другими утилитами, если это необходимо.
public class Deques {
private Deques() {}
public static <T> Iterable<T> asDescendingIterable(final Deque<T> deque) {
return new Iterable<T>() {
public Iterator<T> iterator() {
return deque.descendingIterator();
}
}
}
}
Это еще один случай, когда очень жаль, что у нас еще нет лямбд и ссылок на методы. В Java 8 вы сможете написать что-то вроде этого, учитывая, что ссылка на метод descendingIterator()
соответствует сигнатуре Iterable
:
Deque<String> deque = ...
for (String s : deque::descendingIterator) { ... }
Вместо того, чтобы создавать descendingIterator
, было бы лучше написать метод descendingIterable()
, чтобы он возвращал итерацию по убыванию, основанную на деке, который в основном занимает место вашего анонимного класса. Это кажется довольно разумным для меня. Согласно предложению Колина, итеративная реализация, возвращаемая этим методом, будет вызывать descendingIterator
в исходной деке каждый раз, когда вызывается ее собственный метод iterator()
.
Если у вас только есть итератор и вы хотите сохранить его таким образом, вам нужно написать реализацию Iterable<T>
, которая обернет итератор и вернет его ровно один раз , выбрасывая исключение, если iterator()
вызывается более одного раза. Это сработало бы, но было бы довольно уродливо.
public class DescendingIterableDequeAdapter<T> implements Iterable<T> {
private Deque<T> original;
public DescendingIterableDequeAdapter(Deque<T> original) {
this.original = original;
}
public Iterator<T> iterator() {
return original.descendingIterator();
}
}
А затем
for (T item : new DescendingIterableDequeAdapter(deque)) {
}
Итак, для каждого такого случая вам понадобится специальный адаптер. Я не думаю, что теоретически возможно делать то, что вы хотите, потому что объект должен знать, какие существуют методы, возвращающие итераторы, чтобы он мог их вызывать.
Что касается вашего дополнительного вопроса - я полагаю, потому что цикл for-each действительно должен был сделать вещи короче для сценариев общего назначения. А вызов дополнительного метода делает синтаксис более многословным. Он мог бы поддерживать Iterable
и Iterator
, но что, если переданный объект реализовал оба? (было бы странно, но все же возможно).
У Guava, конечно, есть решение для обратного повторяемого сценария, но, к сожалению, вам нужно два шага. Iterables.reverse () принимает List
в качестве параметра, а не Iterable
.
final Iterable<String> it = Arrays.asList("a", "b", "c");
for(final String item : Iterables.reverse(Lists.newArrayList(it))){
System.out.println(item);
}
Вывод:
c
b
a
Apache Commons Collections API имеет класс под названием IteratorIterable
, чтобы сделать именно это:
Iterator<X> iter;
for (X item : new IteratorIterable(iter)) {
...
}