【问题标题】:Using a LinkedList And ListIterator to return elements in alphabetical order使用 LinkedList 和 ListIterator 按字母顺序返回元素
【发布时间】:2020-01-25 15:47:51
【问题描述】:

'addInOrder' 函数应该按字母顺序将字符串元素(澳大利亚城市名称)添加到 LinkedList 'placesToVisit'。

根据我所遵循的教程,“addInOrder”函数实际上按预期工作。但是,该函数以返回布尔值的方式编写,即private static boolean addInOrder(LinkedList<String> linkedList, String newCity) {}

但我想尝试并决定编写函数“addInOrder”来返回 void,即private static void addInOrder(LinkedList<String> linkedList, String newCity) {}

但是输出没有按字母顺序返回,尽管在 while 循环中使用了 'break' 关键字,但甚至出现重复。

根据教程的原始代码是:

   private static boolean addInOrder(LinkedList<String> linkedList, String newCity) {
    ListIterator<String> stringListIterator = linkedList.listIterator();

        while (stringListIterator.hasNext()) {
            int comparison = stringListIterator.next().compareTo(newCity);
            if (comparison == 0) {
                System.out.println(newCity + " already listed as destination.");
                return false;
            } else if (comparison > 0) {
                stringListIterator.previous();
                stringListIterator.add(newCity);
                return true;
            }
        }
        stringListIterator.add(newCity);
        return true;
     }

输出:

Now visiting, Adelaide
Now visiting, Brisbane
Now visiting, Canberra
Now visiting, Darwin
Now visiting, Melbourne
Now visiting, Perth
Now visiting, Sydney

我的代码:

public class Demo {
public static void main(String[] args) {
    LinkedList<String> placesToVisit = new LinkedList<>();
    addInOrder(placesToVisit, "Sydney");
    addInOrder(placesToVisit, "Melbourne");
    addInOrder(placesToVisit, "Brisbane");
    addInOrder(placesToVisit, "Perth");
    addInOrder(placesToVisit, "Canberra");
    addInOrder(placesToVisit, "Adelaide");
    addInOrder(placesToVisit, "Darwin");

    printList(placesToVisit);
}

private static void printList(LinkedList<String> linkedList) {
    Iterator<String> i = linkedList.iterator();

    while (i.hasNext()) {
        System.out.println("Now visiting, " + i.next());
    }

    System.out.println("=============================");
}

private static void addInOrder(LinkedList<String> linkedList, String newCity) {
    ListIterator<String> stringListIterator = linkedList.listIterator();

    if (linkedList.size() == 0) {
        linkedList.add(newCity);
    } else {
        while (stringListIterator.hasNext()) {
            int comparison = stringListIterator.next().compareTo(newCity);
            if (comparison == 0) {
                System.out.println(newCity + " already listed as destination.");
                break;
            } else if (comparison > 0) {
                stringListIterator.previous();
                stringListIterator.add(newCity);
                break;
            } else if (comparison < 0) {
                stringListIterator.add(newCity);
                break;
            }
        }
        linkedList.addLast(newCity);
    }

}
} 

输出:

Now visiting, Adelaide
Now visiting, Darwin
Now visiting, Brisbane
Now visiting, Canberra
Now visiting, Perth
Now visiting, Melbourne
Now visiting, Sydney
Now visiting, Melbourne
Now visiting, Brisbane
Now visiting, Perth
Now visiting, Canberra
Now visiting, Adelaide
Now visiting, Darwin

【问题讨论】:

  • 嗨,欢迎来到 SO。您这样做是为了训练自己还是只需要城市按字母顺序排列?我的意思是,您在使用LinkedListListIterator 时是否有限制,或者您可以使用List 的其他实现?
  • 原始中的最后一个添加 stringListIterator.add(newCity); 仅在尚未添加城市但您一直在循​​环中添加它并在最后添加额外时间时才调用
  • 谢谢@A.Wolf
  • 谢谢@Joakim Danielson。

标签: java linked-list iterator


【解决方案1】:

您将每个城市添加两次。首先,您将它添加到 break 之前的循环中。然后在循环之后将它添加到列表的末尾,在这一行中:

    linkedList.addLast(newCity);

您还会注意到,您的输出的后半部分正是您插入的城市。

breakreturn 弱。 break 在循环后继续执行,而return 完全退出方法。

编辑:你还有一个问题:你没有按顺序添加。如果列表非空,您的if/else 链将总是找到一个真实案例。这意味着除非要添加的城市已经是列表中的第一个(!),否则您将在第一个元素之前或之后添加它,而不是稍后。

  1. 悉尼进入一个空列表。作为唯一的城市,它只添加一次。
  2. Melbourne 添加在 Sydney 之前(正确)和末尾(不正确)。
  3. 布里斯班添加在墨尔本之前和末尾。
  4. 在布里斯班之后(不正确)和最后(也不正确)添加珀斯
  5. 堪培拉添加在布里斯班之后和末尾。
  6. 阿德莱德添加在布里斯班之前和末尾。
  7. 达尔文添加在阿德莱德之后和末尾。

顺便说一句,对于生产代码,我更喜欢使用ArrayList 而不是LinkedList。如果有 100 000 个城市按顺序插入ArrayList 可能会变得非常昂贵。如果是这样,我会在最后插入并在添加所有城市后对列表进行排序。

【讨论】:

  • 谢谢 Ole V.V.我正在处理您的更正。
  • 谢谢 Ole V.V.我根据您的更正重写了代码。现在可以了。请审查。
【解决方案2】:

贡献者 (Ole V.V.) 更正后:“break 比 return 弱。break 在循环后继续执行,而 return 完全退出方法。”

我查看了代码:

private static void addInOrder(LinkedList<String> linkedList, String newCity) {
    ListIterator<String> stringListIterator = linkedList.listIterator();

    if (linkedList.size() != 0) {
        while (stringListIterator.hasNext()) {
            int comparison = stringListIterator.next().compareTo(newCity);
            if (comparison == 0) {
                System.out.println(newCity + " already listed as destination.");
                return; //return keyword is used instead of break keyword to exit the method
            } else if (comparison > 0) {
                stringListIterator.previous();
                stringListIterator.add(newCity);
                return; //return keyword is used instead of break keyword to exit the method
            }
        }
    }
    stringListIterator.add(newCity);
}

【讨论】:

  • 我已经审核了,我已经测试过了,我没有发现任何迹象表明它应该是不正确的。
  • 请Damilola,删除此答案并接受@OleV.V 的答案。如果有用的话。当别人给你一个解决方案或一个好的起点时,回答你自己的问题是无稽之谈。也许你可以让他在他的答案中添加你自己的解决方案,但不要像这样创建另一个答案。
  • @A.Wolf 我不敢苟同。 Stack Exchange 明确鼓励回答自己的问题,虽然这个答案显然是基于我的,但我认为这没有问题,并且不希望将这个答案中的代码包含在我的答案中。 (是我赞成这个答案。)
  • 很高兴知道!我认为将所有信息集中在一个点上会更合适:)
  • 哈哈你说得对!但对我来说,听取更有经验的 SO 用户的意见以改进帮助提问者的方式很重要,所以感谢您的意见。
猜你喜欢
  • 2016-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-19
  • 2013-10-16
  • 1970-01-01
  • 1970-01-01
  • 2013-05-12
相关资源
最近更新 更多