una otro otra multiplicación multiplicacion multidimensionales matrices listas lista hilos dentro crear con codigo java java-8 java-stream matrix-multiplication

java - otro - Cómo usar secuencias para encontrar pares de elementos de dos listas o multiplicación de matrices



multiplicacion de matrices con hilos java (5)

Tengo dos listas de números y me gustaría encontrar todos los pares de números posibles. Por ejemplo, dadas las listas [1, 2, 3] y [3, 4] el resultado debe ser [(1, 3), (1, 4), (2, 3), (2, 4), (3 , 3), (3, 4)].

Sé que puedo hacer esto usando un bucle for pero ¿hay alguna forma más concisa de hacerlo usando flujos de Java 8?

Intenté lo siguiente, pero me estoy perdiendo algo porque obtengo la List<Stream<int[]>> lugar de la List<int[]> .

public static void main(String[] args) { List<Integer> list1 = Arrays.asList(1, 2, 3); List<Integer> list2 = Arrays.asList(3, 4); List<int[]> pairs = list1.stream().map(i -> list2.stream().map(j -> new int[] { i, j })) .collect(Collectors.toList()); pairs.forEach(i -> { System.out.println("{" + i[0]+ "," + i[1]+ "}"); }); }


Aquí hay una solución que usa IntStream con dos arreglos int como fuente en lugar de List<Integer> . Quería ver si era posible resolver este problema sin encasillar todos los int como un Integer .

int[] one = new int[]{1, 2, 3}; int[] two = new int[]{3, 4}; List<IntIntPair> list = new ArrayList<>(); IntStream.of(one).forEach(i -> IntStream.of(two).mapToObj(j -> PrimitiveTuples.pair(i, j)).forEach(list::add)); System.out.println(list); // [1:3, 1:4, 2:3, 2:4, 3:3, 3:4]

Desafortunadamente, no pude usar flatMap en IntStream ya que devuelve un IntStream . Actualmente no hay flatMapToObj en IntStream , que es lo que se necesitaría aquí. Así que usé forEach en forEach lugar.

Las clases IntIntPair y PrimitiveTuples que usé de Eclipse Collections , ya que simplificaron la salida de la lista como una cadena. Podría usar int[] como lo tiene en su solución. El código se vería como sigue.

List<int[]> list = new ArrayList<>(); IntStream.of(one).forEach(i -> IntStream.of(two).mapToObj(j -> new int[]{i, j}).forEach(list::add));

En la versión 8.1 de Eclipse Collections (que se lanzará a mediados de marzo), ahora existe un método flatCollect en todos los contenedores primitivos de la biblioteca que se puede usar para resolver este problema. Básicamente, esto hace lo que debería hacer un método IntStream en IntStream .

IntList a = IntLists.mutable.with(1, 2, 3); IntList b = IntLists.mutable.with(3, 4); List<IntIntPair> result = a.flatCollect( i -> b.collect(j -> PrimitiveTuples.pair(i, j)), Lists.mutable.empty()); System.out.println(result); // [1:3, 1:4, 2:3, 2:4, 3:3, 3:4]

Actualizar:

Como se señaló en los comentarios de Boris the Spider, la solución forEach no sería segura para subprocesos y se rompería si el IntStream fuera parallel . La siguiente solución debería funcionar en serie o en paralelo. Me alegro de que esto haya sido señalado, porque no había pensado hacer un mapToObj en el IntStream y luego seguí un flatMap .

int[] one = new int[]{1, 2, 3}; int[] two = new int[]{3, 4}; List<int[]> list = IntStream.of(one).parallel() .mapToObj(i -> IntStream.of(two).mapToObj(j -> new int[]{i, j})) .flatMap(e -> e) .collect(Collectors.toList()); list.stream().map(e -> "{" + e[0] + "," + e[1] + "}").forEach(System.out::println);

Nota: Soy un comendador de Eclipse Collections .


En este caso particular, utilizando flatMap , incluso puede omitir una creación de matriz y hacer su código más simple así:

list1.stream() .flatMap(i -> list2.stream().map(j -> "{" + i+ "," + j + "}")) .forEach(System.out::println);


Solo necesitas reemplazar tu primer map() con flatMap() .


Use el método flatMap () en lugar de map () , combinará los flujos en uno. Consulte: Diferencia entre map () y flatMap () y flatMap () ejemplo


//return pair of numbers List<List<Integer>> pairs=numbers.stream() .flatMap(i -> numbers2.stream() .map(j -> Arrays.asList(i,j))) .collect(Collectors.toList()); pairs.stream().forEach(System.out::println);