Есть ли еще более элегантные способы обработки списков на 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<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)));
 }
}
</integer></integer></integer></integer></integer></integer></numbers.size();i++)></integer></integer>

Чтобы создать ту же рекурсию, мне нужно сделать:

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

Это довольно уродливо, и для более сложных решений это ухудшается. Как в этом примере

Итак, мой вопрос: есть ли какие-либо buil-in операторы или вспомогательные функции в Java API, которые сделают это решение более "Pythonic"?

5 ответов

Нет.

Но вот почему Мартин Одерский создал Scala. Он даже сказал, что одна из его целей для Scala заключается в том, что это Python в мире Java. Scala компилируется в байт-код Java и легко перехватывает классы, скомпилированные Java.

Если это не вариант, вы можете взглянуть на Библиотека коллекций Commons.


Вы можете использовать функцию clone() в списках, чтобы получить мелкую копию. Таким образом, вы не должны создавать экземпляр нового объекта самостоятельно, но можете просто использовать копию.

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

Кроме этого, нет, у java нет таких операторов для списков.


Для разных языков требуются разные стили. Попытка выполнить mylist[:i] + mylist[i+1:] в java - это как использовать молоток с винтом. Да, вы можете это сделать, но это не очень аккуратно. Я считаю, что эквивалент может быть чем-то вроде 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);
 }
 } 
 }
}
</t></list<t></t></t></t></t></list<t></list<t></t></list<t></t></integer></list<integer>

Путь python может выглядеть легко и чище, но способность выглядеть чистым часто скрывает тот факт, что решение довольно неэффективно (для каждого уровня рекурсии он создает 5 новых списков).

Но тогда мое собственное решение также не очень эффективно - вместо создания нескольких новых объектов он выполняет избыточные сравнения (хотя некоторые из них могут быть смягчены с помощью аккумуляторов).


Apache Commons решает много таких проблем. Посмотрите ArrayUtils, чтобы сделать нарезку. В Java не так много синтаксического сахара, как языки сценариев, по разным причинам.


Привет 1 вы можете использовать стек, который будет более удобным.

2 цикл for может быть записан следующим образом: для (Число n: числа)

licensed under cc by-sa 3.0 with attribution.