clone iterator
От: Hard_Club  
Дата: 22.01.15 13:19
Оценка:
Есть задача, когда нужно последоватльно идти по елементам коллекции и сравнивать "хвост" от элемента до конца коллекции.

Как в java клонировать итератор, чтобы одним идти по элементам, а за счет его клонов анализировать "хвост"?
Re: clone iterator
От: vsb Казахстан  
Дата: 22.01.15 13:34
Оценка:
Здравствуйте, Hard_Club, Вы писали:

H_C>Есть задача, когда нужно последоватльно идти по елементам коллекции и сравнивать "хвост" от элемента до конца коллекции.


H_C>Как в java клонировать итератор, чтобы одним идти по элементам, а за счет его клонов анализировать "хвост"?


Iterator никак.

ListIterator можно так:

        List<Integer> list = ...;
        ListIterator<Integer> i = list.listIterator();
        while (i.hasNext()) {
            Integer x = i.next();
            ListIterator<Integer> j = list.listIterator(i.nextIndex());
            while (j.hasNext()) {
                Integer y = j.next();
            }
        }


но для LinkedList это будет не очень быстро. Быстрей вроде никак.

Лучше всего скопировать нужную коллекцию в массив и использовать обычные индексы.
Отредактировано 22.01.2015 13:34 vsb . Предыдущая версия .
Re[2]: clone iterator
От: Hard_Club  
Дата: 22.01.15 13:49
Оценка:
vsb>но для LinkedList это будет не очень быстро. Быстрей вроде никак.

А почему для LinkedList это будет не очень быстро?
Re[3]: clone iterator
От: vsb Казахстан  
Дата: 22.01.15 13:53
Оценка:
Здравствуйте, Hard_Club, Вы писали:

vsb>>но для LinkedList это будет не очень быстро. Быстрей вроде никак.


H_C>А почему для LinkedList это будет не очень быстро?


            ListIterator<Integer> j = list.listIterator(i.nextIndex());


Эта строчка возвращает итератор на элемент, находящийся в указанной позиции. Если у нас LinkedList из миллиона элементов, а мы просим итератор на элемент с индексом 400 000, то нам надо проитерироваться 400 000 раз с начала списка, чтобы вернуть такой итератор. Хотя теоретически можно было бы вернуть итератор моментально, скопировав поля, но в JDK этого не реализовано. Разве что через рефлексию копировать поля, но я бы не стал такой метод рекомендовать, разве что нет других вариантов вообще.
Re[4]: clone iterator
От: devcoach  
Дата: 22.01.15 18:15
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Эта строчка возвращает итератор на элемент, находящийся в указанной позиции. Если у нас LinkedList из миллиона элементов, а мы просим итератор на элемент с индексом 400 000, то нам надо проитерироваться 400 000 раз с начала списка, чтобы вернуть такой итератор. Хотя теоретически можно было бы вернуть итератор моментально, скопировав поля, но в JDK этого не реализовано. Разве что через рефлексию копировать поля, но я бы не стал такой метод рекомендовать, разве что нет других вариантов вообще.

Скопировав какие поля?
Re[5]: clone iterator
От: vsb Казахстан  
Дата: 22.01.15 19:40
Оценка:
Здравствуйте, devcoach, Вы писали:

vsb>>Эта строчка возвращает итератор на элемент, находящийся в указанной позиции. Если у нас LinkedList из миллиона элементов, а мы просим итератор на элемент с индексом 400 000, то нам надо проитерироваться 400 000 раз с начала списка, чтобы вернуть такой итератор. Хотя теоретически можно было бы вернуть итератор моментально, скопировав поля, но в JDK этого не реализовано. Разве что через рефлексию копировать поля, но я бы не стал такой метод рекомендовать, разве что нет других вариантов вообще.

