以程序员编程的角度去理解笛卡尔积

以程序员编程的角度去理解笛卡尔积

笛卡尔积其实就是一种线性代数关系。 学过线性代数的人都知道,笛卡尔乘积通俗的说,就是两个集合中的每一个成员,都与对方集合中的任意一个成员有关联。

假设 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查询可自行类比。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chemyoo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值