Почему Очередь <Integer>возвращает Итерабельный <Integer>здесь? - PullRequest
2 голосов
/ 26 января 2020

Контекст:

Я читаю главу 4 Алгоритмов Седжвика и Уэйна. Этот пример кода является примером кода «Порядок поиска вершин в глубину в орграфе».

        public class DepthFirstOrder
        {
            private boolean[] marked;
            private Queue<Integer> pre; // vertices in preorder
            private Queue<Integer> post; // vertices in postorder
            private Stack<Integer> reversePost; // vertices in reverse postorder
            public DepthFirstOrder(Digraph G)
            {
                pre = new Queue<Integer>();
                post = new Queue<Integer>();
                reversePost = new Stack<Integer>();
                marked = new boolean[G.V()];
                for (int v = 0; v < G.V(); v++)
                    if (!marked[v]) dfs(G, v);
            }
            private void dfs(Digraph G, int v)
            {
                pre.enqueue(v);
                marked[v] = true;
                for (int w : G.adj(v))
                    if (!marked[w])
                        dfs(G, w);
                post.enqueue(v);
                reversePost.push(v);
            }
            public Iterable<Integer> pre()
            { return pre; }
            public Iterable<Integer> post()
            { return post; }
            public Iterable<Integer> reversePost()
            { return reversePost; }
        }

Мой вопрос заключается в том, почему очереди возвращаются как итерируемые в соответствующих им методах для поиска. Я понимаю, что код делает иначе, но я не понимаю, почему pre , post и reversePost возвращают Iterable здесь, пока они являются очередями?

Я понимаю, что обычно делает интерфейс Iterable, и что Queue также является Iterable, потому что Collection реализует Iterable.

Однако я не понимаю, почему эта реализация возвращает Queues в качестве Iterables .

1 Ответ

3 голосов
/ 26 января 2020

Это так, что внешний интерфейс только обещает, что это Iterable, а не конкретно, что они Queue с. Это означает:

  1. Реализация может измениться, не затрагивая интерфейс, предоставляемый классом.
  2. Пользователи возвращенных очередей могут полагаться только на то, что они Iterable s, они не могут Предположим, что они Queue с, в частности. (Что среди прочего означает, что нельзя использовать функции изменения состояния, которые Queue предоставляет за пределами того, что [remove] делает Iterable - не без их разыгрывания, что было бы Плохой вещью ™, потому что все, что делает класс гарантией является то, что они Iterable с, а не Queue с.)

Более защищенный класс может вставить фасад между фактическим Queue и возвращаемым объектом для защитить от плохо написанного кода, выполнив # 2 выше, но, конечно, там есть цена.

...