2016-08-24 48 views
1

我正在爲前兩個簡單項目懶洋洋地創建一串字符串。但是,我的流的一部分是字符串列表。Java懶惰字符串包括列表<String>

Stream<String> streamA = Stream.concat(
     Stream.generate(item::getStringA), 
     Stream.generate(item::getStringB)) 

return Stream.concat(streamA, item.getStringList(param).stream()) 

上面的工作,但.getStringList也需要被懶惰地調用。我不清楚如何獲取它並將它合併到流的其餘部分。

回答

2

我想,你真正想做的事,是

return Stream.<Supplier<Stream<String>>>of(
    () -> Stream.of(item.getStringA()), 
    () -> Stream.of(item.getStringB()), 
    () -> item.getStringList(param).stream()) 
    .flatMap(Supplier::get); 

這將產生一個完全懶Stream<String>地方,例如.limit(0).count()不會呼籲item.findFirst()任何方法只會調用getStringA()

流的內容將相當於

Stream.concat(
    Stream.of(item.getStringA(), item.getStringB()), item.getStringList(param).stream()) 
+0

findFirst()正是我想要的。雖然路易斯的答案有效,但我覺得這至少對於一個「流媒體新手」來說更直觀一些。 – Joel

1

我不認爲這些都會影響你的想法。 Stream.generate總是產生一個無限流。但最接近你想要什麼將是

StreamSupport.stream(() -> item.getStringList(param).spliterator(), 0, false) 

...這將懶洋洋地打電話item.getStringList(param)。 (你想要的是不是真正的Stream預期的使用情況,所以它不是很好的支持。)

+0

我開始意識到多麼遙遠我。但是,我不認爲我會發現StreamSupport方法。看起來流是自然適合我所做的,但它似乎有點用這種方法的鞋角。 – Joel

+0

請注意,'StreamSupport.stream(供應商...)'將推遲到終端操作開始時的調用,但將流傳遞給'Stream.concat'已經具有終止流的作用。所以它不像你想像的那麼懶。此外,你不應該像'0'那樣傳遞任意特性。該規範明確指出,特性必須與分割器的特性相同,因此您應該在使用此方法時精確知道您正在做什麼。當源是「List」時,它們必須包含至少'ORDERED | SIZED | SUBSIZED' – Holger

-1

你可以做的是從你的item.getStringList()

public static void main(String[] args) throws InterruptedException { 
    Item item = new Item(); 
    Stream<String> a = Stream.concat(Stream.of("A"), Stream.of("B")); 

    Stream<String> anotherStream = Stream.concat(a, item.getStringList()); 


    anotherStream.forEach(System.out::println); 
} 

private static class Item { 

    public Stream<String> getStringList() { 
     List<String> l = new ArrayList<>(); 

     l.add("C"); 
     l.add("D"); 
     l.add("E"); 
     l.add("F"); 
     final AtomicInteger i = new AtomicInteger(0); 
     return Stream.iterate(l.get(i.get()), (f) -> { 
      // Proof of laziness 
      try { 
       Thread.sleep(1000); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
      return l.get(i.getAndIncrement()); 
     }) 
     // Iterate is by default unbound 
     .limit(l.size()); 
    } 
} 

返回Stream我不知道因爲你的列表仍然在內存中,這種方法仍然有幫助。