2011-01-07 5 views
2

더 관용적 인 Clojure에서 외부 라이브러리를 래핑하려고합니다. 여기에는 데이터 구조를 게으르게 만드는 작업이 포함됩니다. 나는 아래의 read 정적 메소드에 들어가서 FooList을 게으 르고 싶습니다.자바 정적 메서드 내에서 데이터 구조를 게으른 것으로 확장하려면 어떻게해야합니까?

나는 많은 문제로 실행하고 있습니다 :

  1. 자바 정적 메서드는
  2. 을 재정의 할 수 없습니다
  3. proxy는 인스턴스가
  4. gen-class 좀 할까 작동하는 것 같다 객체하지만 난이 바다에서 길을 잃지 생성하는 것 별명 등등
  5. 이 메서드는 공용 메서드를 재정의하는 것을 어렵게 만드는 또 다른 정적 및 개인 메서드 (재사용하고 싶음)를 호출합니다.

이 작업을 수행하는 가장 좋은 전략은 무엇입니까? 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 
    } 
} 

답변

1

Clojure에서는 Iterable 컬렉션 (예 : FooList)에서 (seq 컬렉션)을 호출하고 컬렉션을 가로 지르는 지연 시퀀스를 얻을 수 있습니다. 비록 게으름은 실제로 자바 측에서 전체 FoolList를로드 한 이후로 실제로 많이 이길 수는 없지만.

당신이 정말로 Clojure의 자바 모두에서 게으름 후 다음 작업을 수행 할 수 원하는 경우 :

  • 는 자바 함수는 전체 모음보다는 java.util.Iterator를의 사용자 지정 구현을 돌려 되세요. 게으른 읽기를 얻으려면 순서대로 readLine()이 next() 또는 hasNext() 메소드에서 한 번만 호출되도록해야합니다. 파일의 끝에 도달하면 판독기를 닫으십시오.Clojure의 측면에서

는이 작업을 수행 할 경우, 다음 파일을 읽을되고 Clojure의 순서가 소모됨에 따라 점진적으로 파싱 (반복자-SEQ 자바 반복자)와 게으른 서열을 만들 .

+0

고마워, 정확히 내가 무엇을 찾고 있었는지. –

2

범위가 완전히 벗어 났을 수도 있지만 similar problem입니다. 그래서 나의 최종 선택은 java.lang.Iterable과 함께하는 것이 었습니다. 당신이 더 깊이 생각한다면, 게으른 기준을 정확하게 맞추는 것입니다. 예, 일부 자료가 없습니다. List (예 : size()).하지만이를 단순하게하기 위해 희생 할만한 여지가 있습니다. 뒤돌아 보니 결코 후회하지 않았습니다.

+0

나는 똑같은 일을한다. 단순히 다음 줄을 얻기 위해'myFileIterator.next()'를 호출한다. IO 예외를 RuntimeException 또는 null 반환으로 어느쪽으로 든 감싸십시오. – dagnelies

+0

사실, FooList라는 원숭이 패치를 할 수 있다면 간단히 [clojure.lang.ISeq] (https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/ISeq)를 구현할 것입니다. .java) :'first','rest','more' 및'cons'를 구현하는 것입니다. 그러나 또 다른 아이디어에 감사드립니다. –

1

일반적으로 자바에서는 전체 파일을 읽으 려하므로이 작업을 수행 할 필요가 없습니다. 그러나 단지 머리글을 읽거나 파일을 너무 크게 읽으므로 한 번에 읽을 수 있으면 원하는 줄만 읽을 수 있습니다.

그러나 연습 문제로이 클래스를 변경하는 가장 간단한 방법은 수정하는 것입니다. 이 클래스에 대한 소스를 가져올 수 있습니다 (필요하다면 컴파일 해제). 클래스 경로에서 먼저 추가하여 현재 시스템에 패치로 적용 할 수 있습니다.

+0

내가 말했듯이, 나는 도서관을 게으름이 요구되는 관용적 인 조상으로 옮기고있다. 라이브러리의 자체 패치 된 복사본을 유지할 수 있다고 생각하지만 나중에 새로운 버전 등으로 인해 슬픔이 생길 것 같습니다. –

+0

@Pedro, 필요합니다.하지만 기존 라이브러리를 해킹해야하는 모든 솔루션이있을 것입니다. 보다 나쁜. 가장 좋은 해결책은 도서관 제공자에게 도서관을 변경하도록 요청하는 것입니다. –

0

디자인 할 게으른 기능과 방법으로 Bar 및 BarList를 만들거나 Foo 및 FooList에 위임 한 다음 Bar 및 BarList를 사용 하시겠습니까 ??

질문에 대한 답변을 놓쳤습니까?

+0

나는 외부 라이브러리에 대한 개발자 액세스 권한이 없거나 패치 된 버전의 코드를 유지하려고하지 않고 문제의 클래스를 원숭이 패치로 찾고 있습니다. –

관련 문제