SORU
11 ŞUBAT 2015, ÇARŞAMBA


Neden Java Akışları kez kapalı?

'Nin yürütme bir boru hattı gibi birçok kez istediğiniz gibi idam edilebilir IEnumerable,, bir akım olabilir Java sadece bir kez. yineledi aksine C#

Ölümcül bir operasyon için herhangi bir çağrı akışı, kullanılmaz hale kapatır. ''Güç bir sürü alır. özelliği bu

Bunun nedenini tahmin edebiliyorumdeğilteknik. Bu garip bir kısıtlama arkasında tasarım konuları nelerdi?

Edit: bahsettiğim şey göstermek, C Hızlı Sıralama aşağıdaki uygulanmasını değerlendirmek üzere#:

IEnumerable<int> QuickSort(IEnumerable<int> ints)
{
  if (!ints.Any()) {
    return Enumerable.Empty<int>();
  }

  int pivot = ints.First();

  IEnumerable<int> lt = ints.Where(i => i < pivot);
  IEnumerable<int> gt = ints.Where(i => i > pivot);

  return QuickSort(lt).Concat(new int[] { pivot }).Concat(QuickSort(gt));
}

Şimdi emin olmak için, bu hızlı bir nevi iyi bir uygulama olduğunu savunan değilim! Ancak lambda ifade akışı işlemi ile birlikte ifade gücünü büyük örneğidir.

Ve Java ile yapılabilir mi! Hatta kullanılmaz hale olmadan boş olup olmadığını akışı isteyemem.

CEVAP
11 ŞUBAT 2015, ÇARŞAMBA


Arka plan

Soru basit görünüyor olsa da, gerçek cevap mantıklı biraz bilgi gerektirir. Eğer sonuca atlamak istiyorsanız, aşağı doğru ilerleyin...

Karşılaştırma noktası Pick - Temel işlevsellik

Temel kavramlar kullanarak, C#'IEnumerable s kavramı daha yakından istediğiniz 56 ** çok yaratabilen Java's Iterable ile ilgilidir. IEnumerables IEnumerators oluşturun. Java Iterable Iterators oluşturun

Her kavram tarihi IEnumerable Iterable hem 'her' tarzı veri toplama üyeleri döngü içinde. izin vermek için temel bir motivasyon var, benzer, Onlar sadece daha fazla izin olarak bir basitleştirme, ve onlar da farklı gelişmeler ile bu aşamada geldi, ama önemli bir ortak özelliği ne olursa olsun.

