对应数据结构中的哈希表:无序、不重复的非线性结构
set原码:
不能包含重复元素的的集合,通常情况,set包含单独的值(map是键值对)
add()、contains()
- @Test
- void testSet01() {
- // HashSet 是java中的一个标准的哈希表
- Collection
nums = new HashSet<>(); - nums.add(123);
- nums.add(456);
- nums.add(789);
- nums.add(1);
- nums.add(13);
- nums.add(258);
- nums.add(10);
- System.out.println(nums);
- }
和自己添加的值顺序不同,无序
无序不是随机,会用特定的hash算法算值,而不是随机
- @Test
- void testSet01() {
- // HashSet 是java中的一个标准的哈希表
- Collection
nums = new HashSet<>(); - nums.add(123);
- nums.add(456);
- nums.add(789);
- nums.add(1);
- nums.add(13);
- nums.add(258);
- nums.add(10);
- // add方法会返回一个boolean,表示是否添加成功
- System.out.println(nums.add(31));
- // 添加失败,返回false,表示之前已经存在了这个值
- System.out.println(nums.add(31));
-
- //是否包含某个元素
- System.out.println(nums.contains(1));
- System.out.println(nums.contains(11));
- System.out.println(nums);
- }
注意:哈希表是无序的(没有下标),因此无法使用常规的循环,通过下标访问
(1)迭代器访问
- @Test
- void testSet02() {
- // HashSet 是java中的一个标准的哈希表
- Collection
nums = new HashSet<>(); - nums.add(123);
- nums.add(456);
- nums.add(789);
- nums.add(1);
- nums.add(13);
- nums.add(258);
- nums.add(10);
-
- //迭代器访问
- Iterator
it = nums.iterator(); - while (it.hasNext()) {
- System.out.println(it.next());
- }
-
- }
(2)for循环加强进行遍历
for (Integer i : nums) {
System.out.println(i);
}
(3)forEach进行遍历
nums.forEach((i) ->System.out.println(i));
这个set是使用二叉树(红黑树)实现的一个集合,因此该集合是有序的
(1). 字符串按accll码值排序
- @Test
- void testSet03() {
- Set
ss = new TreeSet<>(); -
- // 有序的集合
- ss.add("apply");
- ss.add("huawei");
- ss.add("mi");
- ss.add("mm");
- ss.add("vivo");
- ss.add("OPPO");
-
- System.out.println(ss);
- }
(2). 数字按大小排序
- @Test
- void testSet04() {
- Set
ss = new TreeSet<>(); - // 有序的集合
- ss.add(1);
- ss.add(2);
- ss.add(33);
- ss.add(333);
- ss.add(12);
- ss.add(102);
- ss.add(50);
- System.out.println(ss);
- }
(3).对象
先定义一个Person类
- package com.openlab.day20.entity;
-
- public class Person {
-
- private int id;
- private String name;
- private String nickname;
- private String gender;
- private int age;
-
- public int getId() {
- return id;
- }
-
- public void setId(int id) {
- this.id = id;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String getNickname() {
- return nickname;
- }
-
- public void setNickname(String nickname) {
- this.nickname = nickname;
- }
-
- public String getGender() {
- return gender;
- }
-
- public void setGender(String gender) {
- this.gender = gender;
- }
-
- public int getAge() {
- return age;
- }
-
- public void setAge(int age) {
- this.age = age;
- }
-
- public Person() {
- }
-
- public Person(int id, String name, String nickname, String gender, int age) {
- super();
- this.id = id;
- this.name = name;
- this.nickname = nickname;
- this.gender = gender;
- this.age = age;
- }
-
- @Override
- public String toString() {
- return "Person [id=" + id + ", name=" + name + ", nickname=" + nickname + ", gender=" + gender + ", age=" + age
- + "]";
- }
-
- }
- @Test
- void testSet06() {
- Set
ss = new TreeSet<>(); - ss.add(new Person(1, "cc", "曹孟德", "男", 32));
- ss.add(new Person(2, "lb", "刘玄德", "男", 28));
- ss.add(new Person(3, "sq", "孙百万", "男", 18));
- ss.add(new Person(4, "zf", "张翼德", "男", 24));
- ss.add(new Person(5, "gy", "关云长", "男", 26));
- ss.add(new Person(6, "hhd", "夏侯惇", "男", 43));
- ss.add(new Person(7, "lb", "吕奉先", "男", 23));
- ss.add(new Person(8, "dc", "貂蝉", "男", 16));
-
- System.out.println(ss);
- }
jvm不知道Person类应该怎样排序
String和Integer在定义的时候已经指定了排序规则,而我们自己写的Person没有制定规则,是让jvm自动去完成,但是jvm也不知道
注意:在java中,如果对象需要比较,则必须让该类实现Comparable接口
String和Integer(包装类)都实现了此接口
所以Person要想进行比较也需要实现Comparable接口
要求传递一个跟原对象进行比较
Comparable接口有个泛型,要求传递过来一个东西跟原对象进行比较,我们传递Person,比较比较同一个对象,不是同一个对象比较没有意义
重写方法:
该方法返回一个int的值
若返回一个 >0 的数,按照正序排序
若返回一个 <0 的数,按照降序排序
若返回一个 =0 的数,不变
@Override
public int compareTo(Person o) {
return 0;}
- package com.openlab.day20.entity;
-
- public class Person implements Comparable
{ -
- private int id;
- private String name;
- private String nickname;
- private String gender;
- private int age;
-
- public int getId() {
- return id;
- }
-
- public void setId(int id) {
- this.id = id;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String getNickname() {
- return nickname;
- }
-
- public void setNickname(String nickname) {
- this.nickname = nickname;
- }
-
- public String getGender() {
- return gender;
- }
-
- public void setGender(String gender) {
- this.gender = gender;
- }
-
- public int getAge() {
- return age;
- }
-
- public void setAge(int age) {
- this.age = age;
- }
-
- public Person() {
- }
-
- public Person(int id, String name, String nickname, String gender, int age) {
- super();
- this.id = id;
- this.name = name;
- this.nickname = nickname;
- this.gender = gender;
- this.age = age;
- }
-
- @Override
- public String toString() {
- return "Person [id=" + id + ", name=" + name + ", nickname=" + nickname + ", gender=" + gender + ", age=" + age
- + "]";
- }
-
- @Override
- public int compareTo(Person o) {
- // 指定需要排序的规则!!!
-
- // 指定规则:id的升序排列
- // return this.getId() - o.getId();
-
- // 指定规则:age的降序排列
- return o.getAge() - this.getAge();
- }
-
- }
return this.getId() - o.getId();
比较当前对象和下一个对象的id,如果大于零,相当于return 1,
代码相当于
int temp = this.getId() - o.getId();
if(temp > 0){
return 1;
}else{
return -1;
}
且TreeSet是有序的
HashSet就不是了
- @Test
- void testSet05() {
- // 生成一个大小固定的list
- List
list = Arrays.asList(1,3,34,5,5,6,7,88,8,8,88,99); - Set
ss = new TreeSet<>(); - Set
s = new HashSet<>(); - ss.addAll(list);
- System.out.println(ss);
- s.addAll(list);
- System.out.println(s);
- }
Arrays.asList() 将不定长的数据以ArrayList的形式返回,返回的是一个固定大小的ArrayList(传了几个数据就是几个,不能再改变)