Как я могу расширить структуру данных в Java-статическом методе, чтобы быть ленивым? - PullRequest
2 голосов
/ 07 января 2011

Я пытаюсь обернуть внешнюю библиотеку в более идиоматическую Clojure. Это включает в себя создание ленивых структур данных. Я хотел бы использовать статический метод read ниже и сделать FooList ленивым.

У меня много проблем:

  1. Статические методы Java не могут быть переопределены
  2. proxy только генерирует объекты экземпляра
  3. gen-class кажется, что-то вроде работы, но я теряюсь в море пространств имен, псевдонимов и т. Д.
  4. Данный метод вызывает другой статический и закрытый метод (который я хотел бы использовать повторно), что затрудняет переопределение открытого метода.

Какая лучшая стратегия для этого? Можно ли открыть FooList и повторно реализовать его как ленивый, с результирующим классом, доступным для остальной части моего кода?

org.apache.commons.collections.list.LazyList кажется подходящим для этой задачи, но я не уверен, как на самом деле быть в состоянии использовать его.

Помощь

public class Foo {

    public static FooList read(String filename) {
        FooList foos = new FooList(); //FooList extends ArrayList
        BufferedReader br = new BufferedReader(new FileReader(filename));

        for (String s = br.readLine(); null != s; s = br.readLine()) {
            Foo f = parseLine(s);
            foos.add(f);
        }

        br.close();
        return foos;
    }

    private static Foo parseLine(String s) {
        //return s as Foo
    }
}

Ответы [ 4 ]

2 голосов
/ 07 января 2011

Может быть полностью вне вашей сферы, но у меня была похожая проблема . Итак, мой последний выбор заключался в том, чтобы выбрать java.lang.Iterable, который, если вы думаете глубже, точно соответствует критериям ленивости. Да, у него нет вещей, которые есть у List (например, size()), но я мог бы позволить себе пожертвовать этим для простоты. Оглядываясь назад, я никогда не сожалел, что сделал этот выбор.

1 голос
/ 08 января 2011

В Clojure вы можете просто вызвать (seq collection) для любой коллекции Iterable (например, вашего FooList) и получить ленивую последовательность, которая пересекает коллекцию.Хотя на самом деле лень мало что дает вам, так как вы уже загрузили полный FoolList на стороне Java.

Если вы действительно хотите лень как в Clojure, так и в Java, тогда вы можете сделать следующее:1004 *

Пусть ваша функция Java возвращает пользовательскую реализацию java.util.Iterator, а не полную коллекцию.Чтобы получить ленивое чтение, вы должны убедиться, что readLine () вызывается только один раз за итерацию (в методе next () или hasNext ()).Не забудьте закрыть () читатель, когда дойдете до конца файла.

На стороне Clojure создайте отложенный запрос с помощью (iterator-seq java-iterator)

Если вы сделаете это, ваш файл будет считываться и анализироваться постепенно по мере использования последовательности Clojure.

1 голос
/ 07 января 2011

В целом, в Java это не стоит делать, так как вы обычно хотите прочитать весь файл.Однако, скажем, вы просто хотите прочитать заголовок или файл, который слишком велик для чтения, вы можете прочитать только те строки, которые вам нужны.

Однако в качестве упражнения самый простой способ изменить этот класс - это отредактироватьЭто.Вы можете получить исходный код для этого класса (декомпилировать его, если нужно) и сначала добавить его в путь к классу, чтобы он использовался как исправление для вашей текущей системы.

0 голосов
/ 07 января 2011

Вы не можете создать Bar и BarList с методами и отложенной функцией, которую хотите разработать, делегируя Foo и FooList, а затем просто использовать Bar и BarList ??

Я упустил момент в вашемвопрос

...