如果一个小arrayList的所有元素都包含在另一个中,则有效地验证多次

时间:2015-05-18 22:47:36

标签: java performance arraylist

我有几个小数组列表(800~1500),对于每一个我必须在最佳时间内验证它是否包含评估数组列表中的所有项目。目标arrayList(比如说,tSet)和评估arrayList(eSet)都有1到5个元素。

我尝试了一系列简单的循环(当前实现),执行时间约为10个seonds,而containsAll(),执行时间不一致,范围从8秒到16秒(使用相同的tSet)。有这种不一致的原因吗?有没有更好的方法来执行此操作?

数组元素来自以下类:

public class ItemBD_Temp implements Comparable<ItemBD_Temp> {
private String sTabela;
private String sValor;
private String sNome;
...
}

还有compareTo()方法:

public int compareTo(ItemBD_Temp o) {
    String concatThis;
    String concatOther;
    if(this.sTabela.equals("*AnyTable*") || o.sTabela.equals("*AnyTable*")){
        concatThis = "";
        concatOther = "";
    }
    else if(this.sNome.equals("*AnyAtrib*") || o.sNome.equals("*AnyAtrib*")){
        concatThis = this.sTabela;
        concatOther = o.sTabela;
    }
    else if(this.sValor.equals("*AnyValue*") || o.sValor.equals("*AnyValue*")){
        concatThis = this.sTabela + this.sNome;
        concatOther = o.sTabela + o.sNome;
    }
    else{
        concatThis = this.sTabela + this.sNome + this.sValor;
        concatOther = o.sTabela + o.sNome + o.sValor;
    }

    return concatThis.compareTo(concatOther);
}

这是我到目前为止的一个非常简化的版本:

for(int j = 0; j < eSet.itens.size() && tSetAllowed == true; j++){
    itemFound = false;
    //CURRENT ITEM TO BE SEARCHED
    eItem = new ItemBD_Temp(eSet.itens.get(j));

    //CHECK IF CURRENT ITEM IS ON THE CURRENT tSet. IF FOUND, STOPS AND CHECKS NEXT eItem
    for(int k = 0; k < tSet.size() && itemFound == false; k++){
        tItem = tSet.get(k);

        if(tItem.compareTo(eItem) == 0){
            itemFound = true;
        }
        else{
            itemFound = false;
        }
    }

    //IF tItem WASN'T FOUND, THEN tSet CAN BE DISCARTED
    if(itemFound==false){
        tSetAllowed = false;
    }
}

编辑1: 为了使用arrayList.containsAll(),我还必须覆盖Equals方法,如下所示:

@Override
public int hashCode() {
        int hash = 3;
        hash = 89 * hash + (this.sTabela != null ? this.sTabela.hashCode() : 0);
        hash = 89 * hash + (this.sValor != null ? this.sValor.hashCode() : 0);
        hash = 89 * hash + (this.sNome != null ? this.sNome.hashCode() : 0);
        return hash;
 }

@Override
public boolean equals(Object obj) {
        System.out.println("OVERRIDED EQUALS");
        if (getClass() == obj.getClass()) {
            if(this.sTabela.equals("*AnyTable*") || ((ItemBD_Temp)obj).sTabela.equals("*AnyTable*")){
                return true;
            }
            else if(this.sNome.equals("*AnyAtrib*") || ((ItemBD_Temp)obj).sNome.equals("*AnyAtrib*")){
                if(this.sTabela.equals(((ItemBD_Temp)obj).sTabela))
                    return true;
                else
                    return false;
            }
            else if(this.sValor.equals("*AnyValue*") || ((ItemBD_Temp)obj).sValor.equals("*AnyValue*")){
                if((this.sTabela+this.sNome).equals( (((ItemBD_Temp)obj).sTabela+((ItemBD_Temp)obj).sNome) ))
                    return true;
                else
                    return false;
            }
            else{
                if((this.sTabela+this.sNome+this.sValor).equals( (((ItemBD_Temp)obj).sTabela+((ItemBD_Temp)obj).sNome+((ItemBD_Temp)obj).sValor) ))
                    return true;
                else
                    return false;
            }
        }
        else{
            return (this == obj);
        }        
    }

这是必要的,因为o bj1 = {sTabela = "1", sNome = "2", sValor="3"}obj2 = {sTabela = "AnyTable", sNome = "AnyAtrib", sValor="AnyValue"}等不同对象应被视为等效。

1 个答案:

答案 0 :(得分:1)

您正在使用ArrayList作为数据结构。它是一种不同步的数据结构。在您的问题中,只有读操作,所以不应该是一个问题。但是,在程序中总体上有很多不同步的列表,请考虑线程安全性。

对于通过迭代器或索引访问元素的ArrayList,速度方面几乎相同。但是,这不是官方基准。您也可以考虑使用迭代器来尝试代码。

  

我有几个小阵列列表(800~1500),每个都有一个   必须验证它是否包含评估arrayList中的所有项目   最好的时间。目标arrayList(比方说,tSet)   并且评估arrayList(eSet)有1到5个元素。

您有800到1500个阵列列表。我认为你“有义务”使用该数据结构。

你有1个评估arrayList。在这里,我会考虑改变。我会使用哈希表/地图作为数据结构。 平均而言,搜索速度更快。事实证明这是正确的。在哈希表/映射中插入/删除/搜索元素的平均时间复杂度是O(1)。这意味着平均时间不变。 (最坏的情况是O(n),但总的来说我们对平均值感兴趣。)

“如果目标列表包含评估列表的所有项目”等同于“所有评估列表项目都在目标列表中”。在您的示例中,您遍历目标列表并进行比较,但您也可以遍历评估列表并进行比较。

  

现在假设你总是想测试评估   list是目标列表的子集。循环越好越好   评估列表并进行比较,因为预计会有较少的比较   元件。

我稍后会查看您的代码。但有一件事让我觉得不舒服:

  

循环中的条件!您确定您的算法按预期工作吗?