D>Скопировав какие поля?

    private class ListItr implements ListIterator<E> {
        private Node<E> lastReturned;
        private Node<E> next;
        private int nextIndex;
        private int expectedModCount = modCount;


вот эти.
Re[6]: clone iterator
От: vsb Казахстан  
Дата: 22.01.15 19:50
Оценка: 2 (1)
Вот рабочий пример, если интересно.

package test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.*;

public class ListTest {
    public static void main(String[] args) {
        LinkedList<Integer> list = new LinkedList<Integer>();
        list.add(1);
        list.add(2);
        list.add(3);
        Iterator<Integer> i = list.iterator();
        while (i.hasNext()) {
            Iterator<Integer> j = copyIterator(list, i);
            Integer x = i.next();
            if (j != null) {
                while (j.hasNext()) {
                    Integer y = j.next();
                    System.out.println(x + " " + y);
                }
            }
        }
    }

    private static <T> Iterator<T> copyIterator(LinkedList<T> list, Iterator<T> i) {
        try {
            Class<?> iteratorClass = i.getClass();
            Constructor<?> constructor = iteratorClass.getDeclaredConstructors()[0];
            constructor.setAccessible(true);
            Object result = constructor.newInstance(list, list.size());
            for (Field field : iteratorClass.getDeclaredFields()) {
                if (!Modifier.isFinal(field.getModifiers())) {
                    field.setAccessible(true);
                    field.set(result, field.get(i));
                }
            }
            @SuppressWarnings("unchecked") Iterator<T> resultIterator = (Iterator<T>) result;
            return resultIterator;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
Re[7]: clone iterator
От: Hard_Club  
Дата: 22.01.15 21:08
Оценка:
Маньяки
Re[8]: clone iterator
От: vpchelko  
Дата: 22.01.15 22:51
Оценка:
Здравствуйте, Hard_Club, Вы писали:

H_C>Маньяки


Да — но так не надо делать.
Сало Украине, Героям Сала
Re[9]: clone iterator
От: Hard_Club  
Дата: 22.01.15 23:14
Оценка:
когда вообще стоит что-то делать через reflection?
Re[10]: clone iterator
От: vpchelko  
Дата: 22.01.15 23:17
Оценка:
Здравствуйте, Hard_Club, Вы писали:

H_C>когда вообще стоит что-то делать через reflection?


1. например dependency injection.

2. когда задачи не решаются без reflection-на (не ваш вариант, используйте ArrayList — делайте итерацию по индексам).
LinkedList это рудимент: занимает больше памяти для хранения коллекции, и нету RandomAccess. Преимуществ нет по сравнению с ArrayList.
Сало Украине, Героям Сала
Отредактировано 22.01.2015 23:29 vpchelko . Предыдущая версия . Еще …
Отредактировано 22.01.2015 23:28 vpchelko . Предыдущая версия .
Отредактировано 22.01.2015 23:27 vpchelko . Предыдущая версия .
Re[11]: clone iterator
От: Hard_Club  
Дата: 23.01.15 08:48
Оценка:
руками что-ли. єто же framework делает
Re[10]: clone iterator
От: vsb Казахстан  
Дата: 23.01.15 09:44
Оценка:
Здравствуйте, Hard_Club, Вы писали:

H_C>когда вообще стоит что-то делать через reflection?


В данном случае проблема не в reflection, как таковом (в нём то проблем нет, он работает надёжно), а в том, что мы подсмотрели реализацию в JDK и написали свой метод исходя из этой реализации. Если завтра в LinkedList поменяется реализация (а это может быть в абсолютно минорном обновлении), то есть все шансы, что этот код перестанет работать.
Re[11]: clone iterator
От: Hard_Club  
Дата: 23.01.15 10:07
Оценка:
vsb>В данном случае проблема не в reflection, как таковом (в нём то проблем нет, он работает надёжно), а в том, что мы подсмотрели реализацию в JDK и написали свой метод исходя из этой реализации. Если завтра в LinkedList поменяется реализация (а это может быть в абсолютно минорном обновлении), то есть все шансы, что этот код перестанет работать.

просто считается, что в коде должно быть как можно меньше reflection
Re[12]: clone iterator
От: vsb Казахстан  
Дата: 23.01.15 10:14
Оценка:
Здравствуйте, Hard_Club, Вы писали:

vsb>>В данном случае проблема не в reflection, как таковом (в нём то проблем нет, он работает надёжно), а в том, что мы подсмотрели реализацию в JDK и написали свой метод исходя из этой реализации. Если завтра в LinkedList поменяется реализация (а это может быть в абсолютно минорном обновлении), то есть все шансы, что этот код перестанет работать.


H_C>просто считается, что в коде должно быть как можно меньше reflection


Ну reflection во-первых немного медленней других способов, во-вторых IDE с ним не может нормально работать. Если можно задачу решить нормально без него, естественно лучше так и делать.
Re[12]: clone iterator
От: vpchelko  
Дата: 23.01.15 16:51
Оценка:
Здравствуйте, Hard_Club, Вы писали:

H_C>руками что-ли. єто же framework делает


А если свой фрейворк пишешь?
Сало Украине, Героям Сала
Re[13]: clone iterator
От: Hard_Club  
Дата: 23.01.15 20:40
Оценка:
V>А если свой фрейворк пишешь?

ну это вообще
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.