Streamy, mapowanie jednego parametru na dwa

0

Google mnie zawiodło.

Tak z ciekawości:
Czy jest sposób, aby w streamie z jednego parametru zrobić dwa - tak, żeby każdemu początkowemu elementowi odpowiadały dwa elementy. Chodzi mi o to, żeby pętlę:

public void test(){
	List<String> list = Arrays.asList("S1", "S22", "SS3");
	for(String string: list){
		System.out.println("Number of letters="+countLetters(string) + "\tNumber of digits=" + countDigits(string));
	}
}

Wiem, że można to zrobić w ten sposób:

public void test(){
	List<String> list = Arrays.asList("S1", "S22", "SS3");
        list.stream().forEach(x -> System.out.println("Number of letters="+countLetters(x) + "\tNumber of digits=" + countDigits(x)));
}

Ale chciałbym na końcu mieć BiConsumer'a, a nie zwykłego Consumer'a, np:

        List<String> list = Arrays.asList("S1", "S23", "SS3");
        BiConsumer<Integer, Integer> consumer = (Integer a, Integer b) -> System.out.println("Number of letters=" + a + "\tNumber of digits=" + b);

        list.stream() 
		// magia która zmapuje mi stringa na dwie liczby
			.forEach(x,y -> consumer);

Czy w ogóle da się coś takiego zrobić?

0

Zwroc krotke w funkcji mapujacej, idea w scali (bo javy nie znam).

List("1", "2", "3")
  map { x => (x.toInt, x.toInt) }
  foreach { case (a,b) => println("a = " + a + ", b = " + b) }
1

Krotki nie znajdują się pakietach Javy. Możesz wziąć Pair z Apache Commons lub z javafx albo wykorzystać do tego tablicę:

 list.stream().map(a -> new int[]{countLetters(a), countDigits(a)})
    .forEach(a -> biConsumer.accept(a[0], a[1]));

Istnieje także biblioteka z krotkami: http://www.javatuples.org/

0

No, ewentualnie napisac samemu....

/* package whatever; // don't place package name! */

import java.util.*;
import java.lang.*;
import java.io.*;

/* Name of the class has to be "Main" only if the class is public. */

class Pair<A, B> {
	private final A a;
	private final B b;
	
	public Pair(A _a, B _b) { a = _a; b = _b; }
	
	public final A first() { return a; }
	public final B second() { return b; }
	
	@Override
	public String toString() { return "Pair(" + a + ", " + b + ")"; }
}

class Ideone
{
	public static void main (String[] args) throws java.lang.Exception
	{
		Pair<Integer, String> p = new Pair(10, "Hello");
		System.out.println(p);
	}
}
1

Ani tablica ani równe wariacje na temat krotek tu nie pomogą, bo w Javie nie ma "wielowyjścia" tak jak w Rubym czy Scali. Inaczej mówiąc nie można stworzyć kodu, który będzie zwracał dwa obiekty tak by można było je przekazać do BiConsumer. Najbliżej do tego efektu rozwiązaniu @JacaDev z wykorzystaniem Pair zamiast tablicy. Jednak nadal będzie to kod imperatywny, a nie funkcyjny ponieważ mówisz JAK ma zostać zrealizowanie wywołanie BiConsumer, a nie jak tylko że chcesz by coś zostało zrobione.

1 użytkowników online, w tym zalogowanych: 0, gości: 1