Are there even more elegant ways to handle lists in Java? (Python VS Java)

I love the way I can handle lists in Python. This solution to any recursion looks easy and clean. For example, a typical problem of getting all permutations of elements in a list in Python looks like this:

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]) 

I like the way I can just get new instances of modified lists by doing things like numbers[:i] + numbers[i+1:] or sol + [numbers[i]]

If I try to specify the exact same thing in Java, it looks like this:

 import java.util.ArrayList; import java.util.Arrays; class rec { static void permutation_recursion(ArrayList<Integer> numbers, ArrayList<Integer> 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<Integer> remaining = new ArrayList<Integer>(numbers); remaining.remove(i); ArrayList<Integer> sol_rec = new ArrayList<Integer>(sol); sol_rec.add(n); permutation_recursion(remaining,sol_rec); } } static void get_permutation(ArrayList<Integer> numbers) { permutation_recursion(numbers,new ArrayList<Integer>()); } public static void main(String args[]) { Integer[] numbers = {1,2,3}; get_permutation(new ArrayList<Integer>(Arrays.asList(numbers))); } } 

To create the same recursion, I need to do:

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

This is pretty ugly, and for more complex solutions it gets worse. Like in this example

So my question is: are there any buil-in statements or helper functions in the Java API that will make this solution more Pythonic?

+7
source share
5 answers

Not.

But that's why Martin Odersky created Scala . He even said that one of his goals for Scala is that it is Python in the Java world. Scala compiles to Java bytecode and easily intercepts classes compiled by Java.

If this is not an option, you can take a look at the Commons Collection Library .

+8
source

You can use the clone() function in lists to get a shallow copy. Thus, you do not have to instantiate a new object yourself, but you can just use a copy.

 ArrayList<Integer> remaining = remaining.clone().remove(i); 

Other than that, no, java has no such operators for lists.

+2
source

Apache Commons solves a lot of these problems. Take a look at ArrayUtils to do the slicing. Java does not have as much syntactic sugar as scripting languages, for various reasons.

+1
source

Different languages ​​require different styles. Trying to execute mylist[:i] + mylist[i+1:] in java is how to use a hammer with a screw. Yes, you can do it, but it's not very neat. I believe the equivalent could be something like ArrayList temp = new ArrayList(list); temp.remove(index); ArrayList temp = new ArrayList(list); temp.remove(index);

I believe that the following performs the same task, but does it a little differently, but does not experience readability problems. Instead of creating a new list, it modifies the list, passes it, and returns the list to its previous state when the recursive call returns.

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

The python path may look easy and cleaner, but the ability to look clean often obscures the fact that the solution is quite inefficient (for each recursion level, it creates 5 new lists).

But then my own solution is also not very effective - instead of creating several new objects, it performs redundant comparisons (although some of them can be mitigated by using batteries).

+1
source

Hi 1, you can use the stack to be more convenient.

2 the for loop can be written as follows: for (Number n: numbers)

0
source

All Articles