一 set集合结构及特点
结构:
特点:
1.1 无序的 元素不能正确的排序
1.2 无重复 元素内容不能重复
1.3 无索引 证明没有下标不能进行修改操作
案例:
public class Demo1 { public static void main(String[] args) { Set hs= new HashSet<>();//实例化set集合 hs.add("aa");//向set集合中添加元素 hs.add("哈哈哈"); hs.add("我是高手"); hs.add("cc"); hs.add("嗡嗡嗡"); hs.add("嗡嗡嗡");//此cc元素添加不了 特点不可重复 for (Object object : hs) { System.out.println(object); } } }
控制台运行结果:
可以看到输出结果是4个,并没有输出重复值。所以,得出特点1,2:不能重复并且无序
注意:set集合特点与list集合特点相反。
二: Set的遍历方式(两种)
2.1 foreach遍历
2.3 iterator(迭代器)
两种案例:
public class Demo2 { public static void main(String[] args) { HashSet hs= new HashSet<>();//实例化set集合 hs.add("aa");//向set集合中添加元素 hs.add("bb"); hs.add("cc"); /** * foreach 循环方式遍历set */ for (Object object : hs) { System.out.println(hs); } System.out.println("========================="); /** * iterator(迭代器)遍历方式 */ Iterator it = hs.iterator(); while(it.hasNext()) { System.out.println(it.next()); } } }
运行结果:
注意:不能使用for循环,Set集合不能单独取值,因为没有下标。
三:Set集合的去重原理
3.1原理
HashSet集合底层原理调用HashCode方法与equals方法进行比较
3.2优先级别
先调用HashCode进行元素判断比较(每次比较元素都会调用一次HashCode方法进行 比较) 如果元素相同(如果不理解请看下面控制台输出噢)
后比较equals方法判断进行判断元素内容是否一致
注意:List与Set去重原理不一样 List只需要重写equals,HashSet要重写HashCode及 equals两种方法
去重案例:
public class Demo3 { public static void main(String[] args) { HashSet hs = new HashSet<>();// 实例化set集合 hs.add(new Person(1, "小花"));// 向set集合中添加元素 hs.add(new Person(2, "小名"));// 向set集合中添加元素 hs.add(new Person(3, "小明"));// 向set集合中添加元素 System.out.println(hs.contains(new Person(3, "小明")));// // hs.add(new Person(3, "小明")); // System.out.println(hs); } } class Person { private int id; private String name; public Person() { // TODO Auto-generated constructor stub } public Person(int id, String name) { super(); this.id = id; this.name = name; } @Override public String toString() { return "Person [id=" + id + ", name=" + name + "]"; } 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; } //重写hashCode方法 @Override public int hashCode() { System.out.println("hashCode被调用了... "); final int prime = 31; int result = 1; result = prime * result + id; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } //重写equals方法 @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; Person other = (Person) obj; if (id != other.id) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } }
控制台运行:
提示:会发现上面控制台调用了四次HashCode方法。因为每次HashCode方法每次都会一次一次的去底层数据去进行比较,如果一致会再调用equals方法进行比较 返回true或false
四:Comparable(自然排序)和Comparator(比较器排序)
4.1 Comparable排序
想要自然排序要进行实体实现comparable(lang包中)接口并重写其中的方法并返回return 值想要排序的数据
- this比较元素对象是进行升序
- 元素对象比较this的进行降序
最后最后实例化TreeSet 进行自然排序
注意:如果直接实例化TreeSet会报错 因为没有实现comparable并重写里面的方法哦!
实操代码:
public class Demo4 { public static void main(String[] args) { System.out.println("==============系统默认排序==无规则排序==========="); HashSet hs = new HashSet<>();// 实例化set集合 hs.add(new Person1(1, "老牛", 22, 12444));// 向set集合中添加元素 hs.add(new Person1(2, "老王", 23, 12345)); hs.add(new Person1(3, "老六", 24, 54331)); hs.add(new Person1(4, "老四", 30, 34141)); // 默认 底层set默认排序 for (Object object : hs) { System.out.println(object); } System.out.println("===============自然排序=============="); // 实列自然排序 TreeSet ts = new TreeSet<>(); for (Object object : hs) { ts.add(object);//将系统排序添加到自然排序 } //重新遍历自然排序 for (Object object : ts) { System.out.println(object); } } } class Person1 implements Comparable<Person1> { //person1继承自然排序接口 最下面必须重写comparable方法 private int id; private String name; private int age; private int money; public Person1() { // TODO Auto-generated constructor stub } public Person1(int id, String name, int age, int money) { super(); this.id = id; this.name = name; this.age = age; this.money = money; } @Override public String toString() { return "Person1 [id=" + id + ", name=" + name + ", age=" + age + ", money=" + money + "]"; } 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 int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getMoney() { return money; } public void setMoney(int money) { this.money = money; } @Override public int compareTo(Person1 o) {//重写Comparable方法 return this.age - o.age; // } }
运行结果:
4.2Comparator(比较器排序)
4.2.3比较器说明
能对多个对象数据进行排序
4.2.3使用方法
比较器进行排序在自然排序流程后面需要同时使用,实列自然排序TreeSet再匿名实列 比较器(如下图)重写compare方法
4.2.3匿名实列比较器
实操代码
public class Demo4 { public static void main(String[] args) { System.out.println("==============系统默认排序==无规则排序==========="); HashSet hs = new HashSet<>();// 实例化set集合 hs.add(new Person1(1, "老牛", 22, 12444));// 向set集合中添加元素 hs.add(new Person1(2, "老王", 23, 12345)); hs.add(new Person1(3, "老六", 24, 54331)); hs.add(new Person1(4, "老四", 30, 34141)); // 默认 底层set默认排序 for (Object object : hs) { System.out.println(object); } System.out.println("===============自然排序=============="); // 实列自然排序 TreeSet ts = new TreeSet<>(); for (Object object : hs) { ts.add(object);//将系统排序添加到自然排序 } //重新遍历自然排序 for (Object object : ts) { System.out.println(object); } System.out.println("==============比较器排序==先金额排序后年龄排序========="); TreeSet tsPlusvip = new TreeSet<>(new Comparator<Person1>() {//自然排序实现比较器接口 @Override // 重写比较器中方法 public int compare(Person1 o1, Person1 o2) { //按金额比相同 int num = o2.getMoney() - o1.getMoney(); if(num==0) {//判断如果金额等于0 return o1.getAge() - o2.getAge();//就按年龄比相同 } return num;//继续按照金额比相同 返回金额 } }); for (Object object : hs) { tsPlusvip.add(object); } for (Object object : tsPlusvip) { System.out.println(object); } } } class Person1 implements Comparable<Person1> { //person1继承自然排序接口 最下面必须重写comparable方法 private int id; private String name; private int age; private int money; public Person1() { // TODO Auto-generated constructor stub } public Person1(int id, String name, int age, int money) { super(); this.id = id; this.name = name; this.age = age; this.money = money; } @Override public String toString() { return "Person1 [id=" + id + ", name=" + name + ", age=" + age + ", money=" + money + "]"; } 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 int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getMoney() { return money; } public void setMoney(int money) { this.money = money; } @Override public int compareTo(Person1 o) {//重写Comparable方法 return this.age - o.age; // } }
运行控制台:
注意:如果要进行多个数据排序的话,要进行判断,如上图是优先根据金额排序后 排序年龄的
这就是小编给大家整理的一些Set集合内容 感谢观看!