将多个过滤器应用于对象的ArrayList

时间:2017-05-26 08:43:36

标签: java filtering

这是我多年来潜伏在StackOverflow上的第一个问题。 我应该说清楚我不是一个非常高级的程序员,并且主要是为工作创建实用工具,请保持简单。

我有一个显示'OrderLine'视图的程序。这些OrderLines有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"};

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

即。如果选择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&amp; packSize分别。例如,如果用户选择了多个产品组I.E. 'ENG,HYD,IND',没有产品会被添加到orderList中,因为当从上面的代码片段返回的String被要求查看它是否包含单个过滤器名称时

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天的时间来看这个,出于某种原因,我有一个心态障碍。我知道这可能是一个相当明显的解决方案,但它是让过滤器组合在一起工作的问题。

如果您可以建议我在这方面的错误出错,那将非常感激。

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

P.S。关于过滤列表的问题,我已经查看了很多细节,但是我在这里寻求帮助更多的是过滤的逻辑。我意识到有关于使用Streams和Lambda表达式的信息,如果你想添加它的信息请随意,但我遇到的根本问题是逻辑而不是语义。

非常感谢提前。

1 个答案:

答案 0 :(得分:0)

代码可能会改变如下。

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