Hadi karşılaştırmak özelliği: her iki dilde, eğer bir sınıf uygular IEnumerable/Iterableo zaman bu sınıf uygulamak gerekir en azından tek bir yöntem (C#, GetEnumerator Java iterator()). Her durumda, örnek (18*/Iterator*) veri şimdiki ve sonraki üyeleri erişim sağlayan döndü. Bu özellik için-her dil sözdizimi kullanılır.

Karşılaştırma noktası Pick - işlevselliği Geliştirilmiş

IEnumerable C# dili diğer özellikleri bir dizi sağlamak için uzatıldı (mostly related to Linq). Özellikler seçimleri, projeksiyonlar, toplamalardan, vb ekledi. Bu uzantıları, set-teoride kullanmak güçlü bir motivasyon, SQL ve İlişkisel Veritabanı kavramları benzer.

Java 8 de fonksiyonel programlama derecesi Dere ve Lambda kullanarak etkinleştirmek için eklenmiştir. Java 8 akışları öncelikle fonksiyonel programlama teori, ama motive olduğunu unutmayın. Ne olursa olsun, benzerlikler bir yeri vardır.

Bu da ikinci nokta. Geliştirmeleri C için yapılan# IEnumerable konsepti için bir geliştirme olarak uygulanmıştır. Java olsa da, geliştirmeler yapıldı uygulanan yaratarak yeni bir temel kavramlarını Lambda ve Akarsular, ve sonra da oluşturma nispeten önemsiz bir şekilde dönüştürmek Iterators Iterables Akarsuları, ve vize-versa.

Bu yüzden, Java Stream kavramı için IEnumerable karşılaştırarak eksik. Java Dere ve Koleksiyonları kombine API karşılaştırmak gerekir.

Java, Akarsu İterables, ya Yineleyicisi olarak aynı değildir

Akışı sorunları kullanımına aynı şekilde çözmek için tasarlanmıştır:

  • Kullanımına veri dizisi açıklayan bir yoludur.
  • Veri akışı Dönüşümleri Bir dizi açıklayan bir yoludur.

Bir *ile 24* veri bir değeri olsun, işleyebilir ve başka bir veri değeri.

Akarsular, fonksiyonları bir dizi birlikte zincir, sonra akışı için bir giriş değeri besleme ve kombine sırası gelen çıktı değeri olsun. Not, Java açısından, her fonksiyonu Stream tek bir örneği içinde saklanır. Akarsu API dönüşümü ifadelerin bir sıra zincir bir şekilde Stream örnekleri bir dizi bağlantı sağlar.

Stream konsepti tamamlamak için, veri kaynağı akışı ve akış tüketir terminal fonksiyon beslenmen gerek.

Yem akış değerleri bu şekilde aslında Iterable ama Iterable, bileşik bir fonksiyonu olduğunu bir kendisi değildir Stream bir bölüm olabilir.

Stream bir de tembel, sadece bir değer istemek için çalışır anlamda olması amaçlanmıştır.

Akarsuları: bunlar önemli varsayımlar ve özellikleri unutmayın

  • Java Stream bir dönüşüm motoru, bir devlet, bir veri öğesi, başka bir devlet olmanın dönüştürüyor.
  • veri akışı düzeni veya pozisyon kavramı yok, sadece istenir ne dönüşüm var.
  • akarsu çok kaynak, diğer akarsu, Kullanımına, İterables, Koleksiyonları da dahil olmak üzere, veri ile sağlanabilir
  • olamaz "" akışı, böyle olurdu "dönüşümü yeniden programlama". Sıfırla Veri kaynağı sıfırlama ne istediğinizi muhtemelen değildir.
  • mantıksal olarak sadece 1 veri öğesi yok 'uçuş' herhangi bir zamanda akış (akış paralel akış, hangi noktada olduğu sürece, başına iş parçacığı 1 öğe vardır.) Bu daha geçerli öğeler 'hazır' akışı temin edilecek veya akış toplayıcı toplama ve birden çok değer azaltmak için gerekebilir. var olan veri kaynağı bağımsızdır
  • Akarsu ilişkisiz (sonsuz), yalnızca veri kaynağı, toplayıcı ya da sonsuz olabilir) ile sınırlı olabilir.
  • Dere, bir akarsu filtreleme çıktı, başka bir akış. chainable vardır Ve bir akarsu tarafından dönüştürülmüş değerleri giriş sırayla farklı bir dönüşüm yapan bir akış sağlanabilir. Veriler, dönüştürülmüş haliyle yanındaki bir dere akar. Ve bir akış verileri müdahale çekin ve bir sonraki takmanız gerekmez.

C# Karşılaştırma

Ne zaman olduğunu düşündüğünüz bir Java Stream sadece bir kısmının kaynağı, akış ve toplama sistemi ve Dere ve Kullanımına sıklıkla kullanılan birlikte Koleksiyonları, o zaman hiç merak bu sıkı ilişki, aynı kavram olan neredeyse tüm gömülü tek IEnumerable kavram C#.

IEnumerable parçaları (ve yakın ilişkili kavramlar) Java Yineleyici, İterable, Lambda, ve Akış kavramları bütün olarak görünür.

IEnumerable, ve vize-versa daha zor olan Java kavramları yapabileceğiniz küçük şeyler vardır.


Sonuç

  • Burada tasarım problemi, diller arasındaki kavram eşleştirmede bir sorun yok.
  • Akışları farklı bir şekilde sorunları çözmek
  • Akarsu Java işlevselliği (şeyler yapmanın farklı bir yolu ekleyin, işlevsellik uzak almadan) ekleyin

Akarsu olarak sınıflandırmak için adil olan sorunları çözerken size daha fazla seçenek sunar ekleme 'güç arttırıcı', 'azaltma', 'götürmek', ya da 'kısıtlama'.

