[改善Java代碼]非穩定排序推薦使用List

我們知道Set與List的最大區別就是Set中的元素不可以重復(這個重復指的equals方法的返回值相等),其他方面則沒有太大的區別了,在Set的實現類中有一個比較常用的類需要了解一下:TreeSet,該類實現了類默認排序為升序的Set集合,如果插入一個元素,默認會按照升序排列(當然是根據Comparable接口的compareTo的返回值確定排序位置了),不過,這樣的排序是不是在元素經常變化的場景中也適用呢?我們來看例子:

 1 import java.util.SortedSet;
 2 import java.util.TreeSet;
 3 
 4 public class Client {
 5     public static void main(String[] args) {
 6         SortedSet<Person> set = new TreeSet<Person>();
 7         //身高180CM
 8         set.add(new Person(180));
 9         //身高175CM
10         set.add(new Person(175));
11         
12         for(Person p:set){
13             System.out.println("身高:"+p.getHeight());
14         }
15     }
16     
17     static class Person implements Comparable<Person>{
18         //身高
19         private int height;
20         
21         public Person(int _age){
22             height = _age;
23         }
24         
25 
26         public int getHeight() {
27             return height;
28         }
29 
30 
31         public void setHeight(int height) {
32             this.height = height;
33         }
34 
35         //按照身高排序
36         public int compareTo(Person o) {
37             return height - o.height;
38         }
39 
40     }
41 }

?

程序輸出:

身高:175
身高:180

?

這沒有問題,隨著時間的推移,身高175cm的人長高了10cm,而180cm卻保持不變,那排序的位置應該改變一下吧,看代碼(只需修改main方法):

 1     public static void main(String[] args) {
 2         SortedSet<Person> set = new TreeSet<Person>();
 3         // 身高180CM
 4         set.add(new Person(180));
 5         // 身高175CM
 6         set.add(new Person(175));
 7         // 身高最矮的人大變身
 8         set.first().setHeight(185);
 9         for (Person p : set) {
10             System.out.println("身高:" + p.getHeight());
11         }
12     }

?

程序輸出:

身高:185
身高:180

很可惜,竟然沒有重新排序,偏離了我們的預期。這正是下面要說明的問題,SortedSet接口(TreeSet實現了該接口)只是定義了在給集合加入元素時將其進行排序,并不能保證元素修改后的排序結果,因此TreeSet使用于不變量的集合數據排序,比如String、Integer等類型,但不適用于可變量的排序,特別是不確定何時元素會發生變化的數據集合。?
原因知道了,那如何解決此類重排序問題呢?有兩種方式:?

