简体   繁体   English

使用供应商界面的Guava Lazy Collection

[英]Guava Lazy Collection using Supplier interface

I would like some kind of generic method to allow me to lazy load a collections contents based on use of the java.util.Collection.get( int ) method. 我希望某种通用方法允许我基于java.util.Collection.get(int)方法的使用来延迟加载集合内容。 I found the Supplier interface in Guava and this looks like a great way of doing the lazy loading, but how to make the loading invisible in java collections is something I am struggling with. 我在Guava中找到了Supplier接口,这看起来是完成延迟加载的一种好方法,但是如何使加载在Java集合中不可见是我所苦苦挣扎的事情。

Below is a sample lazy loading method that iterates through an iterator. 下面是一个通过迭代器迭代的示例惰性加载方法。

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() );
    }
}

I want to avoid having to use the Supplier.get() method if I can help it, but instead have a collections wrapper take care of it for me when Collection.get( int ) is called. 如果可以提供帮助,我想避免使用Supplier.get()方法,而是在调用Collection.get(int)时让一个Collections包装器为我处理。 I hope to achieve this in a simple method call that I called makeLazy( Collection ) below. 我希望通过一个简单的方法调用来实现这一目标,我在下面将其称为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 );
    }
}

I realise that I would need to override collections somehow, but my knowledge in this area has some gaps. 我意识到我需要以某种方式覆盖集合,但是我在这方面的知识还存在一些空白。 Could somebody give me some hints and tips on what I need to do to implement the makeLazy( Collection ) method? 有人可以给我一些提示和技巧来实现makeLazy(Collection)方法吗?

Thanks, Stuart 谢谢,斯图尔特

Based on the discussion with Louis Wasserman I decided to take his advice and use an iterator. 基于与Louis Wasserman的讨论,我决定听取他的建议并使用迭代器。 The solution below appears to be working for me. 以下解决方案似乎对我有用。

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();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM