我正在尝试迭代一个LinkedList(包含一个Object数据和一个Node的Nodes),并按照字母顺序排列的方式将元素添加到所述列表中。下面是这个addElement方法的代码片段,下面我将展示整个程序的输出,以及它出错的地方。
public void addElement(Object element) {
LinkedListIterator iter = new LinkedListIterator();
if (first == null) {
addFirst(element); // If list is empty, make the input first
} else {
String input = String.valueOf(element);
String current = String.valueOf(first.data);
int compare = input.compareTo(current);
while (iter.hasNext()) {
if (compare > 0) { // element is greater than position
// Do nothing, keep going
} else if (compare < 0) { // element is where it needs to be
// Since element is now smaller than the next thing,
// break the loop to add it.
break;
} else { // element completely matches position
// Do nothing, keep going
}
current = String.valueOf(iter.next());
compare = input.compareTo(current);
}
iter.add(element);
}
}
此输入,一次一个(没有空格或逗号),将是: 葡萄,甜瓜,苹果,桃子,香蕉
输出将是: (葡萄) (葡萄甜瓜) (苹果葡萄瓜) (Apple Grape Melon Peach) (Apple Grape Banana Melon Peach)
正如你所看到的,没有明显的理由(至少我可以看到),除了香蕉这个术语外,所有内容都按字典顺序排序。为什么它突然跳过Grape,一个元素领先于它应该是什么? Apple和Grape之间的任何单词都会出现这种情况,例如Cherry,所以我怀疑在第一个和第二个术语之间添加元素时存在逻辑错误。帮助将不胜感激,至于我的生活,我找不到逻辑错误。干杯!
答案 0 :(得分:0)
在IDE中运行调试器,并检查要比较的input
和current
的值。根据您的代码,input
可能类似于java.lang.Object@61bbe9ba
。这取决于元素的类是否正确覆盖了toString
方法。如果是这种情况,则替换:
String input = String.valueOf(element);
使用:
String input = String.valueOf(element.data);
另一种可能性是data
的{{1}}方法正在评估toString
之类的内容。无论哪种方式,您都需要确保所比较的java.lang.Object@61bbe9ba
和input
的值是正确的。
此外,更简单的排序方法是使用Collections提供的排序方法。下面是一个示例,其中compare
是您的LinkedList,linkedList
是您的LinkedList元素的类类型:
Element
另一种解决方案是使用相同的比较器创建TreeSet,遍历LinkedList并将每个元素添加到TreeSet。每次添加新元素时,TreeSet都会自动排序,并且比LinkedList具有更快的数据访问时间。 TreeSet为O(log n),而LinkedList为O(n)。
Collections.sort(linkedList, (Element element1, Element element2) -> String.valueOf(element1.data).compareTo(String.valueOf(element2.data)));
答案 1 :(得分:0)
做得太多了,实际上一个人必须在一个位置之后插入,也在一个位置之前插入。
String sought = String.valueOf(element);
while (iter.hasNext()) {
current = String.valueOf(iter.next());
comparison = sought.compareTo(current);
if (comparison == 0) {
return; // Already added
} else if (compare > 0) {
// Sought element is larger than the current element,
// so add it in front
iter.previous();
break;
}
}
iter.add(element); // Add it after this one
答案 2 :(得分:0)
您的代码等同于以下简化版本:
public void addElement(Object element) {
if (first == null) {
addFirst(element); // If list is empty, make the input first
} else {
String input = String.valueOf(element);
LinkedListIterator iter = new LinkedListIterator();
String current = String.valueOf(first.data);
while (iter.hasNext() && input.compareTo(current) >= 0) {
current = String.valueOf(iter.next());
}
iter.add(element);
}
}
现在,当您到达列表末尾或current
大于input
时,更容易看到循环退出。这样逻辑就可以了。
但现在看看你在比较input
的内容!最初,您将其与data
字段的字符串值进行比较。但是在循环中,您将它与iter.next()
的字符串值进行比较,后者为您提供节点,而不是data
的值。实际上,您将字符串"Banana"
与"com.example.LinkedListNode@331fe1a"
进行比较。您需要使用String.valueOf(iter.next().data)
。 (假设您的LinkedListIterator
按常规行事且iter.next()
具有正确的返回类型。)
您可以通过更严格地处理数据类型来减少这些错误。具体来说,您应该考虑使LinkedList
通用。也许你还没有开始研究泛型,但是当你这样做时,你会意识到他们如何使这个代码更整洁。
编辑:
如您所说iter.next()
返回实际数据,那么问题必须在其他地方。你问题中循环的逻辑看起来没问题,所以我现在怀疑你LinkedListIterator
类中的逻辑,特别是它的add
方法。看起来它是在 next 元素之后而不是在当前元素之后添加。