Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用java树集实现排序表(按元素的字段排序)?_Java_Sorting_Treeset - Fatal编程技术网

如何使用java树集实现排序表(按元素的字段排序)?

如何使用java树集实现排序表(按元素的字段排序)?,java,sorting,treeset,Java,Sorting,Treeset,我为此使用了TreeSet,它以每个快照的方式工作。换句话说,“一次排序”显示一次 现在,我想实现一个实时排序表 每当任何元素中的值发生变化时,排序表都会相应地更新 为了在每次更新样式上进行排序,我尝试删除元素并再次将其添加到树集 quotes.remove(quote); quotes.add(quote); 它不起作用,因为我必须在compareTo()中实现排序逻辑,但它打破了标识使remove()工作的对象的约定。TreeSet从不调用Java文档中描述的equals()和hashco

我为此使用了TreeSet,它以每个快照的方式工作。换句话说,“一次排序”显示一次

现在,我想实现一个实时排序表

每当任何元素中的值发生变化时,排序表都会相应地更新

为了在每次更新样式上进行排序,我尝试删除元素并再次将其添加到树集

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)

  • 以下是解决此问题的方法之一,我正在对oldQuote进行硬编码以保持其简短,但您可以对其进行更新:

       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);
        }
    }