【问题标题】:Are there any more elegant ways of handling lists in Java ? (Python VS Java)有没有更优雅的方式来处理 Java 中的列表? (Python VS Java)
【发布时间】:2011-06-07 10:04:32
【问题描述】:

我确实喜欢在 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<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)));
    }
}

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

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

ArrayList<Integer> sol_rec = new ArrayList<Integer>(sol);
sol_rec.add(n);

这很丑陋,更复杂的解决方案会变得更糟。喜欢this example

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

【问题讨论】:

  • 总有 Jython :)
  • 标题中的more 是多余的——问题应该是在Java 中是否有任何巧妙的方式来处理列表。和 afaik,不 - 没有。

标签: java python list operators language-design


【解决方案1】:

没有。

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

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

【讨论】:

  • 我认为 Jython 是 Java 世界的 Python ;-)。
【解决方案2】:

您可以在列表上使用clone() 函数来获取它们的浅表副本。这样您就不必自己实例化新对象,而只需使用副本即可。

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

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

【讨论】:

    【解决方案3】:

    嗨 1 可以使用stack,这样会更方便。

    2 for 循环可以这样写: for(数字 n:数字)

    【讨论】:

      【解决方案4】:

      Apache Commons 解决了很多此类问题。查看ArrayUtils 进行切片。由于各种原因,Java 不像脚本语言那样有很多语法糖。

      【讨论】:

        【解决方案5】:

        不同的语言需要不同的风格。尝试在 java 中完成mylist[:i] + mylist[i+1:] 就像使用带螺丝的锤子一样。是的,你可以做到,但它不是很整洁。我相信等价物可能类似于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<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);
                 }
              } 
        
           }
        }
        

        python 方式可能看起来简单而干净,但看起来干净的能力往往掩盖了解决方案效率很低的事实(对于每个递归级别,它都会创建 5 个新列表)。

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-01-08
          • 1970-01-01
          • 2021-11-10
          • 1970-01-01
          • 2011-01-24
          • 2010-10-24
          相关资源
          最近更新 更多