Set排序方法

beat365在线官网 📅 2025-11-08 00:19:53 ✍️ admin 👁️ 5774 ❤️ 638
Set排序方法

在讲解Set集合排序的几种方法之前,我们应该先清楚Set集合的几种类型以及特点,才能有效使用起来。

Set集合的特点

​ Set不允许包含相同的元素,如果试图把两个相同元素加入同一个集合中,add方法返回false。

​ Set判断两个对象相同不是使用==运算符,而是根据equals方法。也就是说,只要两个对象用equals方法比较返回true,Set就不会同时接受这两个对象。

Set集合的分类

Set集合主要分为3种:

​ |——SortedSet接口——TreeSet实现类

Set接口——|——HashSet实现类

​ |——LinkedHashSet实现类

HashSet(无序,可null)

HashSet的特点是不能保证元素的排列顺序,顺序有可能发生变化,集合元素可以是null,但只能放入一个null。因为在HashSet中存入一个元素的时候,会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据 hashCode值来决定该对象在HashSet中存储位置,所以储存位置是随机的。HashSet就好像是HashMap的key。

TreeSet(有元素顺序的)

TreeSet是SortedSet接口的唯一实现类,TreeSet可以确保集合元素处于排序状态。TreeSet支持两种排序方式,自然排序 和定制排序,其中自然排序为默认的排序方式。一般的Set排序都会使用到TreeSet。

LinkedHashSet(记录插入顺序)

LinkedHashSet集合同样是根据元素的hashCode值来决定元素的存储位置,但是它同时使用链表维护元素的次序。这样使得元素看起 来像是以插入顺 序保存的,也就是说,当遍历该集合时候,LinkedHashSet将会以元素的添加顺序访问集合的元素。一般的,如果让你设计一个缓存算法,LinkedHashSet就是基本的基础,利用LRU,筛选出应该淘汰的元素。

由于TreeSet是有元素顺序的,因此我们在排序的过程中都会使用TreeSet。

方法一:传统方法

public class TraditionalSetSortTest {

public static void main(String[] args) {

Set set = new HashSet<>();

set.add(new BigDecimal(1.2).setScale(2, BigDecimal.ROUND_HALF_UP));

set.add(new BigDecimal(2.3).setScale(2, BigDecimal.ROUND_HALF_UP));

set.add(new BigDecimal(3.4).setScale(2, BigDecimal.ROUND_HALF_UP));

set.add(new BigDecimal(2.4).setScale(2, BigDecimal.ROUND_HALF_UP));

set.add(new BigDecimal(0.4).setScale(2, BigDecimal.ROUND_HALF_UP));

set.add(new BigDecimal(9.4).setScale(2, BigDecimal.ROUND_HALF_UP));

TreeSet sortSet = new TreeSet<>(new Comparator() {

@Override

public int compare(BigDecimal o1, BigDecimal o2) {

return o1.compareTo(o2);

}

});

sortSet.addAll(set);

System.out.println(sortSet);

}

}

--------------------------------------------------------------------------------------------

结果:[0.40, 1.20, 2.30, 2.40, 3.40, 9.40]

方法二:lambda表达式

public class LambdaSetSortTest {

public static void main(String[] args) {

Set set = new HashSet<>();

set.add(new BigDecimal(1.2).setScale(2, BigDecimal.ROUND_HALF_UP));

set.add(new BigDecimal(2.3).setScale(2, BigDecimal.ROUND_HALF_UP));

set.add(new BigDecimal(3.4).setScale(2, BigDecimal.ROUND_HALF_UP));

set.add(new BigDecimal(2.4).setScale(2, BigDecimal.ROUND_HALF_UP));

set.add(new BigDecimal(0.4).setScale(2, BigDecimal.ROUND_HALF_UP));

set.add(new BigDecimal(9.4).setScale(2, BigDecimal.ROUND_HALF_UP));

TreeSet sortedSet = new TreeSet<>(((o1, o2) -> o1.compareTo(o2)));

sortedSet.addAll(set);

System.out.println(sortedSet);

}

}

--------------------------------------------------------------------------------------------

结果:[0.40, 1.20, 2.30, 2.40, 3.40, 9.40]

方法三:使用Comparator,在jdk1.8以后,Comparator有Comparator.naturalOrder()自然排序这个方法,也有Comparator.reverseOrder()相反排序的方法。

