com.feilong.coreextension.util.CartesianProductUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of feilong Show documentation
Show all versions of feilong Show documentation
feilong is a suite of core and expanded libraries that include utility classes, http, excel,cvs, io classes, and much much more.
/*
* Copyright (C) 2008 feilong
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.feilong.coreextension.util;
import static com.feilong.core.bean.ConvertUtil.toList;
import static com.feilong.core.util.CollectionsUtil.get;
import static com.feilong.core.util.CollectionsUtil.newArrayList;
import static com.feilong.core.util.CollectionsUtil.size;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 笛卡尔乘积.
*
*
* 在数学中,两个集合X和Y的笛卡尓积(Cartesian product),又称直积,表示为X × Y,
*
* 第一个对象是X的成员而第二个对象是Y的所有可能有序对的其中一个成员。
* 假设集合A={a, b},集合B={0, 1, 2},则两个集合的笛卡尔积为{(a, 0), (a, 1), (a, 2), (b, 0), (b, 1), (b, 2)}。
*
* 类似的例子有,如果A表示某学校学生的集合,B表示该学校所有课程的集合,则A与B的笛卡尔积表示所有可能的选课情况。
*
*
* @author feilong
* @since 1.7.2
*/
public final class CartesianProductUtil{
/** The Constant LOGGER. */
private static final Logger LOGGER = LoggerFactory.getLogger(CartesianProductUtil.class);
/** Don't let anyone instantiate this class. */
private CartesianProductUtil(){
//AssertionError不是必须的. 但它可以避免不小心在类的内部调用构造器. 保证该类在任何情况下都不会被实例化.
//see 《Effective Java》 2nd
throw new AssertionError("No " + getClass().getName() + " instances for you!");
}
//---------------------------------------------------------------
/**
* 笛卡尔乘积(数组数组参数形式).
*
* 示例:
*
*
*
*
*
* Integer[] array1 = { 1, 2, 3 };
* Integer[] array2 = { 1, 2 };
* Integer[] array3 = { 5 };
* Integer[] array4 = { 4, 8 };
*
* LOGGER.debug(JsonUtil.format(cartesianProduct(v1, v2, v3, v4), 0, 4));
*
*
*
* 返回:
*
*
* [[1,1,5,4],[2,2,5,8],[3,1,5,4],[1,2,5,8],[2,1,5,4],[3,2,5,8],[1,1,5,4],[2,2,5,8],[3,1,5,4],[1,2,5,8],[2,1,5,4],[3,2,5,8]]
*
*
*
*
* @param
* the generic type
* @param arrays
* the arrays
* @return the list
*
* @see 笛卡尔乘积及java算法实现
* @see Iterative Cartesian
* Product in Java
* @see 程序使用说明
* @see "com.google.common.collect.Sets#cartesianProduct(Set...)"
* @see "com.google.common.collect.Lists#cartesianProduct(List...)"
* @see #cartesianProduct(Iterable)
* @since 1.7.2
*/
@SafeVarargs
public static List> cartesianProduct(T[]...arrays){
List> list = newArrayList();
for (T[] array : arrays){
list.add(toList(array));
}
return cartesianProduct(list);
}
/**
* 笛卡尔乘积(Iterable数组参数形式).
*
* 示例:
*
*
*
*
*
* List{@code >} result = cartesianProduct(toList(1, 2, 3), toList(1, 2), toList(5), toList(4, 8));
* LOGGER.debug(JsonUtil.format(result, 0, 4));
*
*
*
* 返回:
*
*
* [[1,1,5,4],[2,2,5,8],[3,1,5,4],[1,2,5,8],[2,1,5,4],[3,2,5,8],[1,1,5,4],[2,2,5,8],[3,1,5,4],[1,2,5,8],[2,1,5,4],[3,2,5,8]]
*
*
*
*
* @param
* the generic type
* @param iterables
* the iterables
* @return the list
* @see 笛卡尔乘积及java算法实现
* @see Iterative Cartesian
* Product in Java
* @see 程序使用说明
* @see "com.google.common.collect.Sets#cartesianProduct(Set...)"
* @see "com.google.common.collect.Lists#cartesianProduct(List...)"
* @see #cartesianProduct(Iterable)
* @since 1.7.2
*/
@SafeVarargs
public static List> cartesianProduct(Iterable...iterables){
List> list = toList(iterables);
return cartesianProduct(list);
}
//---------------------------------------------------------------
/**
* Cartesian product.
*
* @param
* the generic type
* @param
* the generic type
* @param iterables
* the iterables
* @return the list
* @since 1.7.2
*/
private static > List> cartesianProduct(Iterable iterables){
int length = 1;
for (Iterable iterable : iterables){
length *= size(iterable);
}
//---------------------------------------------------------------
List> returnList = new ArrayList<>(length);
for (int i = 0; i < length; i++){
returnList.add(buildList(iterables, i));
}
return returnList;
}
/**
* Builds the list.
*
* @param
* the generic type
* @param
* the generic type
* @param iterables
* the iterables
* @param i
* the i
* @return the list
* @since 1.8.2
*/
private static > List buildList(Iterable iterables,int i){
//从不同的数组中取值
List list = newArrayList();
for (Iterable iterable : iterables){
list.add(get(iterable, i % size(iterable)));
}
//---------------------------------------------------------------
if (LOGGER.isDebugEnabled()){
LOGGER.debug(list.toString());
}
return list;
}
}