以程序员编程的角度去理解笛卡尔积
笛卡尔积其实就是一种线性代数关系。 学过线性代数的人都知道,笛卡尔乘积通俗的说,就是两个集合中的每一个成员,都与对方集合中的任意一个成员有关联。
假设 A 表 数据:
假设B表数据:
那么A,B表的笛卡尔积为:
那么对于程序员来说怎么用程序员的角度去理解笛卡尔积呢?
其实笛卡尔积就相当与两个循环,首先循环A,再在A循环内循环B。所叠加的结果。我们以Java语言来做演示,用List,Map来模拟表数据结构。一个Map对应一行数据,List代表表数据集合。
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
public class ABTest {
/**
* @param args
*/
public static void main(String[] args) {
//表A
List<Map<String,Object>> A = new ArrayList<Map<String,Object>>();
//表B
List<Map<String,Object>> B = new ArrayList<Map<String,Object>>();
//模拟笛卡尔乘积表
List<Map<String,Object>> AB = new ArrayList<Map<String,Object>>();
//初始化A,B数据
initList(A,"A");
initList(B,"B");
//模拟笛卡尔积
int a_size = A.size();
int b_size = B.size();
Map<String,Object> row = null;
for(int a = 0; a < a_size; a++)
{
for(int b = 0; b < b_size; b++)
{
//if(B.get(b).get(key) == A.get(a).get(key)){//此处表示过滤条件,加上过滤条件就不是笛卡尔积了,
//但是这里可以模拟Where条件
//使用TreeMap使得Map中的Key值按一定的顺序排序
row = new TreeMap<String, Object>();
row.putAll(B.get(b));
row.putAll(A.get(a));
AB.add(row);
//}
}
}
System.err.println(AB);
}
static void initList(List<Map<String,Object>>list,String listName)
{
Map<String,Object> row = null;
int limit = ("A".equalsIgnoreCase(listName) ? 4 : 3);
int num = 0;
for(int i =1; i < limit; i++)
{
row = new Hashtable<String, Object>();
num = (i-1)*3;
if(i >= 2 && "A".equalsIgnoreCase(listName))
{
num = (i-1)*3-1;
row.put(listName+"1",listName+(num+1));
}
else if(i == 1 && "B".equalsIgnoreCase(listName))
{
row.put(listName+i,"A1");
}
else
{
row.put(listName+"1",listName+(num+1));
}
row.put(listName+"2",listName+(num+2));
row.put(listName+"3",listName+(num+3));
list.add(row);
}
}
}
运行结果:
[
{A1=A1, A2=A2, A3=A3, B1=A1, B2=B2, B3=B3},
{A1=A1, A2=A2, A3=A3, B1=B4, B2=B5, B3=B6},
{A1=A3, A2=A4, A3=A5, B1=A1, B2=B2, B3=B3},
{A1=A3, A2=A4, A3=A5, B1=B4, B2=B5, B3=B6},
{A1=A6, A2=A7, A3=A8, B1=A1, B2=B2, B3=B3},
{A1=A6, A2=A7, A3=A8, B1=B4, B2=B5, B3=B6}
]
比对结果是一致的(注:举例中没有使用ID是因为在A,B中都有ID字段,放到Map中会冲突,可能引起一些误解,所以演示案例将ID移除)。
使用过滤就是在以上代码的if语句中添加判断语句。
其他SQL查询可自行类比。