¿Hay formas más elegantes de manejar listas en Java? (Python VS Java)

Me gusta la forma en que puedo tratar las listas en Python. Hace que cualquier solución recursiva parezca fácil y limpia. Por ejemplo, el problema típico de obtener todas las permutaciones de los elementos en una lista, en Python se ve así:

def permutation_recursion(numbers,sol): if not numbers: print "this is a permutation", sol for i in range(len(numbers)): permutation_recursion(numbers[:i] + numbers[i+1:], sol + [numbers[i]]) def get_permutations(numbers): permutation_recursion(numbers,list()) if __name__ == "__main__": get_permutations([1,2,3]) 

Me gusta la forma en que puedo obtener nuevas instancias de listas modificadas haciendo cosas como numbers[:i] + numbers[i+1:] o sol + [numbers[i]]

Si trato de codificar exactamente lo mismo en Java, parece que:

 import java.util.ArrayList; import java.util.Arrays; class rec { static void permutation_recursion(ArrayList numbers, ArrayList sol) { if (numbers.size() == 0) System.out.println("permutation="+Arrays.toString(sol.toArray())); for(int i=0;i<numbers.size();i++) { int n = numbers.get(i); ArrayList remaining = new ArrayList(numbers); remaining.remove(i); ArrayList sol_rec = new ArrayList(sol); sol_rec.add(n); permutation_recursion(remaining,sol_rec); } } static void get_permutation(ArrayList numbers) { permutation_recursion(numbers,new ArrayList()); } public static void main(String args[]) { Integer[] numbers = {1,2,3}; get_permutation(new ArrayList(Arrays.asList(numbers))); } } 

Para crear la misma recursión necesito hacer:

 ArrayList remaining = new ArrayList(numbers); remaining.remove(i); ArrayList sol_rec = new ArrayList(sol); sol_rec.add(n); 

Lo cual es bastante feo y empeora para soluciones más complejas. Como en este ejemplo

Entonces, mi pregunta es … ¿existen operadores incorporados o funciones de ayuda en la API de Java que harían a esta solución más “Pythonic”?

No.

Pero es por eso que Martin Odersky creó Scala . Incluso ha dicho que uno de sus objectives para Scala es que sea el Python del mundo Java. Scala comstack a bytecode Java y se interopla fácilmente con clases comstackdas de Java.

Si esa no es una opción, puede echar un vistazo a la Biblioteca de la Colección Commons .

Puede usar la función clone() en las listas para obtener una copia superficial de ellas. De esa manera, no tendrá que crear una instancia de un nuevo Objeto, sino que solo puede usar la copia.

 ArrayList remaining = remaining.clone().remove(i); 

Aparte de eso, no, Java no tiene tales operadores para listas.

Apache Commons resuelve muchos de estos tipos de problemas. Echa un vistazo a ArrayUtils para hacer rebanar. Java no tiene mucha azúcar sintáctica como lo hacen los lenguajes de scripting por varias razones.

Diferentes idiomas requieren diferentes estilos. Tratar de lograr mylist[:i] + mylist[i+1:] en java es como usar un martillo con un tornillo. Sí, puedes hacerlo, pero no está muy ordenado. Creo que el equivalente podría ser algo como ArrayList temp = new ArrayList(list); temp.remove(index); ArrayList temp = new ArrayList(list); temp.remove(index);

Creo que lo siguiente cumple la misma tarea, pero lo hace de una manera ligeramente diferente, pero no sufre problemas de legibilidad. En lugar de crear una nueva lista, modifica la lista, la pasa y la devuelve a su estado anterior cuando vuelve la llamada recursiva.

 import java.util.Arrays; import java.util.List; import java.util.ArrayList; public class Permutation { public static void main(String[] args) { List> result = permutations( Arrays.asList( new Integer[] {1,2,3})); for (List permutation : result) { System.out.println(permutation); } } public static  List> permutations(List input) { List> out = new ArrayList>(); permutationsSlave(input, new ArrayList(), out); return out; } public static  void permutationsSlave(List input, ArrayList permutation, List> result) { if (input.size() == chosen.size()) { result.add(new ArrayList(permutation)); return; } for (T obj : input) { if (!permutation.contains(obj)) { permutation.add(obj); permutationsSlave(input, permutation, result); permutation.remove(permutation.size()-1); } } } } 

La forma de Python puede parecer fácil y limpia, pero la capacidad de verse limpia a menudo oculta el hecho de que la solución es bastante ineficiente (para cada nivel de recursión crea 5 nuevas listas).

Pero mi propia solución tampoco es terriblemente eficiente: en lugar de crear múltiples objetos nuevos, realiza comparaciones redundantes (aunque parte de esto podría aliviarse mediante el uso de acumuladores).

Hola 1 puedes usar la stack, que será más útil.

2 el bucle for se puede escribir así: para (Número n: números)