java set类_java中set类型集合解析(一)

集合的体系:

-----------------Collection  单例集合接口

----------------------List 如果实现的是List接口的集合,具备有序,可重复的特性

-----------------------------ArrayList  底层是维护了一个Object数组实现的。 特点: 查询速度快,增删慢。

-----------------------------LinkedList  底层是使用链表数据结构实现的,特点:查询速度慢,增删块

-----------------------------Vector  底层维护了一个Object类型的数组,和ArrayList 基本一致,特点:线程安全,但是操作效率低 (出现的早,西安基本被ArrayList  替代了)

----------------------Set  如果实现的是Set接口的集合,具备无序,不可重复的特性

-----------------------------HashSet  底层是使用了哈希表实现的,特点:存取快

-----------------------------TreeSet   底层是使用红黑树(二叉树)存储的,特点:直接排序(前提是元素具备自然顺序的属性)

-----------------------------------------本文重点对Set集合进行说明------------------------------------------------

HashSet:

存储的原理:

往HashSet中添加元素的时候,会先调用hashCode()方法,查询哈希值,然后通过得到的元素的哈希值然后通过移位等运算确定元素的存储位置;

1、当确定好的元素的位置处没有其他的元素,则直接将该元素存储在这个位置

2、当确定好的元素的位置处还有其他的元素,则会先调用元素的equals方法,确认两个元素是否一致,如果一致认为是重复元素,不会添加成功,如果不一致,继续添加到该位置处(hash存储是以桶的形式存储的,一个位置可以允许有多个元素)

如下是hashSet使用场景,一个简单的例子

/*需求:支持从键盘输入用户名和密码,如果输入的用户名已经存在了 则不允许添加。。。*/

importjava.util.HashSet;importjava.util.Scanner;classUser{

String username;

String password;publicUser(String username,String password){this.username =username;this.password =password;

}

@Override//重写equals方法,设置比较用户名

public booleanequals(Object obj) {

User user=(User) obj;return this.username.equals(user.username);

}

@Override//重写toString方法,主要是用来显示已注册用户的(格式自定义)

publicString toString() {return "{"+username+":"+password+"}";

}

@Override//重写hashCode方法,用用户名来确定存储位置

public inthashCode() {return this.username.hashCode();

}

}public classhashSetPractise {static HashSet users = newHashSet();staticUser user;public static voidmain(String[] args) {

Scanner sc= newScanner(System.in);while(true){

System.out.println("请输入用户名:");

String username=sc.next();

System.out.println("请输入密码:");

String password=sc.next();

user= newUser(username,password);//add方法返回的是一个boolean类型的数据,true表示添加成功

if(users.add(user)){

System.out.println("注册成功");

System.out.println("当前注册的用户:"+users);

}else{

System.out.println("重复注册了。。");

}

}

}

}

TreeSet:

特点

如果元素具备自然顺序 的特性,那么就按照元素自然顺序的特性进行排序存储。

treeSet要注意的事项

1. 往TreeSet添加元素的时候,如果元素本身具备了自然顺序的特性,那么就按照元素自然顺序的特性进行排序存储(比如说元素是int类型数据,元素是char类型数据等)

2. 往TreeSet添加元素的时候,如果元素本身不具备自然顺序的特性(自定义的元素),那么该元素所属的类必须要实现Comparable接口,把元素的比较规则定义在compareTo(T o)方法上。

3. 如果比较元素的时候,compareTo方法返回 的是0,那么该元素就被视为重复元素,不允许添加.(注意:TreeSet与HashCode、equals方法是没有任何关系。)

4. 往TreeSet添加元素的时候, 如果元素本身没有具备自然顺序 的特性,而元素所属的类也没有实现Comparable接口,那么必须要在创建TreeSet的时候传入一个比较器(实际上就是单独定义一个类实现Comparator接口的的Compare方法)

5. 往TreeSet添加元素的时候,如果元素本身不具备自然顺序的特性,而元素所属的类已经实现了Comparable接口, 在创建TreeSet对象的时候也传入了比较器那么是以比较器的比较规则优先使用。

使用方法

1、具备自然顺序的就不在赘述,能实现自动排序,不需要比较器等其他方法;

2、实现Conparable接口的CompareTo方法实现

importjava.util.TreeSet;/*需求,定义一个员工类并传入员工,按照工资从小到大排序*/

class Emp implementsComparable{intid;

String name;intsalary;public Emp(int id,String name,intsalary){this.id =id;this.name =name;this.salary =salary;

}

@OverridepublicString toString() {return "{"+id+","+name+","+salary+"}";

}

@Override//实现compareTo方法//这个方法会返回一个负整数,零或正整数,代表该对象小于,等于或大于指定对象。

public intcompareTo(Object o) {

Emp emp=(Emp) o;return this.salary-emp.salary;

}

}public classtreeSet {public static voidmain(String[] args) {

TreeSet tree= newTreeSet();

tree.add(new Emp(110,"Mary",1800));

tree.add(new Emp(100,"kobe",1500));

tree.add(new Emp(109,"JackJones",3200));

tree.add(new Emp(440,"James",400));//如果不实现Comparable的compareTo方法,会报错,因为默认treeSet会进行排序,不指定的话不知道依据什么排序

System.out.println(tree);

}

}

3、定义一个比较器(推荐使用比较器方法实现,会使代码更加灵活)

importjava.util.Comparator;importjava.util.TreeSet;classEmp {intid;

String name;intsalary;public Emp(int id,String name,intsalary){this.id =id;this.name =name;this.salary =salary;

}

@OverridepublicString toString() {return "{"+id+","+name+","+salary+"}";

}

}/*定义一个比较器并实现compare方法,方法和compareTo一样,返回的是负整数,零或者正整数,分别代表小于,等于和大于*/

class MyCompare implementsComparator{

@Overridepublic intcompare(Object o1, Object o2) {

Emp p1=(Emp) o1;

Emp p2=(Emp) o2;return p1.id-p2.id;

}

}public classtreeSet {public static voidmain(String[] args) {

MyCompare myCompare= newMyCompare();

TreeSet tree= newTreeSet(myCompare);

tree.add(new Emp(110,"Mary",1800));

tree.add(new Emp(100,"kobe",1500));

tree.add(new Emp(109,"JackJones",3200));

tree.add(new Emp(440,"James",400));

System.out.println(tree);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值