2016-04-14 26 views
8

varsayalım setn element ve k ile HashSet bazı int0 arasındadır (dahil) ve n (hariç).Verimliliği.(). FindFirst atlama()

Birisi, basitçe, bunu yaptığınızda aslında ne olduğunu açıklayabilir mi?

set.stream().skip(k).findFirst(); 

Özellikle, bunun zaman karmaşıklığı nedir? Collection arabirimine spliterator() eklenmesi, Java 7 ile mümkün olabileceğinden, koleksiyonların "rastgele" öğelerine daha hızlı erişebildiğimiz anlamına mı geliyor?

+2

Genelde konuşma, hayır ve HashSet ile değil. HashSet.spliterator() '' SİPARİŞLİ 'özelliğine sahip değildir, dolayısıyla burada tanımlanmamış bir davranış olabilir. –

+0

@LouisWasserman Teşekkürler, düşündüm ama sadece onay istedi. –

+1

'Spliterator' arabiriminin kendisinin 'at' yöntemine veya işaretçiyi geçerli öğeye taşımanın başka bir yoluna sahip olmadığını fark edebilirsiniz. Dolayısıyla, “rastgele” koleksiyon koleksiyonlarına “daha ​​hızlı erişim” uygulamalarının hiçbir yolu yoktur. – Holger

cevap

6

Güncel uygulama aşağıdaki Ç (k) karmaşıklığı ve moreless eşdeğer sahiptir. @ The8472 cevabında belirtilen kod parçası sadece paralel akışlar için çalışır. Paralel durumda amortize edilmiş karmaşıklık kabaca O (k/n) dir, burada n işlemci sayısıdır.

3

louis o anda aşağıdaki yöntem bazı durumlarda uzak atlamak optimize eden bir biçimde uygulanan (jdk 1.8) var aslında gerçekten sırasız akışlarında mantıklı değil atlama, bahseder gibi:

 Spliterator<T> unorderedSkipLimitSpliterator(Spliterator<T> s, 
                long skip, long limit, long sizeIfKnown) { 
      if (skip <= sizeIfKnown) { 
       // Use just the limit if the number of elements 
       // to skip is <= the known pipeline size 
       limit = limit >= 0 ? Math.min(limit, sizeIfKnown - skip) : sizeIfKnown - skip; 
       skip = 0; 
      } 
      return new StreamSpliterators.UnorderedSliceSpliterator.OfRef<>(s, skip, limit); 
     } 

budur geçerli çünkü kaynak koleksiyonunu farklı bir sıraya bölmekle eşdeğerdir.

Iterator<?> it = set.iterator(); 
for(int i=0; i<k && it.hasNext(); i++) it.next(); 
return it.hasNext() ? Optional.of(it.next()) : Optional.empty(); 

Güncel uygulama sıralı akışları için karakteristik hesaba ORDERED içine alır asla: