有没有更优雅的方式来处理Java中的列表? (Python VS Java)

我喜欢用Python处理列表的方式。 它做任何递归解决方案看起来容易和干净。 例如,在Python中获取元素的所有排列的典型问题如下所示:

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

我喜欢通过像numbers[:i] + numbers[i+1:]sol + [numbers[i]]这样简单地获取修改列表的新实例的方式

如果我尝试在Java中编写完全相同的代码,它看起来像:

 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))); } } 

要创建相同的递归,我需要做:

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

这对于更复杂的解决方案来说非常难看并且变得更糟。 就像在这个例子中

所以我的问题是…… Java API中是否有任何内置运算符或辅助函数可以使这个解决方案更“Pythonic”?

没有。

但这就是Martin Odersky创建Scala的原因 。 他甚至说他对Scala的目标之一就是它是Java世界的Python。 Scala编译为Java字节码,并且可以轻松地与Java编译类进行交互。

如果这不是一个选项,你可以看看Commons Collection Library 。

您可以使用Lists上的clone()函数来获取它们的浅表副本。 这样你就不必自己实例化一个新对象,但只能使用副本。

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

除此之外,不,java没有列表的这样的运算符。

Apache Commons解决了很多这类问题。 看看ArrayUtils做切片。 由于各种原因,Java没有像脚本语言那样的大量语法糖。

不同语言需要不同的风格。 尝试在java中完成mylist[:i] + mylist[i+1:]就像使用带螺丝的锤子一样。 是的,你可以做到,但它不是很整洁。 我相信等价物可能类似于ArrayList temp = new ArrayList(list); temp.remove(index); ArrayList temp = new ArrayList(list); temp.remove(index);

我相信以下内容完成相同的任务,但是以略微不同的方式完成,但不会遇到可读性问题。 它不是创建新列表,而是修改列表,传递它,并在递归调用返回时将列表返回到先前的状态。

 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); } } } } 

python方式可能看起来简单和清晰,但看起来干净的能力通常隐藏了这样一个事实:解决方案效率非常低(对于每个递归级别,它创建5个新列表)。

但是我自己的解决方案也不是非常有效 – 它不是创建多个新对象而是执行冗余比较(尽管其中一些可以通过使用累加器来缓解)。

嗨1你可以使用堆栈,这将更方便。

2 for循环可以这样写:for(Number n:numbers)