如何使用java树集实现排序表(按元素的字段排序)?
我为此使用了TreeSet,它以每个快照的方式工作。换句话说,“一次排序”显示一次 现在,我想实现一个实时排序表 每当任何元素中的值发生变化时,排序表都会相应地更新 为了在每次更新样式上进行排序,我尝试删除元素并再次将其添加到树集如何使用java树集实现排序表(按元素的字段排序)?,java,sorting,treeset,Java,Sorting,Treeset,我为此使用了TreeSet,它以每个快照的方式工作。换句话说,“一次排序”显示一次 现在,我想实现一个实时排序表 每当任何元素中的值发生变化时,排序表都会相应地更新 为了在每次更新样式上进行排序,我尝试删除元素并再次将其添加到树集 quotes.remove(quote); quotes.add(quote); 它不起作用,因为我必须在compareTo()中实现排序逻辑,但它打破了标识使remove()工作的对象的约定。TreeSet从不调用Java文档中描述的equals()和hashco
quotes.remove(quote);
quotes.add(quote);
它不起作用,因为我必须在compareTo()中实现排序逻辑,但它打破了标识使remove()工作的对象的约定。TreeSet从不调用Java文档中描述的equals()和hashcode()
有什么想法吗?请告知
代码:
remove()返回false,最终在集合中有四个元素(预期为3)
--Top Stocks By Turnover--
Quote [symbol=face, turnover=3000.0]
Quote [symbol=msft, turnover=2000.0]
Quote [symbol=appl, turnover=1000.0]
remove symbol face : false
add symbol face : true
--Top Stocks By Turnover--
Quote [symbol=face, turnover=3000.0]
Quote [symbol=msft, turnover=2000.0]
Quote [symbol=appl, turnover=1000.0]
Quote [symbol=face, turnover=50.0]
更新2:
我尝试了PriorityQueue,下面是代码:
它不起作用,因为PriorityQueue不按顺序存储元素。排序仅在从队列轮询元素时有效
更新3:
尝试了user54321的建议,即通过使用自定义集合(请参见下面的答案)。然而,如果有两个以上的要素具有相同的“营业额”值,那么这看起来就不好了
我的要求很普通。似乎JDK的所有收藏都不符合我的情况
更新4:
user54321的解决方案适合我的临时需要。
有两点:
Quote(“face”,“50d”)
,当您调用quotes时它不存在。删除(Quote)代码>
public void onAdd(String symbol, double turnover) {
final Quote quote = new Quote(symbol, turnover);
quotes.remove(quote);
quotes.add(quote);
}
public void onQuoteUpdate(String symbol, double turnover) {
final Quote newQuote = new Quote(symbol, turnover);
final Quote oldQuote = new Quote("face", 3000d);
quotes.remove(oldQuote);
quotes.add(quote);
}
public static void main(String args[]) {
TreeSetTest test = new TreeSetTest();
test.onAdd("appl", 1000d);
test.onAdd("msft", 2000d);
test.onAdd("face", 3000d);
test.printTopStocks();
test.onQuoteUpdate("face", 50d);
test.printTopStocks();
}
删除了我先前添加的答案。看起来该场景使用了错误的数据结构 这就是原因 添加或删除项目时,TreeSet使用
compareTo()
对可用元素进行二进制搜索
就你而言
添加前3个元素后,集合如下所示。[{appl,1000d},{msft,2000d},{face,3000d}]
现在,当您尝试删除元素{face,50d}
时
它从{msft,2000d}
开始搜索,
从compareTo()
结果中,它确定{face,50d}
应位于{msft,2000d}
之前
并继续搜索元素的开头(使用{appl,1000d}
next进行检查)
由于搜索没有找到{face,3000d}
,因此该元素将保持不变,不会被删除
接下来,当您添加元素{face,50}
时,会发生类似的搜索,因为搜索没有找到{face,3000}
,
它将{face,50}
添加到开头
现在,该集看起来是这样的。[{face,50},{appl,1000d},{msft,2000d},{face,3000d}]
现在的问题是,compareTo()
不能同时考虑符号和换位来进行合理的排序。
TreeSet
可用于获取唯一元素的排序集合
如果需要获得具有特定排序条件的不同对象的排序集合,在本例中,可以使用
更新:在自定义数据结构中使用列表和集合
这里的问题是我们必须保持两个条件。
1.符号必须是唯一的
2.收款应按营业额进行排序
Quote中的compareTo()
可以一次检查一个,但不能同时检查两个。
因此,在这种情况下,我们可能不得不选择自定义数据结构
首先在compareTo()中仅使用营业额
然后实现自定义数据结构。
请注意,我们使用哈希集来单独跟踪符号。
使用列表,以便保留重复的营业额值
static class QuoteCollection {
Set<String> symbols = new HashSet<>();
List<Quote> quotes = new LinkedList<>();
public void onQuoteUpdate(Quote q) {
if (symbols.contains(q.getSymbol())) {
// this requires quotes.equals() to be implemented
quotes.remove(q);
} else {
symbols.add(q.getSymbol());
}
insertToCollection(q);
}
// inserting at correct position to remain sorted
private void insertToCollection(Quote q) {
int index = Collections.binarySearch(quotes, q);
if (index < 0)
index = ~index; // bitwise compliment to find insert position if it is not available in the list
quotes.add(index, q);
}
public List<Quote> getQuotes() {
return quotes;
}
}
静态类QuoteCollection{
Set symbols=新的HashSet();
列表引号=新建LinkedList();
报价更新时公共无效(报价q){
if(symbols.contains(q.getSymbol())){
//这需要实现quotes.equals()
删除(q);
}否则{
symbols.add(q.getSymbol());
}
插入采集(q);
}
//在正确位置插入以保持排序
私有void insertToCollection(报价q){
int index=Collections.binarySearch(引号,q);
如果(指数<0)
index=~index;//如果插入位置在列表中不可用,则按位补全查找插入位置
添加(索引,q);
}
公共列表getQuotes(){
返回报价;
}
}
然后在main()中使用它。请注意,printTopStocks()已做了一些更改
public static void main(String args[]) {
Main test = new Main();
QuoteCollection quoteCollection = new QuoteCollection();
quoteCollection.onQuoteUpdate(new Quote("appl", 1000d));
quoteCollection.onQuoteUpdate(new Quote("msft", 2000d));
quoteCollection.onQuoteUpdate(new Quote("face", 3000d));
test.printTopStocks(quoteCollection.getQuotes());
quoteCollection.onQuoteUpdate(new Quote("face", 50d));
test.printTopStocks(quoteCollection.getQuotes());
}
public void printTopStocks(List<Quote> quotes) {
System.out.println("--Top Stocks By Turnover--");
for (final Quote quote : quotes) {
System.out.println(quote);
}
}
publicstaticvoidmain(字符串参数[]){
主测试=新主测试();
QuoteCollection QuoteCollection=新的QuoteCollection();
quoteCollection.onQuoteUpdate(新的Quote(“appl”,1000d));
quoteCollection.onQuoteUpdate(新报价(“msft”,2000d));
quoteCollection.onQuoteUpdate(新报价(“面”,3000d));
test.printTopStocks(quoteCollection.getQuotes());
quoteCollection.onQuoteUpdate(新引号(“面”,50d));
test.printTopStocks(quoteCollection.getQuotes());
}
公共作废打印TopStocks(列表报价){
System.out.println(“--按营业额排列的前几名股票--”);
对于(最终报价:报价){
系统输出打印项次(报价);
}
}
这种方法确实涉及数据重复。但是,排序后的集合可以以线性时间复杂度进行维护(因为它使用“List.remove()”)请只添加相关的最小代码我认为您的类Q
@Override
public int compareTo(Quote o) {
return Double.compare(o.turnover, turnover);
}
static class QuoteCollection {
Set<String> symbols = new HashSet<>();
List<Quote> quotes = new LinkedList<>();
public void onQuoteUpdate(Quote q) {
if (symbols.contains(q.getSymbol())) {
// this requires quotes.equals() to be implemented
quotes.remove(q);
} else {
symbols.add(q.getSymbol());
}
insertToCollection(q);
}
// inserting at correct position to remain sorted
private void insertToCollection(Quote q) {
int index = Collections.binarySearch(quotes, q);
if (index < 0)
index = ~index; // bitwise compliment to find insert position if it is not available in the list
quotes.add(index, q);
}
public List<Quote> getQuotes() {
return quotes;
}
}
public static void main(String args[]) {
Main test = new Main();
QuoteCollection quoteCollection = new QuoteCollection();
quoteCollection.onQuoteUpdate(new Quote("appl", 1000d));
quoteCollection.onQuoteUpdate(new Quote("msft", 2000d));
quoteCollection.onQuoteUpdate(new Quote("face", 3000d));
test.printTopStocks(quoteCollection.getQuotes());
quoteCollection.onQuoteUpdate(new Quote("face", 50d));
test.printTopStocks(quoteCollection.getQuotes());
}
public void printTopStocks(List<Quote> quotes) {
System.out.println("--Top Stocks By Turnover--");
for (final Quote quote : quotes) {
System.out.println(quote);
}
}