问题
I have a number of ArrayList
with each ArrayList
having objects and each one can have different length. I need to generate permutation like in the below example:
suppose i have 2 arraylist
arraylist A has object a, object b and object c
arraylist B has object d, object e
Then the output should be 6 new arraylist with this combinations:
combination 1 object a and object d,
combination 2 object a and object e,
combination 3 object b and object d,
combination 4 object b and object e,
combination 5 object c and object d,
combination 6 object c and object e,
Can anyone help me?
回答1:
Guava 19+
Lists.cartesianProduct(List...)
E.g.:
List<Object> list1 = Arrays.asList("a", "b", "c");
List<Object> list2 = Arrays.asList("d", "e");
System.out.println(Lists.cartesianProduct(list1, list2));
Output:
[[a, d], [a, e], [b, d], [b, e], [c, d], [c, e]]
回答2:
With Java8
streams
List<String> a = Arrays.asList("a", "b", "c");
List<String> b = Arrays.asList("d", "e");
String[][] AB = a.stream().flatMap(ai -> b.stream().map(bi -> new String[] { ai, bi })).toArray(String[][]::new);
System.out.println(Arrays.deepToString(AB));
output
[[a, d], [a, e], [b, d], [b, e], [c, d], [c, e]]
To get as List
List<List<String>> ll = a.stream().flatMap(ai -> b.stream().map(bi -> new ArrayList<>(Arrays.asList(ai, bi)))).collect(Collectors.toList());
回答3:
With an Iterable+Iterator:
import java.util.*;
class CartesianIterator <T> implements Iterator <List <T>> {
private final List <List <T>> lilio;
private int current = 0;
private final long last;
public CartesianIterator (final List <List <T>> llo) {
lilio = llo;
long product = 1L;
for (List <T> lio: lilio)
product *= lio.size ();
last = product;
}
public boolean hasNext () {
return current != last;
}
public List <T> next () {
++current;
return get (current - 1, lilio);
}
public void remove () {
++current;
}
private List<T> get (final int n, final List <List <T>> lili) {
switch (lili.size ())
{
case 0: return new ArrayList <T> (); // no break past return;
default: {
List <T> inner = lili.get (0);
List <T> lo = new ArrayList <T> ();
lo.add (inner.get (n % inner.size ()));
lo.addAll (get (n / inner.size (), lili.subList (1, lili.size ())));
return lo;
}
}
}
}
class CartesianIterable <T> implements Iterable <List <T>> {
private List <List <T>> lilio;
public CartesianIterable (List <List <T>> llo) {
lilio = llo;
}
public Iterator <List <T>> iterator () {
return new CartesianIterator <T> (lilio);
}
}
You can use them in a simplified for-loop:
class CartesianIteratorTest {
public static void main (String[] args) {
List <Character> la = Arrays.asList (new Character [] {'a', 'b', 'c'});
List <Character> lb = Arrays.asList (new Character [] {'d', 'e'});
List <List <Character>> llc = new ArrayList <List <Character>> ();
llc.add (la);
llc.add (lb);
CartesianIterable <Character> ci = new CartesianIterable <Character> (llc);
for (List<Character> lo: ci)
show (lo);
}
public static void show (List <Character> lo) {
System.out.print ("(");
for (Object o: lo)
System.out.print (o);
System.out.println (")");
}
}
回答4:
Use nested for loops that would have a loop for every ArrayList as below. I am assuming I have two ArrayLists - intList and stringList. I can have two nested for loops (one for each list) to generate the permutation.
for(Integer i : intList){
for (String s : stringList) {
...
}
}
回答5:
Use Guava...here is an example of a Cartesian product of a list with itself:
public static void main(String[] args){
//How to do a cartesian product of a List of items
List<Integer> listToSelfMultiply = Arrays.asList(new Integer(1), new Integer(2), new Integer(3), new Integer(4));
LinkedList<Integer> linkedListCopy = Lists.newLinkedList(listToSelfMultiply);
for (Integer i:listToSelfMultiply) {
if(linkedListCopy.size() == 1) {
break;
}
linkedListCopy.remove();
System.out.println("" + Arrays.deepToString(Lists.cartesianProduct(Arrays.asList(i), linkedListCopy).toArray()) + "");
}
}
来源:https://stackoverflow.com/questions/8082595/how-do-i-generate-a-cartesian-product-in-java