Neden Java Akışları kez kapalı?

Bu soruyu dere fonksiyon dizileri, veri değil çünkü yanlış. Akıntıyı besleyen veri kaynağına bağlı olarak, veri kaynağı sıfırlama, ve aynı, ya da farklı bir akış besleyebilirsiniz.

'Yürütme boru hattına birçok kez istediğimiz gibi, Java stream 'sadece bir kez. yinelenen olarak idam edilebilir s IEnumerable, aksine C#

Stream IEnumerable bir karşılaştırma yanlış olur. IEnumerable istediğiniz kadar birçok kez idam, olabilir demek için kullanıyorsunuz kapsamında en iyi olarak birçok kez istediğiniz gibi yinelenen olabilir Iterables Java ile karşılaştırılır. Stream IEnumerable kavramının bir alt kümesi ve veri kaynakları, ve bu nedenle bu alt değil temsil bir Java olur. yeniden

Ölümcül bir operasyon için herhangi bir çağrı akışı, kullanılmaz hale kapatır. ''Güç bir sürü alır. özelliği bu

İlk ifade doğru, bir bakıma. 'Güç' ifadesi değil. alır götürür Hala İEnumerables Akarsu karşılaştırma. Akışında terminal operasyon bir 'break' döngü. bir fıkra gibi. Her zaman eğer isterseniz başka bir akış var, özgürsünüz, ve yeniden sağlayabilir verileri gerekir. Eğer IEnumerable gibi Iterable, bu ifade için olduğunu düşünüyorsanız, tekrar, Java, sorun yok.

Bu teknik değil nedenini tahmin edebiliyorum. Bu garip bir kısıtlama arkasında tasarım konuları nelerdi?

Sebebi teknik ve bir Dere ne bir alt kümesi gibi basit bir sebepten. Stream alt kaynağı, akış Sıfırla bu yüzden veri kaynağını kontrol etmez. Bu bağlamda, bu çok garip değil.

Örnek QuickSort

Quicksort örnek imza:

IEnumerable<int> QuickSort(IEnumerable<int> ints)

Veri kaynağı olarak 43* *giriş şımart:

IEnumerable<int> lt = ints.Where(i => i < pivot);

Ayrıca, dönüş değeri veri kaynağı olan, IEnumerable de,, ve bu Tür bir operasyon olduğu için, bu arz sırası önemlidir. Eğer düşündüğünüz Java Iterable sınıf için uygun bir maç için bu, özellikle List uzmanlık Iterable beri listesidir kaynağı veri olan bir garanti sipariş veya yineleme, sonra eşdeğer Java kodu için kod olabilir:

Stream<Integer> quickSort(List<Integer> ints) {
    // Using a stream to access the data, instead of the simpler ints.isEmpty()
    if (!ints.stream().findAny().isPresent()) {
        return Stream.of();
    }

    // treating the ints as a data collection, just like the C#
    final Integer pivot = ints.get(0);

    // Using streams to get the two partitions
    List<Integer> lt = ints.stream().filter(i -> i < pivot).collect(Collectors.toList());
    List<Integer> gt = ints.stream().filter(i -> i > pivot).collect(Collectors.toList());

    return Stream.concat(Stream.concat(quickSort(lt), Stream.of(pivot)),quickSort(gt));
}    

Bir hata yeniden var olan, sıralama değerleri düzgün bir şekilde işlemek çoğaltmak değil, bir 'benzersiz bir değer' tür. not yok

Ayrıca not nasıl Java kodu kullanır, veri kaynağı (List) ve akış kavramları farklı nokta ve C# bu iki 'kişilikleri' ifade edebilir sadece IEnumerable. Ayrıca, ancak ben kullanmak List taban türü, kullanılabilir daha genel Collection ve bir küçük yineleyici-Akış dönüşüm, yapardım eskiden daha genel Iterable

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Amena

    Amena

    15 Kasım 2006
  • FullMag

    FullMag

    15 ŞUBAT 2007
  • Kevin Bruckert

    Kevin Brucke

    30 Aralık 2006