双链表实现和重用迭代代码

时间:2016-09-23 20:25:05

标签: java linked-list

我有自己的双链表实现。对于节点内的每个属性,我有一个单独的方法来遍历链表。我想有一个接受比较器的方法,以便停止链表上的迭代。我如何看待它的一个例子是:伪代码:list.find((a, b) -> a == b)。这个方法会找到一个节点,但是如果我想找到多个节点呢?将findOneNode重命名为nodeSearch(fn, bool stopAtFirst)并使用重载?

public ListNode searchAge(int age) {
    return findOneNode((Predicate<Person>) node -> node.getAge() == age);
}

public ListNode findOneNode(Predicate predicate) {
    ListNode current = header;

    while (current != null) {
        if (current.getPerson() != null) {
            Boolean found = predicate.test(current.getPerson());
            if (found){
                return current;
            }
        }
        // Reached trailer?
        current = (current.getNext() != null) ? current.getNext() : null;
    }
    return null;
}
  • 上面的代码是一个好习惯吗?
  • 有更好的方法来实现这个吗?
  • 如果设计良好,我将如何在一个方法中实现搜索一个节点和多个节点?

澄清

当我说找到多个节点时,我并不是指返回所有节点。它希望在每个节点上使用.toString()方法,将其存储到StringBuffer中,然后返回一个字符串。

如果节点对象上有4个属性(名字,姓氏,年龄,中间名),我需要4种不同的方法并执行相同的循环操作,直到找到所请求的{{1 }}

2 个答案:

答案 0 :(得分:0)

嗯,行current = current.getNext();建立了相同的结果,而Boolean found是多余的,可以像if(predicate.test(current.getPerson()))

一样在测试中

根据所需的通用性,您的Predicate可能应该在ListNode上,而不是在Person上(您现在将它们混合在变量名中)

至于更好:它也可以使用递归来完成,递归通常有点慢,但更容易理解(如果你使用Scala,它会将它编译为for循环)。

至于搜索多个节点,这通常称为过滤器,它返回自己的相同类型的集合(所以另一个链表,其中包含相同的人)。

答案 1 :(得分:0)

  

对于节点内的每个属性,我有一个单独的方法来遍历链表。

从概念上讲,这是一个糟糕的设计。这不好,因为它不灵活。即使现在你已经有了这个要求,但你无法达到它。

通常,您应该将双列表实现与实际节点有效负载(Person实体左右)分开。如果您认为以这种方式思考,您将意识到您可以使用任何存在的java List<T>实现。例如。 LinkedList<Person>。因此,您可以轻松获取符合谓词的人员的节点

List<Person> people = new LinkedList<>();
...
List<Person> sameAgePeople = people.stream()
    .filter(node -> node.getAge() == age)
    .collect(Collectors.toList());

因此,您将获得符合条件的新sameAgePeople列表。