Estoy aprendiendo Java 8 streams. Dime por favor, ¿cómo puedo escribir un sortArray
método más compacto?
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import static org.junit.Assert.assertArrayEquals;
public class TestStream {
/*
* Sort numbers in an array without changing even numbers position
*/
@Test
public void test_1() {
int[] nonSorted = new int[]{3, 4, 5, 2, 1, 6, 9, 8, 7, 0};
int[] expected = new int[]{1, 4, 3, 2, 5, 6, 7, 8, 9, 0};
Integer[] arr = sortArray(nonSorted);
int[] sorted = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
sorted[i] = arr[i];
}
assertArrayEquals(expected, sorted);
}
private Integer[] sortArray(int[] array) {
Map<Integer, Integer> even = extractEven(array);
Integer[] withoutEvens = removeEven(array);
int length = even.size() + withoutEvens.length;
Integer[] result = new Integer[length];
Arrays.sort(withoutEvens);
for (int i = 0; i < withoutEvens.length; i++) {
result[i] = withoutEvens[i];
}
even.forEach((k, v) -> {
System.arraycopy(result, k, result, k + 1, length - k - 1);
result[k] = v;
});
return result;
}
private Map<Integer, Integer> extractEven(int[] array) {
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < array.length; i++) {
if (array[i] % 2 == 0) {
map.put(i, array[i]);
}
}
return map;
}
private Integer[] removeEven(int[] array) {
ArrayList<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < array.length; i++) {
if (array[i] % 2 != 0) {
list.add(array[i]);
}
}
Integer[] a = new Integer[list.size()];
return list.toArray(a);
}
}
fuente
Realmente me gustó la idea de usar un ordenado
Stack
, pero no es fácilmente paralelizable y me dio curiosidad cómo resolverlo.Mi idea es ordenar índices de elementos desiguales y, dependiendo de la posición del índice, podemos distinguir durante la creación de la matriz de resultados si un número es par o no.
fuente
Creo que lo que quiere decir con Java-8 es usar
Stream
sy otras API introducidas desde ese lanzamiento. Sin embargo, ya tienes un código de muy buen rendimiento en mi opinión. La forma en que podría pensar en resolver el problema es la siguiente:Encuentra los números pares e impares y sus asignaciones a los índices actuales. De modo que incluso los valores con sus índices permanecerían fijos.
Sobre los números impares y sus índices, reasigne los valores ordenándolos naturalmente.
Una vez hecho todo esto, combine estos mapas divididos pares e impares basados en los índices.
Recupere los valores de este resultado combinado.
La implementación general de esto sería algo así como:
fuente
Esta es una prueba de inserción con secuencias. La
nonSorted
matriz se transmite y se recopila en anew int[]
. Si el valor de lanonSorted
matriz es par, solo se copia, de lo contrario, si es impar, se ejecuta una clasificación de inserción solo para valores impares ya presentes en el resultado.fuente