[英]Java Collections.sort() not sorting
我在Java內置的Collections.sort()方法中遇到問題。 我正在嘗試對名為TreeNode的自定義對象類型的ArrayList進行排序。 我過去曾經成功地使用過該方法,並且希望通過外觀來查看我是否缺少任何明顯的東西。
我想對這些TreeNode對象進行排序的方式是通過它們都稱為myWeight的整數字段,該整數表示特定字符在文本文件中出現的次數。 在我的項目中,我使用一個名為TreeNode的自定義類,並使用該類的兩個子級命名為InternalNode和LeafNode。 這些節點用於構建用於編碼文本文件的霍夫曼樹。 我已經確保所有這些方法都實現了Comparable,並且我嘗試了僅使用具有compareTo()方法的父TreeNode類的變體,讓所有它們都具有相同的compareTo()方法,我已經放棄了compareTo()實現,以在其中使用Integer.compare()方法代替,但沒有骰子。
我也嘗試過使用比較器,並將其作為Collections.sort()方法的參數傳遞,但也沒有任何改變。
這是我嘗試調用排序並顯示結果的地方:
private void generateHuffmanTreeTest(final HashMap<Character, Integer> theMap) {
ArrayList<TreeNode> sortedList = new ArrayList<TreeNode>();
System.out.println("Generating the Huffman Tree with new logic...");
for (Map.Entry<Character, Integer> entry : theMap.entrySet()) {
sortedList.add(new LeafNode(entry.getKey(), entry.getValue()));
}
Collections.sort(sortedList);
for (int i = 0; i < sortedList.size(); i++) {
LeafNode n = (LeafNode) sortedList.get(i);
System.out.println(n.myData + " " + n.myWeight);
}
以下是我也嘗試比較的對象類。
public class TreeNode implements Comparable<TreeNode> {
/** Left child of this node. */
public TreeNode myLeft;
/** Right child of this node. */
public TreeNode myRight;
/**
* Weight of all nodes branching from this one, or the weight
* of just this node if this node is a leaf.
*/
public int myWeight;
/**
* Default constructor. Should not be used to create pure
* TreeNode objects.
* No TreeNodes should be constructed, only InternalNodes
* and LeafNodes should comprise the tree.
*/
public TreeNode() {
}
/**
* Sets the left child of this node.
*
* @param theNode The node to become the left child.
*/
public void setLeft(final TreeNode theNode) {
myLeft = theNode;
}
/**
* Sets the right child of this node.
*
* @param theNode The node to become the right child.
*/
public void setRight(final TreeNode theNode) {
myRight = theNode;
}
/**
* Compares two TreeNodes based on their myWeight field.
*/
@Override
public int compareTo(TreeNode theOther) {
int result = 0;
if (myWeight < theOther.myWeight) result = -1;
if (myWeight > theOther.myWeight) result = 1;
return result;
}
}
public class InternalNode extends TreeNode implements Comparable<TreeNode> {
/**
* Creates a new InternalNode.
*/
public InternalNode() {
super();
}
/**
* Calculates the weight of both children from this Node.
*/
public void calcWeight() {
int result = 0;
if (myLeft != null) result = result + myLeft.myWeight;
if (myRight != null) result = result + myRight.myWeight;
myWeight = result;
}
/**
* Sets the left child of this node.
*
* @param theNode The child to be set.
*/
public void setLeft(final TreeNode theNode) {
myLeft = theNode;
}
/**
* Sets the right child of this node.
*
* @param theNode The child to be set.
*/
public void setRight(final TreeNode theNode) {
myRight = theNode;
}
/**
* Compares two TreeNodes based on their myWeight field.
*/
@Override
public int compareTo(TreeNode theOther) {
int result = 0;
if (myWeight < theOther.myWeight) result = -1;
if (myWeight > theOther.myWeight) result = 1;
return result;
}
}
public class LeafNode extends TreeNode implements Comparable<TreeNode> {
/** Char value for this node to hold. */
public char myData;
/** Weight value of the char this node holds. */
public int myWeight;
/**
* Creates a new LeafNode that contains a char value for it to
* hold as well as a weight value that is equal to the number
* of times that character appears in the target String.
*
* @param theData The char value for this node to hold.
* @param theWeight The frequency of the char value in the text.
*/
public LeafNode(final char theData, final int theWeight) {
super();
myData = theData;
myWeight = theWeight;
}
/**
* Compares two TreeNodes based on their myWeight field.
*/
@Override
public int compareTo(TreeNode theOther) {
int result = 0;
if (myWeight < theOther.myWeight) result = -1;
if (myWeight > theOther.myWeight) result = 1;
return result;
}
}
編輯***是的,如果我也發布此內容的輸出,可能會有所幫助。 這是我從閱讀的文本文件中運行此代碼時得到的結果:
65007
514908
! 3923
" 17970
# 1
$ 2
% 1
' 7529
( 670
) 670
* 300
, 39891
- 6308
. 30806
/ 29
0 179
1 392
2 147
3 61
4 23
5 55
6 57
7 40
8 193
9 35
: 1014
; 1145
= 2
? 3137
@ 2
A 6574
B 3606
C 2105
D 2017
E 2259
F 1946
G 1303
H 4378
I 7931
J 308
K 1201
L 713
M 3251
N 3614
O 1635
P 6519
Q 35
R 3057
S 2986
T 6817
U 254
V 1116
W 2888
X 673
Y 1265
Z 108
[ 1
] 1
à 4
a 199232
b 31052
c 59518
d 116273
ä 1
e 312974
f 52950
g 50023
h 163026
i 166350
é 1
j 2266
ê 11
k 19230
l 95814
m 58395
n 180559
o 191244
p 39014
q 2295
r 145371
s 159905
t 219589
u 65180
v 25970
w 56319
x 3711
y 45000
z 2280
1
您遇到的問題是您在TreeNode
和myWeight
中都定義了LeafNode
。 結果, compareTo
方法使用的myWeight
變量可能與LeafNode
構造函數編寫並在打印LeafNode.myWeight
時LeafNode.myWeight
。
您可能只想從LeafNode
刪除重復的myWeight
定義。
請參閱此處有關變量隱藏的部分: https : //dzone.com/articles/variable-shadowing-and-hiding-in-java
您可以使用Comparator<TreeNode>
。 這樣,如果您向TreeNode
類添加字段,則可以實現一個不同的比較器並將其傳遞給Collections.sort()
方法。 但是,默認情況下,如果您仍然希望它們是Comparable
,則可以將它們保留為默認的compareTo()
方法:
輸出:
[1, 5, 6, 0, 1, 0, 8, 3, 7, 4]
[0, 0, 1, 1, 3, 4, 5, 6, 7, 8]
TreeNode:
public static class TreeNode implements Comparable<TreeNode> {
public TreeNode(int weight) {
this.myWeight = weight;
}
public int myWeight;
public String toString() {
return "" + myWeight;
}
@Override
public int compareTo(TreeNode o) {
int val = 0;
if (myWeight > o.myWeight) {
val = 1;
} else if (myWeight < o.myWeight){
val = -1;
}
return val;
}
}
比較器,用於排序:
public static class TreeNodeComparator implements Comparator<TreeNode> {
// Sorts by default `compareTo()`, You can always change this
// If you want to sort by another property
@Override
public int compare(TreeNode o1, TreeNode o2) {
return o1.compareTo(o2);
}
}
主要:
public static void main(String[] args) throws Exception {
java.util.ArrayList<TreeNode> nodes = new java.util.ArrayList<>();
for (int i = 10; i > 0; i--) {
int val = ThreadLocalRandom.current().nextInt(0, 10);
TreeNode node = new TreeNode(val);
nodes.add(node);
}
System.out.println(nodes);
Collections.sort(nodes, new TreeNodeComparator());
System.out.println(nodes);
}
您可以創建一個單獨的類來實現Comparator
接口,並覆蓋compare
方法,如下所示:
public class SortByWeight implements Comparator<TreeNode> {
@Override
public int compare(TreeNode o1, TreeNode o2) {
return o1.myWeight - o2.myWeight;
}
}
然后,在方法中進行比較時,創建比較器的新實例。
ArrayList<TreeNode> sortedList = new ArrayList<TreeNode>();
System.out.println("Generating the Huffman Tree with new logic...");
TreeNode t = new TreeNode();
t.myWeight = 2;
TreeNode r = new TreeNode();
r.myWeight = 5;
TreeNode q = new TreeNode();
q.myWeight = 1;
sortedList.add(t);
sortedList.add(r);
sortedList.add(q);
//new comparator here
Collections.sort(sortedList, new SortByWeight());
for (int i = 0; i < sortedList.size(); i++) {
System.out.println(sortedList.get(i).myWeight);
}
這個的輸出是
1
2
5
希望能幫助到你。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.