public class ComparatorSetSortTest {

public static void main(String[] args) {

Set set = new HashSet<>();

set.add(new BigDecimal(1.2).setScale(2, BigDecimal.ROUND_HALF_UP));

set.add(new BigDecimal(2.3).setScale(2, BigDecimal.ROUND_HALF_UP));

set.add(new BigDecimal(3.4).setScale(2, BigDecimal.ROUND_HALF_UP));

set.add(new BigDecimal(2.4).setScale(2, BigDecimal.ROUND_HALF_UP));

set.add(new BigDecimal(0.4).setScale(2, BigDecimal.ROUND_HALF_UP));

set.add(new BigDecimal(9.4).setScale(2, BigDecimal.ROUND_HALF_UP));

TreeSet sortedSet = new TreeSet<>(Comparator.naturalOrder());

sortedSet.addAll(set);

System.out.println(sortedSet);

}

}

--------------------------------------------------------------------------------------------

结果:[0.40, 1.20, 2.30, 2.40, 3.40, 9.40]

方法四:使用Stream

这里使用Stream的时候可以转还成Set或者List,转换成Set的时候还需要再创建TreeSet,如果没有必须要求是Set,其实可以是直接转换成List,直接就是有序的,更加方便。

List list = set.stream().sorted(Comparator.naturalOrder()).collect(Collectors.toList());

public class StreamSetSortTest {

public static void main(String[] args) {

Set set = new HashSet<>();

set.add(new BigDecimal(1.2).setScale(2, BigDecimal.ROUND_HALF_UP));

set.add(new BigDecimal(2.3).setScale(2, BigDecimal.ROUND_HALF_UP));

set.add(new BigDecimal(3.4).setScale(2, BigDecimal.ROUND_HALF_UP));

set.add(new BigDecimal(2.4).setScale(2, BigDecimal.ROUND_HALF_UP));

set.add(new BigDecimal(0.4).setScale(2, BigDecimal.ROUND_HALF_UP));

set.add(new BigDecimal(9.4).setScale(2, BigDecimal.ROUND_HALF_UP));

Set newSet = set.stream().sorted(Comparator.naturalOrder()).collect(Collectors.toSet());

TreeSet treeSet = new TreeSet<>();

treeSet.addAll(newSet);

System.out.println(treeSet);

}

}

--------------------------------------------------------------------------------------------

结果:[0.40, 1.20, 2.30, 2.40, 3.40, 9.40]

补充:

已知数值a,如果要求向上取值(即寻找顺序的Set集合中一个大于等于a的第一个元素,日常业务还是用到很多的,不到半斤算半斤(含),超过半斤算一斤类似),可以借用set的floor方法,数值超出元素的最大值后会返回null。

如果是BigDecimal类型,TreeSet集合元素与ceiling参数的小数点位数请务必保持一致。举例如下:

public class SetFloorMethod {

public static void main(String[] args) {

Set set = new HashSet<>();

set.add(new BigDecimal(1.2).setScale(2, BigDecimal.ROUND_HALF_UP));

set.add(new BigDecimal(2.3).setScale(2, BigDecimal.ROUND_HALF_UP));

set.add(new BigDecimal(3.4).setScale(2, BigDecimal.ROUND_HALF_UP));

set.add(new BigDecimal(2.4).setScale(2, BigDecimal.ROUND_HALF_UP));

set.add(new BigDecimal(0.4).setScale(2, BigDecimal.ROUND_HALF_UP));

set.add(new BigDecimal(9.4).setScale(2, BigDecimal.ROUND_HALF_UP));

TreeSet sortedSet = new TreeSet<>(Comparator.naturalOrder());

sortedSet.addAll(set);

System.out.println(sortedSet);

BigDecimal value1 = sortedSet.ceiling(new BigDecimal(0.5).setScale(2, BigDecimal.ROUND_HALF_UP));

System.out.println("根据0.5可以取到元素:" + value1);

BigDecimal value2 = sortedSet.ceiling(new BigDecimal(2.35).setScale(2, BigDecimal.ROUND_HALF_UP));

System.out.println("根据2.35可以取到元素:" + value2);

BigDecimal value3 = sortedSet.ceiling(new BigDecimal(11).setScale(2, BigDecimal.ROUND_HALF_UP));

System.out.println("根据11可以取到元素:" + value3);

}

}

--------------------------------------------------------------------------------------------

结果如下:

[0.40, 1.20, 2.30, 2.40, 3.40, 9.40]

根据0.5可以取到元素:1.20

根据2.35可以取到元素:2.40

根据11可以取到元素:null

相关推荐

「熱銷全球,峇厘島必買伴手禮」MaxTea 美詩茶飲 globalsips
2025 MIUI 13 字型懶人包,推薦清單整理 :: 哇哇3C日誌
365bet官网注册

2025 MIUI 13 字型懶人包,推薦清單整理 :: 哇哇3C日誌

📅 11-03 👁️ 9490
面对球员恶劣行为:世界杯赛场上的道德拷问与纪律整顿