`
sing100star
  • 浏览: 28961 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

商品分类以及统计

阅读更多

     在卓越网首页的左边,或者当当网的左边,都有商品分类列表,并会显示旗下的商品有多少种。如何在计算机中描述?那可定是用树来表示。但要高效地完成这个功能会面临哪些问题?

    1、怎么统计某一分类的商品种类

    2、如果更改某一分类商品种类数量,怎么通知其他节点

    3、对于非叶子节,是否要记录商品数,

    4、如果增加新的商品类型,又怎么做

 

    对于这些问题,我认为关键的一点是:一旦有数据变化,就要通知双亲,直到根节点。这样一来,每当获取某一中分类的商品种类数时,它会检测是否收到通知,如果收到,则重新计算;否则直接返回数量。

    2011年9月,引入CommodityVisitor和CommoditySearcher,用来处理遍历和检索两种情况;重写计算商品分类数量的相关函数;删除多余函数。

   废话不多说,直接贴代码,欢迎拍砖。

 

 

/**
 * 商品分类
 */
public class CommodityClassify implements Cloneable {
    private static final int ZERO = 0;
    //*************************  节点属性  ******************************
    /**
     * 该分类名称
     */
    private String name;
    /**
     * 商品分数码
     */
    private String code;
    /**
     * 该分类下的商品种类数
     */
    private int amount = ZERO;
    /**
     * 是否要计算商品种类
     */
    private boolean needRecount = true;

    //*************************** 树形关系  *********************************
    /**
     * 双亲结点
     */
    private CommodityClassify parent;
    /**
     * 孩子结点
     */
    private List<CommodityClassify> children = Collections.synchronizedList(new LinkedList<CommodityClassify>());

    public CommodityClassify(String name, String code) {
        this(name, code, ZERO);
    }

    public CommodityClassify(String name, String code, int amount) {
        this.name = name;
        this.code = code;
        this.amount = amount;
    }

    /**
     * 调整节点的amount
     *
     * @param amount
     */
    public synchronized void adjustAmount(int amount) {
        //1、如果是叶子节点,则传入amount,否则跳过
        if (isLeafy() && this.amount != amount) {
            this.amount = amount;
            onAmountChange();
        }
    }

    /**
     * 判断是否为叶子节点
     */
    public boolean isLeafy() {
        return 0 == children.size();
    }

    /**
     * 计算当前节点的商品种类
     */
    public int calcAmount() {
        if (needRecount && !isLeafy()) {
            amount = ZERO;
            for (CommodityClassify cc : children) {
                amount += cc.calcAmount();
            }
            needRecount = false;
        }
        return amount;
    }

    /**
     * 返回深度
     *
     * @return
     */
    public int getDepth() {
        int depth = 1;
        CommodityClassify root = parent;
        while (root != null) {
            depth += 1;
            root = root.getParent();

        }
        return depth;
    }

    //*************************  getter/setter  ******************************
    protected void setChildren(List<CommodityClassify> children) {
        this.children = children;
    }

    public boolean isNeedRecount() {
        return needRecount;
    }

    private void setNeedRecount(boolean needRecount) {
        this.needRecount = needRecount;
    }

    public CommodityClassify getParent() {
        return parent;
    }

    public void setParent(CommodityClassify parent) {
        this.parent = parent;
    }

    public String getName() {
        return name;
    }

    public String getCode() {
        return code;
    }

    public List<CommodityClassify> getChildren() {
        return children;
    }

    public int getAmount() {
        return amount;
    }
    //*********************  节点操作  **********************

    /**
     * 增加孩子结点
     * 需要同步
     *
     * @param cc
     */
    private void addChild(CommodityClassify cc) {
        //1、设置双亲节点
        cc.setParent(this);
        //2、增加叶子节点
        children.add(cc);
        onAmountChange();
    }
    /**
     * 删除孩子节点
     *
     * @param cc
     */
    private void removeChild(CommodityClassify cc) {
        //1、待删除的节点清空双亲
        cc.setParent(null);
        //2、删除节点
        children.remove(cc);
        //3、通知变化
        onAmountChange();
    }
    /**
     * 返回根节点
     *
     * @return
     */
    private CommodityClassify getRoot() {
        CommodityClassify root = this;
        while (root.parent != null) {
            root = root.parent;
        }
        return root;
    }

    /**
     * 商品分类的数量变化时,重新计算
     */
    private void onAmountChange() {
        notifyParentChange();
        recountTotal();
    }

    /**
     * 通知双亲结点:数据已经改变
     */
    private void notifyParentChange() {
        //通知当前当前结点数据变化
        this.setNeedRecount(true);
        //通知双亲结点数据已经变化
        CommodityClassify parents = this.parent;
        while (parents != null) {
            parents.setNeedRecount(true);
            parents = parents.parent;
        }
    }

    /**
     * 重新计算 商品 总数
     */
    private void recountTotal() {
        this.getRoot().calcAmount();
    }


    //*************************  遍历 **************************

    /**
     * 广度优先遍历
     */
    public void breadthFirstTraversal(CommodityVisitor visitor) {
        Queue<CommodityClassify> queue = new LinkedList<CommodityClassify>();
        queue.add(this);
        while (!queue.isEmpty()) {
            CommodityClassify c = queue.poll();
            visitor.visit(c);
            queue.addAll(c.getChildren());
        }
    }

    /**
     * 返回层次遍历的的链表
     *
     * @return
     */
    public List<CommodityClassify> getBFTList() {
        List<CommodityClassify> list = new LinkedList<CommodityClassify>();
        int currentIndex = 0;
        list.add(this);
        while (currentIndex < list.size()) {
            if (!list.get(currentIndex).isLeafy()) {
                list.addAll(list.get(currentIndex).getChildren());    ///将子节点添加的list中
            }
            currentIndex++;
        }
        return list;
    }

    /**
     * 深度优先遍历 非递归算法   方向 :从右到左
     */
    public void depthFirstTraversal(CommodityVisitor visitor) {
        Stack<CommodityClassify> stack = new Stack<CommodityClassify>();
        stack.push(this);
        while (!stack.isEmpty()) {
            CommodityClassify c = stack.pop();
            visitor.visit(c);
            if (!c.isLeafy()) {
                stack.addAll(c.getChildren());
            }
        }
    }

    //*************************  检索 **************************

    /**
     * 广度优先检索
     */
    public CommodityClassify breadthFirstSearch(CommoditySearcher searcher) {
        Queue<CommodityClassify> queue = new LinkedList<CommodityClassify>();
        queue.add(this);
        while (!queue.isEmpty()) {
            CommodityClassify c = queue.poll();
            if (searcher.search(c)) {
                return c;
            }
            queue.addAll(c.getChildren());
        }
        return null;
    }

    /**
     * 深度优先检索
     */
    public CommodityClassify depthFirstSearch(CommoditySearcher searcher) {
        Stack<CommodityClassify> stack = new Stack<CommodityClassify>();
        stack.push(this);
        while (!stack.isEmpty()) {
            CommodityClassify c = stack.pop();
            if (searcher.search(c)) {
                return c;
            }
            if (!c.isLeafy()) {
                stack.addAll(c.getChildren());
            }
        }
        return null;
    }


    //***************************  常见操作 函数*******************************
    /**
     * 添加子商品分类
     * @param name   分类名称
     * @param code   分类编码
     * @param amount 数量
     * @return
     */
    public CommodityClassify addChild(String name, String code, int amount) {
        CommodityClassify c = new CommodityClassify(name, code, amount);
        addChild(c);
        return c;
    }

    public CommodityClassify addChild(String name, String code) {
        CommodityClassify c = new CommodityClassify(name, code);
        addChild(c);
        return c;
    }

    public CommodityClassify getByCode(final String code) {
        CommoditySearcher vs = new CommoditySearcher() {
            public boolean search(CommodityClassify c) {
                return (c.getCode().equals(code));
            }
        };
        return depthFirstSearch(vs);
    }
    /**
     * 把 当前树 从 整棵树中 剥离出来;
     */
    public void remove() throws Exception {
        if (this.getParent() == null) throw new Exception("根节点不能删除");
        //1、找到双亲
        parent = this.getParent();
        //2、删除当前树
        parent.removeChild(this);
    }

    /**
     * 删除商品分类
     * @param cc
     * @throws Exception
     */
    public void remove(CommodityClassify cc) throws Exception {
        if (this.getParent() == null) throw new Exception("根节点不能删除");
        if (this.equals(cc)) throw new Exception("不能删除自身");
        if (!this.children.contains(cc)) throw new Exception("不包含子节点");
        removeChild(cc);
    }
    //************************  其他 ********************************************
    public boolean equals(Object obj) {
        if (obj == null) return false;
        if (obj.getClass() != this.getClass()) return false;
        CommodityClassify c = (CommodityClassify) obj;
        return c.getCode().equals(this.getCode());
    }

    public Object clone() throws CloneNotSupportedException {
        super.clone();
        CommodityClassify c = new CommodityClassify(name, code, amount);
        List<CommodityClassify> ccList = Collections.synchronizedList(new LinkedList<CommodityClassify>());
        for (CommodityClassify cc : children) {
            CommodityClassify newCC = (CommodityClassify) cc.clone();
            newCC.setParent(c);
            ccList.add(newCC);
        }

        c.setChildren(ccList);
        return c;
    }
}  

  

 

 

public interface CommoditySearcher {
    public boolean search(CommodityClassify c);
}

 

 

 

public interface CommodityVisitor {
    public void visit(CommodityClassify cc);
}

 

 

分享到:
评论

相关推荐

    京东商城商品分类数据.zip

    这份名为“京东商城商品分类数据.zip”的压缩包文件内包含了一个名为“京东商城商品分类数据.xlsx”的Excel表格,它为我们揭示了京东商城内部的商品分类体系和结构,是理解电商运营、市场分析以及商品管理的重要参考...

    淘宝商品分类类目sql,真实60余万条数据 5级目录

    通过SQL文件,我们可以深入理解淘宝的商品分类体系,甚至可以进行各种数据分析,例如统计各个类别的商品数量、分析各级别目录下的商品分布等。这样的数据对于电商从业者、市场分析师、数据科学家以及对电商有兴趣的...

    联合国商品贸易统计数据使用指南.pptx

    在选择的商品分类中检索出需要的商品分类名称和编号,勾选前面方框(可多选),确认选择,选中商品分类在 中显示,点击,按照所选商品筛选检索,也可将所选存为自己的。 按报告国家检索选择报告国家来源,全部/用户...

    淘宝网商品分类, 淘宝网商品类目 sql文件

    总的来说,这个"淘宝网商品分类"数据集为研究淘宝商品生态、电商运营策略提供了宝贵的资源,对于数据分析师、电商从业者以及对电商市场感兴趣的个人都有着极高的价值。通过深入挖掘和利用这些数据,我们可以更深入地...

    java商品分类系统的代码实现,具有添加、修改、删除、查询和统计商品信息的功能.docx

    这个Java商品分类系统的设计和实现主要用于超市商品的管理,包括水果、蔬菜、肉类和零食的分类信息。系统的核心类`GoodsManager`使用ArrayList存储`Goods`对象,实现了商品的增删改查以及统计功能。 1. **添加商品*...

    京东全商品分类

    例如,库存管理系统会根据商品分类进行库存的分类统计,订单处理会根据分类来打包和发货,而搜索索引则会基于分类进行关键词匹配,提高搜索效率。因此,理解并有效利用这些分类数据对于优化京东商城的运营至关重要。

    淘宝商品类目数据共831247条,2019年全部淘宝分类MYSQL导出文件_2019 淘宝 产品 数据,2019年淘宝品类数据-MySQL其他资源

    标签“淘宝分类”、“淘宝商品分类”、“商品分类”强调了数据的核心内容,即与淘宝平台上的商品分类有关,涵盖了广泛的商品信息。 压缩包文件名为“taobao20190803003338”,可能是以日期和时间戳命名,便于管理和...

    超市商品分类的原则.pdf

    超市商品分类是零售业管理的重要环节,旨在提升运营效率,优化顾客购物体验。商品分类主要遵循三大原则:大分类、中分类和小分类。 大分类是最高级别的分类,通常不超过十个,依据商品的特性,如生产来源、生产方式...

    商品分类编码及商品自动化.pdf

    【商品分类编码与商业自动化】 商品分类编码是商业自动化中不可或缺的一部分,它的主要目标是将商品信息用标准化的符号体系表示出来,便于计算机处理和人类理解。随着科技的快速发展,信息处理的需求日益增长,自动...

    商品的分类及编码.doc

    3. 联合国国际贸易标准分类(SITC):另一种国际性的商品分类系统,主要用于统计目的。 4. 对外贸易进口业务统计商品目录:特定国家或地区的进口商品分类目录。 商品条码的使用流程通常包括: 1. 申请厂商代号:...

    国际贸易的基本统计指标与分类.pptx

    - 对外贸易:从单个国家或地区的视角,包括出口和进口,以及过境贸易(商品经过该国但不消费于此)。 - 区域贸易:几个国家或地区间的贸易互动。 - 国际贸易:全球范围内的商品和服务交换。 3. **基本统计指标**...

    商品分类规则PPT学习教案.pptx

    《商品分类规则PPT学习教案》是一份详细阐述商品分类及其重要性的教学材料,主要针对的是专业领域的知识,包括零售管理、供应链管理以及信息管理等多个方面。商品分类是商业运营中的核心环节,对于企业的决策制定、...

    超市商品分类管理.zip

    - 商品分类统计:统计各类商品的数量,提供销售决策参考。 5. 用户界面设计: 虽然C语言不擅长图形用户界面(GUI)开发,但可以通过命令行交互方式实现简单的操作界面。使用`printf`和`scanf`进行输入输出交互,...

    联合国商品贸易统计数据库数据搜集ppt课件.ppt

    - 用户可以通过这个数据库获取各国的贸易总量数据,包括进口、出口以及按商品分类的数据。 - BEC分类系统用于商品的详细分类,便于深入分析特定产品的贸易行为。 - 数据可以按照时间序列分析,揭示贸易趋势和经济...

    第十一章商品流通与外贸统计 .ppt

    《第十一章 商品流通与外贸统计》主要涵盖了四个核心领域:商品供需统计、商品流转统计、商品价格统计以及对外贸易统计。以下将详细介绍这些领域的关键知识点。 首先,商品供需统计是研究商品从生产到消费过程中的...

    联合国商品贸易统计数据使用指南培训课件.ppt

    在商品检索中,用户可以选择商品分类,输入关键词搜索商品名称,或者通过商品分类编码进行查找。报告国家和交易国家的检索同样灵活,支持多选和自定义国家群体。年份检索允许用户按特定年份或年份范围进行筛选。此外...

    国际贸易商品分类PPT学习教案.pptx

    国际贸易商品分类是全球经济活动中至关重要的一个环节,它用于标准化不同国家间商品的识别、统计和关税征收。在国际贸易中,有几种主要的商品分类系统被广泛采用,这些系统为全球贸易的顺畅运作提供了基础。 首先,...

    连锁超市商品分类明细表.doc

    《连锁超市商品分类明细表》是对超市经营商品进行精细化管理的重要工具,主要用于规范商品的存储、销售和统计工作。这份文档详细列出了商品的分类体系,涵盖了食品、饮料烟酒、副食、粮油、生鲜、日配、散装加工、...

Global site tag (gtag.js) - Google Analytics