比较两个链接列表

时间:2015-04-09 05:52:36

标签: java linked-list

比较Java中两个链接列表的最佳方法是什么,我有两个列表,并希望确保一个列表中的所有元素都不在另一个列表中。就像这项工作一样,这两个列表都是LocalDates的列表。

boolean doesNotContain (LinkedList L1, LinkedList L2) { 
        for(LocalDate d:L1) { 
            if(l2.contains(d){
                return false; 

            } 
        }
       return true;    
}    

2 个答案:

答案 0 :(得分:0)

您的解决方案适用于N ^ 2复杂性。如果对两个列表进行排序并在一个循环中迭代它们,则可以在N log N中执行int(即排序复杂性)。

您还可以创建两个包含两个列表中元素的新Set,然后使用containsAll()方法 - 它将完成所有工作。这是一个简洁易懂的解决方案。可能会记忆消耗。

比较方法取决于方法equals()hashCode() - 如果您未在LocalDate课程中正确覆盖它们,则无法获得良好效果。

BTW1:返回后中断是一个死密码

BTW2:使用"命名方法"好像是个坏主意。您很快就会发现自己正在使用!notFulfills( !notContains(sdflasdf))。 Goood幸运地想弄清楚那是做什么的。

答案 1 :(得分:0)

由于doesNotContain(..)的实现接近于containsAll(..)实现的实现,我建议使用该实现。如果执行list1.containsAll(list2),实现将循环遍历list2的所有元素,以检查list1中是否存在相等的对象。这就是您需要在public boolean equals(Object obj)中覆盖LocalDate的原因。

在下面找到一个小例子来展示containsAll(..)

所做的工作

运行检查的主要程序

public static void main(String[] args) throws Exception {
    List<LocalDate> list1 = new LinkedList<>();
    list1.add(new LocalDate("112233"));
    list1.add(new LocalDate("223344"));

    List<LocalDate> list2 = new LinkedList<>();
    list2.add(new LocalDate("112233"));
    list2.add(new LocalDate("112233"));

    System.out.println("list1 = " + list1);
    System.out.println("list2 = " + list2);

    System.out.println("list1.containsAll(list2) = " + list1.containsAll(list2));
    System.out.println("list2.containsAll(list1) = " + list2.containsAll(list1));
}

如果您在不覆盖equals方法的情况下实施LocalDate,只有在比较相同对象的引用时,equals才会成立。

// a naive implementation for demonstration purpose
class LocalDate {

    String hour;
    String minute;
    String second;

    LocalDate(String string) {
        hour = string.substring(0, 2);
        minute = string.substring(2, 4);
        second = string.substring(4, 6);
    }

    @Override
    public String toString() {
        return String.format("LocalDate{%s%s%s} - hashcode: %d", hour, minute, second, this.hashCode());
    }
}

结果将是

list1 = [LocalDate{112233} - hashcode: 33039820, LocalDate{223344} - hashcode: 31311199]
list2 = [LocalDate{112233} - hashcode: 13177912, LocalDate{112233} - hashcode: 21924553]
list1.containsAll(list2) = false
list2.containsAll(list1) = false

如果覆盖equals方法(为了演示目的省略了hashcode)

@Override
public boolean equals(Object obj) {
    if (obj == null) {
        return false;
    }
    if (getClass() != obj.getClass()) {
        return false;
    }
    final LocalDate other = (LocalDate) obj;
    System.out.println(toString() + ".equals(" + obj.toString() + ')');
    if (!Objects.equals(this.hour, other.hour)) {
        return false;
    }
    if (!Objects.equals(this.minute, other.minute)) {
        return false;
    }
    if (!Objects.equals(this.second, other.second)) {
        return false;
    }
    return true;
}

输出将是

list1 = [LocalDate{112233} - hashcode: 33336787, LocalDate{223344} - hashcode: 12767201]
list2 = [LocalDate{112233} - hashcode: 31311199, LocalDate{112233} - hashcode: 13177912]
// generated output by the method containsAll(..)
LocalDate{112233} - hashcode: 31311199.equals(LocalDate{112233} - hashcode: 33336787)
LocalDate{112233} - hashcode: 13177912.equals(LocalDate{112233} - hashcode: 33336787)
list1.containsAll(list2) = true
// generated output by the method containsAll(..)
LocalDate{112233} - hashcode: 33336787.equals(LocalDate{112233} - hashcode: 31311199)
LocalDate{223344} - hashcode: 12767201.equals(LocalDate{112233} - hashcode: 31311199)
LocalDate{223344} - hashcode: 12767201.equals(LocalDate{112233} - hashcode: 13177912)
list2.containsAll(list1) = false

根据打印的Object.hashcode(),您可以很容易地看到containsAll()方法遍历您调用该方法的列表中的所有元素。

如果您想改进检查,您需要澄清以下几点 - 列表中的元素是唯一的 - &gt;然后更好地使用Set - 列表必须具有相同数量的元素 - &gt;如果是的话,你可以比较他们的尺寸 - 如果您只需要检查list2只有list1中的元素(表示该列表包含唯一值) - &gt;在list2上调用containsAll方法 - 之前对列表进行排序(取决于所包含的数据)

也是值得的

如果没有这些信息,就无法在所有情况下提出the best的建议。