Estou aprendendo fluxos Java 8. Diga-me, como posso escrever um sortArray
método de forma mais compacta?
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);
}
}
fonte
Eu realmente gostei da idéia de usar um ordenado
Stack
, mas não é facilmente paralelizável e fiquei curioso em como resolver isso.Minha idéia é classificar índices de elementos desiguais e, dependendo da posição do índice, podemos distinguir durante a criação da matriz de resultados se um número é par ou não.
fonte
Acredito que o que você quer dizer com Java-8 é usar se
Stream
outras APIs introduzidas desde esse lançamento. Você já tem um código com muito bom desempenho na minha opinião. A maneira que eu poderia pensar em resolver o problema é a seguinte -Encontre os números ímpares e pares e seus mapeamentos para os índices atuais. De tal forma que valores iguais com seus índices permaneceriam fixos.
Sobre os números ímpares e seus índices, remapeie os valores ordenando-os naturalmente.
Feito tudo isso, mescle esses mapas pares e ímpares com base nos índices.
Recupere os valores desse resultado mesclado.
A implementação geral disso seria algo como -
fonte
Este é um teste de classificação por inserção com fluxos. A
nonSorted
matriz é transmitida e coletada para anew int[]
. Se o valor danonSorted
matriz é par, apenas é copiado; caso contrário, se for ímpar, uma ordenação por inserção será executada apenas para valores ímpares já presentes no resultado.fonte