黑马程序员——java集合中的TreeSet

Java集合框架之Set接口详解及TreeSet使用
本文深入探讨了Java集合框架中的Set接口及其特性,特别着重于TreeSet的实现方式、元素特点以及如何使用TreeSet进行排序。

 

 


---------------------- <a href="http://edu.youkuaiyun.com"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.youkuaiyun.com"target="blank">.Net培训</a>、期待与您交流! ----------------------

1.        java集合框架中的Set接口:

Java的集合类主要由两个接口派生而出:Collection和Map.

Collection接口派生出了两个重要的子接口:List、Set;

在实现Set接口中的子类中有两个非常重要的类:HashSet 和TreeSet;

2.        Set集合中元素特点:

a)      元素的唯一性:存入Set集合中的每个元素都必须是唯一的,Set集合不允许重复元素的存在。这与List集合完全不同,List集合允许对同一个对象进行多次存入;

b)      元素存取的无序性:该无序指的是元素取出时的顺序与存入时的顺序在大多情况下都是不一致的;而List集合取出时元素的顺序与存入时的顺序完全相同;

c)      元素在内存中的有序性:虽然Set集合中的元素在取出时看起来像是无序的,但是这些元素在内存中的排列时有序的,比如HashSet集合中的元素实际上是按元素的hashcode值的大小依次排列的,而TreeSet集合中的元素则是按对象的自然顺序或是程序员指定的顺序进行排列的;

 

3.       Set集合中的TreeSet:

TreeSet 集合的底层数据结构是二叉树结构。当用TreeSet 集合进行存储对象时,该集合会对存入其中的元素按照自然顺序或指定的顺序进行排序。因此,对象被存储时必须可比较。

实现这种可比较性的方式有两种:

a)      被存储的对象所属的类实现Comparable 接口,并复写其中的compareTo()方法;从而使对象本身具有可比较性,TreeSet集合将依据compareTo方法的返回值,确定元素在TreeSet数据结构中的位置。

b)      若对象本身不具有可比较性,则可以创建一个比较器,使其实现Comparator接口,并复写其中的compare() 方法,然后把该比较器的对象作为参数传入TreeSet集合中。

TreeSet集合同样需要保证其中元素的唯一性,而它保证元素唯一性的方式就是通过compareTo() 方法的返回结果或Comparator类中的compare() 方法的返回结果进行判定的。

在复写compareTo() 或 compare() 方法时,需要分主要条件和次要条件,当主要条件相同时,必须判断次要条件,按照次要条件排序。

下面同样以Person类为例,创建Person类对象,并把对象存入TreeSet集合中,排序方式按照年龄的大小,若年龄相同,则再按照姓名进行排序。

下面的代码将分别采用实现Comparable接口和创建Comparator比较器两种方式,代码示例如下:

import java.util.Comparator;

import java.util.TreeSet;

 

public class TreeSetDemo {

 

       public static voidmain(String[] args) {

              TreeSet<Personl>ts=new TreeSet<Personl>();//对存入的元素进行自然排序;

              ts.add(newPersonl("zhangsan",20));

              ts.add(newPersonl("lisi",30));

              ts.add(newPersonl("wangwu",25));

              System.out.println("实现Comparable接口的排序结果为:");

              for (Personl p : ts){

                     System.out.println(p);

              }

              TreeSet<Personl>ts1=new TreeSet<Personl>(new MyComp());//对传入的元素按比较器的方式进行排序;

              ts1.add(newPersonl("zhangsan",20));

              ts1.add(newPersonl("lisi",30));

              ts1.add(newPersonl("wangwu",25));

              System.out.println("创建比较器的排序结果为:");

              for (Personl p : ts1){

                     System.out.println(p);

              }

       }

}

// 创建比较器,复写compare() 方法;

class MyComp implements Comparator<Personl>{

 

       @Override

       public int compare(Personl p1,Personl p2) {

              int num=newInteger(p1.getAge()).compareTo(p2.getAge());

              if (num==0){

                     returnp1.getName().compareTo(p2.getName());

              }

              return num;

       }

}

//实现Comparable接口,复写compareTo() 方法;

class Personl implements Comparable<Personl>{

       private String name;

       private int age;

       public Personl(String name, intage) {

              super();

              this.name = name;

              this.age = age;

       }

       public String getName() {

              return name;

       }

       public void setName(Stringname) {

              this.name = name;

       }

       public int getAge() {

              return age;

       }

       public void setAge(int age) {

              this.age = age;

       }

       @Override   //复写compareTo() 方法;

       public int compareTo(Personl p){

              int num=newInteger(this.age).compareTo(p.age);

              if (num==0){

                     returnthis.name.compareTo(p.name);

              }

              return num;

       }

       @Override  //复写toString() 方法;

       public String toString() {

              return "Personl[name=" + name + ", age=" + age + "]";

       }

}

 

程序运行结果为:

实现Comparable接口的排序结果为:

Personl[name=zhangsan, age=20]

Personl [name=wangwu,age=25]

Personl [name=lisi, age=30]

创建比较器的排序结果为:

Personl[name=zhangsan, age=20]

Personl [name=wangwu,age=25]

Personl [name=lisi, age=30]

两种实现可比较的方式均成功实现;

 

 

 ---------------------- <a href="http://edu.youkuaiyun.com"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.youkuaiyun.com"target="blank">.Net培训</a>、期待与您交流! ----------------------

详细请查看:<a href="http://edu.youkuaiyun.com" target="blank">http://edu.youkuaiyun.com</a>

 

### Java 高级集合进阶教程 #### Set 接口及其子类特性 Set接口是Java集合框架中的一个重要部分,它不允许存储重复元素。这使得`Set`非常适合用于去除重复项以及表示数学上的集合理论概念。 - **HashSet**: 实了`Set`接口,内部基于哈希表实[^3]。其特点是查找速度非常快,因为它是无序的,并且允许null值的存在(仅限一个)。为了保证元素唯一性,在向`HashSet`中添加对象时会调用该对象的`hashCode()`和`equals()`方法来判断是否已经存在相同元素。 ```java import java.util.HashSet; public class Student { private String name; public Student(String name){ this.name = name; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null || getClass() != obj.getClass()) return false; Student other = (Student) obj; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } } ``` - **LinkedHashSet**: 继承自`HashSet`,除了具备后者所有的性质外还保持了插入顺序不变。这意味着当你迭代这个set的时候,你会按照最初加入这些项目的次序得到它们。 - **TreeSet**: 提供了一种有序的方式去保存元素,底层采用红黑树结构实了排序功能。可以通过自然排序(`Comparable`)或定制比较器(`Comparator`)两种方式定义元素之间的大小关系。 #### Collection 和 Map 的区别与联系 在Java中,`Collection`是一个顶层接口,代表一组单一类型的对象列表。而`Map`则用来映射键到值之间的一对一关联,即每一对键都对应着唯一的值[^4]。 对于想要深入了解高级集合特性的开发者来说: - `Collection`适用于处理单列数据; - `Map`更适合于管理具有键值对形式的数据。 了解两者间的差异有助于选择合适的数据容器以满足特定应用场景的需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值