【问题标题】:Applying multiple filters to an ArrayList of Objects将多个过滤器应用于对象的 ArrayList
【发布时间】:2017-10-27 02:13:23
【问题描述】:

这是我潜伏多年后关于 StackOverflow 的第一个问题。 我要明确我不是一个非常高级的程序员,并且主要是为工作创建实用工具,请保持简单。

我有一个显示“OrderLine”视图的程序。这些 OrderLine 有 4 个属性,packSize、repCode、productGroup 和 productType 需要过滤。

不同的过滤选项如下:

String[] bulkNonBulk = new String[]{"Bulk", "Non Bulk", "Bulk Lubricant"};
String[] productGroup = new String[]{"BLK", "CUT", "ENG", "FRM", "GRS", "HYD", "IND", "MIS", "SS", "TNK", "TRA"};
String[] repCode = new String[]{"BJ", "BS1", "BS2", "FF", "HSE", "OFF", "PCH", "TMO", "TM"};
String[] packSize = new String[]{"1 Litre", "4 Litre", "5 Litre", "10 Litre", "20 Litre", "25 Litre", "60 Litre", "199 Litre", "200 Litre", "205 Litre", "208 Litre", "1000 Litre", "Litre"};

用户将拥有可以为每个属性选择的复选框,并且我需要显示与上述过滤器匹配的任何订单。

I.E.如果选择了 Bulk、Non Bulk、Liter 和 BS1 的过滤器,则需要返回具有这些属性的所有订单。

我遇到的问题与设置这些过滤器的逻辑有关。目前我有以下内容:

private void filterOrders()
{
    List<OrderLine> list = new ArrayList<>();

    for(OrderLine ol : orderListing)
    {
        boolean addOrderLine = false;
        if(ol.getOrderDate().before(currentEndDate) && 
                ol.getOrderDate().after(currentStartDate))
        {
            addOrderLine = true;
            for(CheckBoxFilter cbf : currentFilterList)
            {
                //ol.getFilterList simply returns a list of the filters.
                //cbf.getInternalName returns the name of the filter the CheckBox is associated with.
                if(!ol.getFilterList().toString().contains(cbf.getInternalName()))
                {
                    addOrderLine = false;
                }
            }
        }
        if(addOrderLine)
        {
            list.add(ol);
        }
    }

    filteredOrderLineList = list;
    for(OrderLine ooll : filteredOrderLineList)
    {
        System.out.println(ooll.toString());
    }
}

举个例子

OrderLine.getFilterList()

方法返回如下String ArrayList: "Non Bulk, OFF, ENG, 20",即分别为productType、repCode、productGroup & packSize。例如,如果用户选择了多个 productGroups I.E. 'ENG, HYD, IND', 不会将任何产品添加到 orderList 中,因为当从上面的代码 sn-p 返回的字符串被要求查看它是否包含单个过滤器名称时

cbf.getInternalName()

其中一个过滤器将返回 true:

ol.getFilterList().toString().contains(cbf.getInternalName()))

or ("Non Bulk", "OFF", "ENG", "20").contains("ENG)) //Above code with actual Strings

但是所有其他的都将返回 false,因为当 for 循环为前一个单独的过滤器完成时,下一个过滤器的名称如下所示,例如“HYD”。

ol.getFilterList().toString().contains(cbf.getInternalName()))

or ("Non Bulk", "OFF", "ENG", "20").contains("HYD")) //Above code with actual Strings

当然,因为我们仍然在同一个 OrderLine 循环中,并且它对上一个查询返回 true,所以我们希望将它添加到列表中。

我花了 3 天时间研究这个问题,但出于某种原因,我对此感到困惑。我知道这可能是一个相当明显的解决方案,但是问题在于让过滤器组合一起工作。

如果您能建议我在这方面的逻辑哪里出了问题,我们将不胜感激。

如果您需要有关所使用的类/方法的更多信息,请说。

附:我已经查看了很多关于过滤列表的问题的详细信息,但是我在这里寻求帮助的更多的是过滤的逻辑。我知道有关于使用 Streams 和 Lambda 表达式的信息,如果您想添加这方面的信息,请随意,但是我遇到的根本问题是逻辑而不是语义本身。

非常感谢。

【问题讨论】:

    标签: java filtering


    【解决方案1】:

    代码应该会改变如下。

    private void filterOrders()
    {
        List<OrderLine> list = new ArrayList<>();
    
        for(OrderLine ol : orderListing)
        {
            boolean addOrderLine = false; // need to ensure items outside date range not added      
            if(ol.getOrderDate().before(currentEndDate) && 
                  ol.getOrderDate().after(currentStartDate))
            {
                 addOrderLine = true;
                 for(CheckBoxFilter cbf : currentFilterList)
                 {
                     //ol.getFilterList simply returns a list of the filters.
                     //cbf.getInternalName returns the name of the filter the CheckBox is associated with.
                     if(!ol.getFilterList().toString().contains(cbf.getInternalName()))
                    {
                        addOrderLine = false;
                    }
                }
            }
            if(addOrderLine)
            {
                list.add(ol);
            }
        }
    
        filteredOrderLineList = list;
        for(OrderLine ooll : filteredOrderLineList)
        {
            System.out.println(ooll.toString());
        }
    }
    

    更新

    如果任何“列”的订单行与任何设置的过滤器匹配,则要求代码交付。

    缺少分组 - 每个过滤器需要直接与列关联,然后测试是否设置了任何可以完成

    在伪代码中:-

    for each item
       if in date
           for each column
               columnOk = false
               if column not filtered 
                   then columnOk = true
               else
    
                  for each filter on single column
                      if selected
                           columnOk = true
    
               if columnOk = false then reject
           if not rejected then add to list
    

    【讨论】:

    • 感谢您的回答,这是我的疏忽。我已经更新了我的问题,更具体地说明了我在第一种情况下没有遇到的问题。
    猜你喜欢
    • 1970-01-01
    • 2020-09-03
    • 1970-01-01
    • 2022-01-04
    • 2012-04-09
    • 1970-01-01
    • 2020-09-04
    • 1970-01-01
    • 2012-11-29
    相关资源
    最近更新 更多