知识梳理
前言
这次博客给大家带来的是Collection下的Set集合
list和set区别对比:
Set不允许元素重复。HashSet和TreeSet是两个主要的实现类。
List有序且允许元素重复。ArrayList、LinkedList和Vector是三个主要的实现类。
一、特点
①不可重复
②无序
代码如下(示例):
① 不可重复:
public class dome1 { public static void main(String[] args) { /** * set集合特点 * 1:set集合是不重复的 */ //新建set集合 Set<String> set=new HashSet<String>(); set.add("a"); set.add("b"); set.add("c"); set.add("a"); System.out.println(set); } }
输出结果:
②无序
public class dome1 { public static void main(String[] args) { /** * set集合特点 * 2:set集合是无序的 */ //新建set集合 Set<String> set=new HashSet<String>(); set.add("d"); set.add("b"); set.add("f"); set.add("r"); System.out.println(set); } }
输出结果:
二、遍历方法
1.iterator 迭代器 2.foreach
代码如下(示例):
package com.xhy.set; import java.util.HashSet; import java.util.Iterator; import java.util.Set; public class demo2 { public static void main(String[] args) { Set<Object>set=new HashSet<>(); set.add(new Student("小李", 29)); set.add(new Student("小晓", 29)); set.add(new Student("小华", 29)); set.add(new Student("小胡", 29)); //foreach for (Object o : set) { System.out.println(o); } System.out.println("======================="); //迭代器 Iterator<Object>it=set.iterator(); while(it.hasNext()) { System.out.println(it.next()); } } } class Student{ private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; } public Student(String name, int age) { super(); this.name = name; this.age = age; } public Student() { // TODO Auto-generated constructor stub }
输出结果:
三、HashSet哈希表储存.重复元素储存底层探究
set集合调用HashCode与equals两种方法
set集合去重原理:
①hashset底层数据结构是哈希表
②优先会调用hashcode方法对比地址
③然后调用equals方法对比值
代码论证:
//添加hashCode方法和equals方法
@Override
public int hashCode() {
System.out.println("hashcode被调用");
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
System.out.println("equals方法被调用");
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
①当把hashcode()返回的地址不同时 输出的结果前四个显示hashcode()方法被调用说明是
先进行hashcode()方法的判断判断是否有形同的地址
②当hashcode()方法地址相同时
输出的第一个结果为hashcode()方法被调用---因为set集合里面没值这是第一个地址
输出的第二个结果为hashcode()方法被调用---因为是新建了个地址但地址相同则
输出的第三个结果就为equals()方法被调用
等等。。。
![]()
四、TreeSet
特点:
有序不重复,添加进去的元素会排好序,因为它实现了SortedSet接口,具有排序功能。
1、自然排序:
示例代码如下:
package com.xhy.set; import java.util.TreeSet; public class demo2 { public static void main(String[] args) { TreeSet<Student>set=new TreeSet<Student>(); set.add(new Student("张三",60)); set.add(new Student("王五",59)); set.add(new Student("李四",20)); set.add(new Student("张三",40)); set.add(new Student("张三",30)); //foreach for (Student o : set) { System.out.println(o); } } } class Student implements Comparable{ private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; } public Student(String name, int age) { super(); this.name = name; this.age = age; } public Student() { // TODO Auto-generated constructor stub super(); } @Override public int compareTo(Object o) { // TODO Auto-generated method stub Student s=(Student)o; return this.age-s.age; } }
运行结果如下:
注意报错:
原因:
Student类没有实现接口,在添加Student时会调用compareTo()方法进行排序。Student无法转换成Comparable类去调用该方法。
2.比较器排序:
示例代码如下(按年龄升序):
Set<User> set=new TreeSet<>(new Comparator() { @Override public int compare(Object o1, Object o2) { return ((User) o1).getAge() -((User)o2).getAge(); } }); set.add(new User("张三",60)); set.add(new User("王五",59)); set.add(new User("李四",20)); set.add(new User("张三",40)); set.add(new User("张三",30)); for (User user : set) { System.out.println(user); } } } /** * 按照年龄升序 * @author zjjt * */ class User implements Comparator{ private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "User [name=" + name + ", age=" + age + "]"; } public User(String name, int age) { super(); this.name = name; this.age = age; } public User() { super(); // TODO Auto-generated constructor stub } @Override public int compare(Object o1, Object o2) { User u =(User) o2; return u.age -this.age; }
输出结果:
示例代码如下(按年龄降序):
@Override public int compare(Object o1, Object o2) { return -(((User) o1).getAge() -((User)o2).getAge())); } });
输出结果:
示例代码如下(按年龄降序):
@Override public int compare(Object o1, Object o2) { String name=((User) o1).getName(); String name2=((User) o2).getName(); return name.compareTo(name2); } });