2016-04-09 49 views
8

Java 8 akışlarıyla çalışıyorum ve bunları hata ayıklamak için bir yol bulmak istiyorum. Yani böyle bir akışın bir aşamada unsurları basılmış filtre, bir şeyler yazmak diye düşündüm:İzleme Akışları

int[] nums = {3, -4, 8, 4, -2, 17, 9, -10, 14, 6, -12}; 
int sum = Arrays.stream(nums) 
    .filter(w -> {System.out.print(" " + w); return true;}) // trace 
    .map(n -> Math.abs(n)) 
    .filter(w -> {System.out.print(" " + w); return true;}) // trace 
    .filter(n -> n % 2 == 0) 
    .distinct() 
    .sum(); 
System.out.println(sum); 

Kapat ama yapmak doğru sınırlayıcılar olmadığı için bu, oldukça değil o okunaklı:

3 3 -4 4 8 8 4 4 -2 2 17 17 9 9 -10 10 14 14 6 6 -12 1256 

istediğim geçerli:

[3, -4, 8, 4, -2, 17, 9, -10, 14, 6, -12] 
[3 4 8 4 2 17 9 10 14 6 12] 
56 

bunu yapmanın bir daha standart bir yolu var mı? Bağlantılı makalenin dediği gibi Peek'in bunu yapmadığına dikkat edin, çünkü bir şekilde akışın tüm unsurlarını birlikte her aşamada toplamak istiyorum.

+1

'Peek' işlemini arıyoruz, bağlantılı soruyu kontrol edin. – Tunaki

+0

Peek işi yapmazdı. Soruma daha fazla ayrıntı ekledim. Bu bir def değil! – pitosalas

+1

Ah evet. Ancak bu nasıl işlemez: Akış tek bir boru hattıdır. Her eleman, tüketilene kadar baştan sona geçer. Ve bir sonraki için tekrarlayın. İstediğinizi elde etmek için birden fazla boru hattına sahip olmanız gerekir. Bir toplama çağrısı tüm akışı tüketir ve tekrar işleyemezsiniz. – Tunaki

cevap

9

Her denetim noktası için farklı bir liste kullanmanız gerekir.

Normal olarak, durumları bu şekilde değiştirmek için akış işlemlerini kullanmanızı önermem, ancak hata ayıklama amaçları için bunun iyi olduğunu düşünüyorum. Aslında, @BrianGoetz aşağıda belirtildiği gibi, hata ayıklama neden peek eklenmiştir nedeni oldu.

int[] nums = {3, -4, 8, 4, -2, 17, 9, -10, 14, 6, -12}; 
List<Integer> checkPoint1 = new ArrayList<>(); 
List<Integer> checkPoint2 = new ArrayList<>(); 
List<Integer> checkPoint3 = new ArrayList<>(); 
List<Integer> checkPoint4 = new ArrayList<>(); 
int sum = Arrays.stream(nums) 
       .peek(checkPoint1::add) 
       .map(n -> Math.abs(n)) 
       .peek(checkPoint2::add) 
       .filter(n -> n % 2 == 0) 
       .peek(checkPoint3::add) 
       .distinct() 
       .peek(checkPoint4::add) 
       .sum(); 
System.out.println(checkPoint1); 
System.out.println(checkPoint2); 
System.out.println(checkPoint3); 
System.out.println(checkPoint4); 
System.out.println(sum); 

Çıktı: Kendinizi çok sık sonra bir endeksli gözetleme işlevleri üreten bir statik sarıcı işlevi yazabiliriz Paul çözüm gerek buluyor

[3, -4, 8, 4, -2, 17, 9, -10, 14, 6, -12] 
[3, 4, 8, 4, 2, 17, 9, 10, 14, 6, 12] 
[4, 8, 4, 2, 10, 14, 6, 12] 
[4, 8, 2, 10, 14, 6, 12] 
56 
+0

Clever'e de başvurabilirsiniz. İşe benziyor gibi görünüyor. Ancak, çirkin bir şekilde, hepsinin hemfikir olduğuna eminim. Muhtemelen yapabileceğimiz en iyisi! – pitosalas

+0

Bu korkunç. Maalesef bu şeyleri ayıklamanın kolay bir yolu yok. –

+1

Bu yüzden 'peek()' ekledik. –

6

:

int sum = streamDebugger<Integer>((Supplier<Consumer<?>> peekGen) => { 
    return Arrays.stream(nums) 
       .peek(peekGen.get()) 
       .map(n -> Math.abs(n)) 
       .peek(peekGen.get()) 
       .filter(n -> n % 2 == 0) 
       .peek(peekGen.get()) 
       .distinct() 
       .peek(peekGen.get()) 
       .sum(); 
}) 

otomatikleştirmek için Bu bir adım daha ötesinde, tüm akış arabirim (ler) ini, her bir tanımlanmış arabirim yöntemi tekrar sarılmış bir döndürme döndürecek şekilde sarmalayabilir. otomatik boru hattında her adım için dikizlemek yapar ementation: uygulama oldukça sıkıcı ve umarım gerekli değildir olurdu bu yana

int sum = debugIntStream(Arrays.stream(nums)) 
       .map(n -> Math.abs(n)) 
       .filter(n -> n % 2 == 0) 
       .distinct() 
       .sum(); 

uygulama okuyucuya bırakılmıştır.