(1).Set集合重排序?
重新生成一個Set對象,也就是對原有的Set對象重排序,代碼如下:

 1 import java.util.ArrayList;
 2 import java.util.SortedSet;
 3 import java.util.TreeSet;
 4 
 5 public class Client {
 6     public static void main(String[] args) {
 7         SortedSet<Person> set = new TreeSet<Person>();
 8         // 身高180CM
 9         set.add(new Person(180));
10         // 身高175CM
11         set.add(new Person(175));
12         // 身高最矮的人大變身
13         set.first().setHeight(185);
14         //set重排序
15         set = new TreeSet<Person>(new ArrayList<Person>(set));
       //set = new TreeSet(set);該構造函數只是原Set的淺拷貝,如果里面有相同的元素,是不會重新排序的
16 for (Person p : set) { 17 System.out.println("身高:" + p.getHeight()); 18 } 19 } 20 21 static class Person implements Comparable<Person> { 22 // 身高 23 private int height; 24 25 public Person(int _age) { 26 height = _age; 27 } 28 29 public int getHeight() { 30 return height; 31 } 32 33 public void setHeight(int height) { 34 this.height = height; 35 } 36 37 // 按照身高排序 38 public int compareTo(Person o) { 39 return height - o.height; 40 } 41 42 } 43 }

?

程序輸出:

身高:180
身高:185

就一句話即可重新排序。可能有讀者會問,使用TreeSet(SortedSet< E > s)這個構造函數不是可以更好地解決問題嗎?不行,該構造函數只是原Set的淺拷貝,如果里面有相同的元素,是不會重新排序的。?
(2).徹底重構掉TreeSet,使用List解決問題?
我們之所以使用TreeSet是希望實現自動排序,即使修改也能自動排序,既然它無法實現,那就用List來代替,然后再使用Collections.sort()方法對List排序.看代碼:

 1 import java.util.ArrayList;
 2 import java.util.Collections;
 3 import java.util.List;
 4 import java.util.TreeSet;
 5 
 6 public class Client {
 7     public static void main(String[] args) {
 8         List<Person> list = new ArrayList<Person>();
 9         // 身高180CM
10         list.add(new Person(180));
11         // 身高175CM
12         list.add(new Person(175));
13         // 身高最矮的人大變身
14         list.get(1).setHeight(185);
15         
16         //排序
17         Collections.sort(list);
18         for (Person p : list) {
19             System.out.println("身高:" + p.getHeight());
20         }
21     }
22 
23     static class Person implements Comparable<Person> {
24         // 身高
25         private int height;
26 
27         public Person(int _age) {
28             height = _age;
29         }
30 
31         public int getHeight() {
32             return height;
33         }
34 
35         public void setHeight(int height) {
36             this.height = height;
37         }
38 
39         // 按照身高排序
40         public int compareTo(Person o) {
41             return height - o.height;
42         }
43 
44     }
45 }

?

程序輸出:

身高:180
身高:185

?

兩種方法都可以解決我們的困境,到底哪一個是最優的呢?對于不變量的排序,例如直接量(也就是8個基本類型)、String類型等,推薦使用TreeSet,而對于可變量,例如我們自己寫的類,可能會在邏輯處理中改變其排序關鍵值的,則建議使用List自行排序。?
又有問題了,如果需要保證集合中元素的唯一性,又要保證元素值修改后排序正確,那該如何處理呢?List不能保證集合中的元素唯一,它是可以重復的,而Set能保證元素唯一,不重復。如果采用List解決排序問題,就需要自行解決元素重復問題(若要剔除也很簡單,轉變為HashSet,剔除后再轉回來)。若采用TreeSet,則需要解決元素修改后的排序問題,孰是孰非,就需要根據具體的開發場景來決定了。

?

轉載于:https://www.cnblogs.com/DreamDrive/p/5660201.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/457645.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/457645.shtml
英文地址,請注明出處:http://en.pswp.cn/news/457645.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

如何訪問另一臺電腦的共享文件夾_如何遠程控制另一臺電腦

在工作中&#xff0c;我們時常需要遠程控制一下另一臺電腦&#xff0c;如果這兩臺計算機在局域網內可以通過遠程桌面輕松實現&#xff0c;如果這兩臺計算機不在局域網內則通常需要借助第三方軟件來實現。遠程桌面使用分三步&#xff1a;1、被控制端要開啟遠程桌面功能&#xff…

10_JS數組

JS 數組 以索引為鍵的對象&#xff0c;性能高于對象 創建 new Array() var arr Array() for(var i 0;i<5;i){arr[i] i; };var arr Array(1,2,3,4,5,6)數組字面量 var arr [2,3,4,5,6,7,8];不同&#xff1a;傳入一個整數時&#xff0c;new把這個數當作數組長度&…

微軟Hololens學院教程- Holograms 101: Introduction with Device【微軟教程已經更新,本文是老版本】...

這是老版本的教程&#xff0c;為了不耽誤大家的時間&#xff0c;請直接看原文&#xff0c;本文僅供參考哦&#xff01;原文鏈接&#xff1a;https://developer.microsoft.com/EN-US/WINDOWS/HOLOGRAPHIC/holograms_101 這篇文章將通過一個完整的實例來了解設備的核心特性&#…

python seaborn boxplot_python - 如何將文本框添加到Seaborn Boxplot? - 堆棧內存溢出

我試圖在框圖中插入一個文本框&#xff0c;但是出了點問題。 讓我們先繪制箱線圖&#xff1a;import pandas as pdimport matplotlib.pyplot as pltimport seaborn as sbdf_data pd.read_hdf(data.h5, keyfdf_data)##print(df_data)fig, (ax1, ax2) plt.subplots(1,2,gridspe…

JS_11正則表達式和字符串方法

正則表達式和字符串方法 正則表達式 創建正則對象 構造函數字面量 匹配模式 i&#xff1a;忽略大小寫m&#xff1a;多行匹配g&#xff1a;全局匹配 正則語法 正則作用/a/檢查是否有a/a|b/檢查是否有a或b{}量詞&#xff0c;如{1,3}匹配1到3次&#xff0c;{m,}匹配m次以上…

qtableview點擊行將整行數據傳過去_可以實時獲取數據的Database Asset插件

前言&#xff1a;Goby之前開放的插件入口點較少&#xff0c;大家只能在掃描前、掃描后執行事件&#xff0c;無法參與掃描過程中來。為實現更多場景的應用及提高掃描效率&#xff08;如&#xff1a;后臺爆破子域名等&#xff09;&#xff0c;Goby開放了一些新的API&#xff1a;事…

git 筆記

版本庫1.repository在一個合適的地方&#xff0c;創建一個空目錄$ mkdir learngit$ cd learngit$ pwd/User/leon/learngitpwd命令用于顯示當前的目錄&#xff0c;在我的電腦上&#xff0c;這個倉庫位于/user/michael/learngit2.git init 將當前目錄變成git 可以管理的倉庫。$ g…

github 開源 代碼 學習 集合(轉載)

一個支持多種item類型的recycleView依賴注入庫 1.通過注解的方式方便的把ViewHolder注入到recycleView中。 2.去除findViewByID等冗余操作。 3.去除編寫adapter那些冗余邏輯&#xff0c;只需要編寫proxy和holder即可快速的實現淘寶首頁那樣復雜的頁面。https://github.com/s94…

JS_12 DOM

DOM 操作 HTML DOM Document Object Model&#xff0c;文檔對象模型&#xff0c;用js操作文檔對象 [外鏈圖片轉存失敗(img-Dygj4uK9-1562680086020)(image/domtree.gif)] 節點&#xff1a;構成網頁最基本的部分&#xff0c;網頁的每一部分都是一個節點 文檔節點&#xff1a;…

星星排序python_python中怎么實現星星排列

python中怎么實現星星排列&#xff1f;下面給大家帶來幾種排列陣型。星星陣型1def stars1(n):for i in range(1,n1):str "*"*iprint strif __name__ "__main__":stars1(5)星星陣型2def stars2(n):for i in range(1,n1):str **(n1-i)print strif __name_…

Kendo UI開發教程:Kendo UI模板概述

2019獨角獸企業重金招聘Python工程師標準>>> Kendo UI框架提供了一個易用&#xff0c;高性能的JavaScript模板引擎。通過模板可以創建一個HTML片段然后可以和JavaScript數據合并成最終的HTML元素。Kendo 模板側重于UI顯示&#xff0c;支持關鍵的模板功能&#xff0c…

JS_13原型與原型鏈

原型與原型鏈 原型 每一個函數都有一個屬性&#xff1a;prototype,默認指向object空對象&#xff0c;就是原型對象,原型對象有一個constructor屬性&#xff0c;指向函數對象每一個實例化對象都有一個屬性 proto ,默認指向構造函數的原型對象&#xff08;是構造函數原型對象的…

ajax數據保存及解析

1. $(#frmCam).serialize()&#xff1b;serialize() 方法通過序列化表單值&#xff0c;創建 URL 編碼文本字符串。 2.自動對應ID和值 window.camConfig [<%(camConfig) %>]; if (camConfig.length>0) { for(var property in cam…

python和revit_pyRevit系列教程1

有沒有人和我一樣&#xff0c;想要自己寫一些小功能來用(zhuang)用(bi)&#xff0c;但苦于C#太難學了&#xff0c;不得不作罷。話說感受過Python的美好&#xff0c;怎么能忍受C#的大括號&#xff01;畢竟人生苦短&#xff0c;我用Python&#xff01;好吧&#xff0c;我承認是我…

【leetcode】104. Maximum Depth of Binary Tree

1. 題目 Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node. 2. 思路 遞歸到左、右子樹的max值&#xff0c;1. 3. 代碼 /*** Definition for a binary tree …

JS_14 執行上下文與執行上下文棧

執行上下文和執行上下文棧 變量提升和函數提升 變量提升 所用使用var定義的變量&#xff0c;在程序運行前會被先定義&#xff0c;并賦初值為underfind&#xff0c;保存到其執行上下文中 函數提升 在調用函數&#xff0c;執行函數體之前&#xff0c;會先執行函數定義&#xff…

shell編程-變量

1.Bash用戶自定義變量 【局部變量】 【按數據存儲分類】&#xff1a;整型、浮點型、字符串型、日期型 【變量定義】&#xff1a;x5,y6,z$x$y56,m$(($x$y))11 【Bash變量默認都為字符串型&#xff0c;等號左右不可以有空格】 【變量疊加】&#xff1a;x"$x"123,x${x}3…

JS_15作用域與作用域鏈

作用域與作用域鏈 作用域 類別 全局作用域函數作用域塊作用域&#xff1a;Es6時出現&#xff0c;之前沒有 作用域與執行上下文 區別 創建時機不同 全局作用域外&#xff0c;每個函數都有自己的作用域&#xff0c;作用域在函數創建時就創建了&#xff0c;而不是在調用時全局執…

多線程調用同一個對象的方法_多線程之如何創建和使用線程

一、創建線程和使用線程方式1.1 繼承Thread讓線程類繼承自Thread類&#xff0c;然后重寫run()&#xff0c;把需要多線程調用的代碼放到run()中。但是需要開啟線程的時候不能調用run方法&#xff0c;而是需要調用start()方法。/*** 本類用于演示第一種實現多線程的方式*/ class…

struts2的namespace的問題

<?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd"> <struts> <inc…