如何用Java生成笛卡尔积?
我有一些ArrayList
,每个ArrayList
都有对象,每个ArrayList
可以有不同的长度。 我需要生成排列,如下例所示:
假设我有2个arraylist
arraylist A具有对象a,对象b和对象c
arraylist B有对象d,对象e
那么输出应该是6个新的arraylist与这个组合:
组合1对象a和对象d,
组合2对象a和对象e,
组合3对象b和对象d,
组合4对象b和对象e,
组合5对象c和对象d,
组合6对象c和对象e,
谁能帮我?
番石榴19+
Lists.cartesianProduct(List...)
例如 :
List
输出 :
[[a, d], [a, e], [b, d], [b, e], [c, d], [c, e]]
使用Java8
流
List a = Arrays.asList("a", "b", "c"); List 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));
产量
[[a, d], [a, e], [b, d], [b, e], [c, d], [c, e]]
得到List
List> ll = a.stream().flatMap(ai -> b.stream().map(bi -> new ArrayList<>(Arrays.asList(ai, bi)))).collect(Collectors.toList());
使用Iterable + Iterator:
import java.util.*; class CartesianIterator implements Iterator > { private final List
> lilio; private int current = 0; private final long last; public CartesianIterator (final List
> llo) { lilio = llo; long product = 1L; for (List lio: lilio) product *= lio.size (); last = product; } public boolean hasNext () { return current != last; } public List next () { ++current; return get (current - 1, lilio); } public void remove () { ++current; } private List get (final int n, final List > lili) { switch (lili.size ()) { case 0: return new ArrayList (); // no break past return; default: { List inner = lili.get (0); List lo = new ArrayList (); lo.add (inner.get (n % inner.size ())); lo.addAll (get (n / inner.size (), lili.subList (1, lili.size ()))); return lo; } } } } class CartesianIterable implements Iterable > { private List
> lilio; public CartesianIterable (List
> llo) { lilio = llo; } public Iterator
> iterator () { return new CartesianIterator (lilio); } }
您可以在简化的for循环中使用它们:
class CartesianIteratorTest { public static void main (String[] args) { List la = Arrays.asList (new Character [] {'a', 'b', 'c'}); List lb = Arrays.asList (new Character [] {'d', 'e'}); List > llc = new ArrayList
> (); llc.add (la); llc.add (lb); CartesianIterable ci = new CartesianIterable (llc); for (List lo: ci) show (lo); } public static void show (List lo) { System.out.print ("("); for (Object o: lo) System.out.print (o); System.out.println (")"); } }
使用嵌套for循环,如下所示,每个ArrayList都有一个循环。 我假设我有两个ArrayLists – intList和stringList。 我可以有两个嵌套的for循环(每个列表一个)来生成排列。
for(Integer i : intList){ for (String s : stringList) { ... } }