2016-05-26 40 views
8

İki akışın kesişimini elde etme veya kesişimlerinin boş olup olmadığını bulma genellikle Java'da mümkün değildir, çünkü akışlar yalnızca bir kez kullanılabilir ve genel çözüm O(m*n) karmaşıklığına sahiptir . YineAkış kavşağının boş olmadığını belirleme

<T> boolean intersects(final Stream<T> c1, final Collection<T> c2) { 
    return c1.filter(c2::contains).findAny().isPresent(); 
} 

, hem bizim tedarikçileri temsil eğer sipariş: Biz altta yatan tedarikçinin doğası hakkında hiçbir şey bilmiyorsanız

, biz uzakta en fazla bir dere ve bir koleksiyonu ile alabilirsiniz koleksiyonlar aynı karşılaştırıcı kullanılarak sıralanmış (en basit durumda, ikis Comparable s)? Bu durumda, çözüm doğrusal karmaşıklığına sahip olacaktır (veya daha doğrusu, O(m*n), bakınız this cevabı).

Şimdi soru: Yukarıdaki doğrusal çözeltisi sadece Akış API (.. Yani girdi olarak iki akım kullanılarak) kullanılarak uygulanabilir?

+0

Akışlardaki veriler sipariş edilmişse, doğrusal çözümü uygulayıp uygulayamayacağınızı mı soruyorsunuz? –

+4

Yinelemeli çözümler ve akışlar birbirine uymuyor, bu yüzden yapabileceğiniz en iyi şey, akışlarda iterator() 'i çağırmak ve devam etmek. – Holger

+0

@JimMischel Evet, tam olarak – Bass

cevap

7

Sadece bir Set içine ikinci Akış toplamak ve ilk Çayı'nın herhangi elemanı Bu sette yer alan olup olmadığını sorabilirsiniz: doğrusal sayısı açısından ise

<T> boolean intersects(final Stream<T> c1, final Stream<T> c2) { 
    return c1.anyMatch(c2.collect(Collectors.toSet())::contains); 
} 

c1 dışarı set yapma içindeki öğeler ve contains, sabit zamanlı bir işlemdir.

+0

Teşekkürler, bu iyi bir çözümdür ve bellek ayak izi başına herhangi bir sınırlama belirlenmediği için, bu soruya cevap verir. Yine de, orijinal yinelemeli çözüm (iki yineleyiciden birini ilerleterek), akış tabanlı birinizin yaptığı sırada fazladan bellek gerektirmez. Herhangi bir yeni koleksiyon sunma ile aynı görevi doğrusal zamanda çözmek mümkün mü? – Bass

+3

@ Kısa cevap: hayır. Uzun cevap: noooooo. Temel olarak akışları yineleyicilere dönüştürmeden değil. –

+2

@Bass Ve bir yineleyici sahip olma sorunu, bir öğeyi kolayca "gözleyemeyeceğiniz" dir. 'Next() 'ile onu tüketmeniz gerekiyor, bu yüzden iki yineleyiciden birini ilerletmek çok daha zordur. – Tunaki

İlgili konular