【问题标题】:Guava Lazy Collection using Supplier interfaceGuava Lazy Collection 使用供应商接口
【发布时间】:2014-05-08 07:48:21
【问题描述】:

我想要某种通用方法,允许我基于 java.util.Collection.get(int) 方法的使用延迟加载集合内容。我在 Guava 中找到了 Supplier 接口,这看起来是一种进行延迟加载的好方法,但是如何使加载在 java 集合中不可见是我正在努力解决的问题。

下面是一个通过迭代器进行迭代的示例延迟加载方法。

class MySupplier<T> implements Supplier<T> {
    private T s;
    public MySupplier( T s ) {
        this.s = s;
    }
    public T get() {
        System.out.println( String.format( "Lazy loading '%s'", s ) );
        return s;
    }
}

public void lazyLoad() {
    List<MySupplier<String>> list = Lists.newArrayList( new MySupplier<String>( "a" ), new MySupplier<String>( "a" ), new MySupplier<String>( "b" ), new MySupplier<String>( "c" ), new MySupplier<String>( "d" ) );
    for ( Iterator<MySupplier<String>> i = list.iterator(); i.hasNext(); ) {
        System.out.println( i.next().get() );
    }
}

如果可以的话,我想避免使用 Supplier.get() 方法,而是在调用 Collection.get(int) 时让集合包装器为我处理它。我希望通过一个简单的方法调用来实现这一点,我在下面调用了makeLazy( Collection )

public void lazyLoad_desired() {
    List<String> list = makeLazy( 
            Lists.newArrayList( new MySupplier<String>( "a" ), new MySupplier<String>( "a" ), new MySupplier<String>( "b" ), new MySupplier<String>( "c" ), new MySupplier<String>( "d" ) )
        );
    for ( Iterator<String> i = list.iterator(); i.hasNext(); ) {
        String s = i.next();
        System.out.println( s );
    }
}

我意识到我需要以某种方式覆盖集合,但我在这方面的知识存在一些差距。有人可以给我一些关于实现 makeLazy(Collection) 方法需要做什么的提示和技巧吗?

谢谢, 斯图尔特

【问题讨论】:

  • 在什么情况下你需要这个?您真的有理由相信这会带来性能优势吗?
  • 是的。我们在 EJB 应用程序中有一些场景,这样可以节省时间,因为它不需要加载所有查询结果,而是只加载那些需要的结果。有些查询可以返回数百个本地人,但我们可能只对前三个或四个感兴趣。
  • 一般来说,你最好将其作为一个 Iterable 而不是一个 Collection,这样可以避免很多混乱。

标签: java collections guava


【解决方案1】:

根据与Louis Wasserman 的讨论,我决定采纳他的建议并使用迭代器。下面的解决方案似乎对我有用。

class MySupplier<T> implements Supplier<T> {
    private T s;
    public MySupplier( T s ) {
        this.s = s;
    }
    public T get() {
        System.out.println( String.format( "Lazy loading '%s'", s ) );
        return s;
    }
}

public void lazyLoad() {
    List<MySupplier<String>> list = Lists.newArrayList( new MySupplier<String>( "a" ), new MySupplier<String>( "a" ), new MySupplier<String>( "b" ), new MySupplier<String>( "c" ), new MySupplier<String>( "d" ) );

    for ( Iterator<String> i = supplierIterator( list ); i.hasNext(); ) {
        System.out.println( i.next() );
    }
}

public static <T> Iterator<T> supplierIterator( Collection<? extends Supplier<T>> c ) {
    Function<Supplier<T>, T> function = Suppliers.supplierFunction();
    Iterable<T> iterable = Iterables.transform( c, function );
    return iterable.iterator();
}

【讨论】:

  • 谢谢,我忘记了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-02-12
  • 2012-05-04
  • 2018-05-02
  • 1970-01-01
  • 2023-04-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多