Set实现类 HashSet: 基于HashCode实现元素不重复 当存入元素的哈希码相同时,会调用equals进行确认,如结果为true,则拒绝后者接入。 TreeSet : 基于排列顺序实现元素不重复 实现了SortedSet接
Set实现类
HashSet:
- 基于HashCode实现元素不重复
- 当存入元素的哈希码相同时,会调用equals进行确认,如结果为true,则拒绝后者接入。
TreeSet:
- 基于排列顺序实现元素不重复
- 实现了SortedSet接口,对集合元素自动排序
- 元素对象的类型必须实现Comparable接口,指定排序规则
- 通过ComparaTo方法确定是否为重复元素
set接口:
package com.java.leetcode.collection; import java.util.HashSet; import java.util.Iterator; import java.util.Set; /* 测试set集合的使用 特点:无序,无下标,不能重复 */ public class HSet01 { public static void main(String[] args) { Set<String> set = new HashSet<>(); set.add("娃哈哈"); set.add("苹果"); set.add("雪梨"); set.add("杏"); System.out.println(set);//打印顺序和添加顺序无关 set.add("苹果"); System.out.println("再次添加苹果后"+set);//不能重复 set.remove("娃哈哈");//不能用下标 System.out.println("删除娃哈哈后"+set); //遍历,因为没有下标,不能使用for,可以使用增强for和迭代器 System.out.println("*******使用增强for遍历******"); for (String s:set ) { System.out.println(s); } //使用迭代器 System.out.println("*******使用迭代器遍历******"); Iterator<String> it = set.iterator(); while (it.hasNext()){ System.out.println(it.next()); } //判断 System.out.println("集合中是否存在雪梨?"+set.contains("雪梨")); System.out.println("集合是否为空?"+set.isEmpty()); } }
运行结果:
HashSet:
1.
package com.java.leetcode.collection; import java.util.HashSet; import java.util.Iterator; /* HashSet集合的使用 存储结构:哈希表(数组+链表+红黑树) */ public class HSet02 { public static void main(String[] args) { //新建集合 HashSet<String> hashSet = new HashSet<>(); hashSet.add("黄桃"); hashSet.add("雪梨"); hashSet.add("桑葚"); hashSet.add("橘子"); System.out.println(hashSet);//无序 hashSet.add("橘子"); System.out.println("再次添加橘子后:"+hashSet); //删除 hashSet.remove("橘子"); System.out.println("s删除橘子后:"+hashSet); //遍历 System.out.println("*********使用增强for*******"); for(String s:hashSet){ System.out.println(s); } System.out.println("*********使用迭代器*******"); Iterator<String> it = hashSet.iterator(); while (it.hasNext()){ System.out.println(it.next()); } //判断 System.out.println("集合中存在苹果吗?"+hashSet.contains("苹果")); System.out.println("集合为空吗?"+hashSet.isEmpty()); } }
运行结果:
2.
package com.java.leetcode.collection; import java.util.HashSet; import java.util.Iterator; /* HashSet的使用 存储过程:1.根据hashcode计算保存的位置,如果位置为空,则直接保存,不为空执行第二步 2.再执行equals方法,如果equals方法为true ,则认为是重复,否则,形成链表 */ public class HSet03 { public static void main(String[] args) { HashSet<FruitBean> fruitSet = new HashSet<FruitBean>(); FruitBean apple = new FruitBean("苹果","红色"); FruitBean yellowPeach = new FruitBean("黄桃","黄色"); FruitBean pitaya = new FruitBean("火龙果","红色"); FruitBean snowPear = new FruitBean("雪梨","黄色"); FruitBean plum = new FruitBean("李子","青色"); fruitSet.add(apple); fruitSet.add(yellowPeach); fruitSet.add(pitaya); fruitSet.add(snowPear); fruitSet.add(plum); fruitSet.add(new FruitBean("雪梨","黄色"));//成功添加,想让他添加失败,需要重写hashcode和equals方法 fruitSet.add(plum);//添加无效,因为重复 System.out.println(fruitSet.toString());//无序 //删除 fruitSet.remove(apple); fruitSet.remove(new FruitBean("火龙果","红色")); //没重写hashcode和equals方法前,该形式不能成功删除。 System.out.println("删除之后"+fruitSet.toString()); //遍历 System.out.print("*****增强for遍历*****"); for(FruitBean f:fruitSet){ System.out.print(f); } System.out.println(); System.out.print("*****迭代器遍历*****"); Iterator<FruitBean> it = fruitSet.iterator(); while (it.hasNext()){ System.out.print(it.next()); } System.out.println(); System.out.println("是否存在apple?"+fruitSet.contains(apple)); System.out.println("是否存在plum?"+fruitSet.contains(plum)); System.out.println("是否存在青色的李子?"+fruitSet.contains(new FruitBean("李子","青色"))); } }
重写hashcode和equals方法:
//注释部分为自己写的,后面为快捷键生成 alt+insert==>选择equals()and hashcode() 或者 右键==>Generate==>选择equals()and hashcode()
// @Override // public boolean equals(Object o) { // if (this == o) return true; // if (o == null) return false; // if(o instanceof FruitBean){ // FruitBean fruit = (FruitBean)o; // //如果o的属性和当前属性一样,就返回true // if (this.name.equals(fruit.getName()) && this.color.equals(fruit.getColor())){ // return true; // } // } // return false; // } // // @Override // public int hashCode() { // int nc = this.name.hashCode(); // int cc = this.color.hashCode(); // return nc + cc; // } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; FruitBean fruitBean = (FruitBean) o; return name.equals(fruitBean.name) && color.equals(fruitBean.color); } @Override public int hashCode() { return Objects.hash(name, color); }
运行结果:
TreeSet:
1.
package com.java.leetcode.collection; import java.util.Iterator; import java.util.TreeSet; /* TreeSet的使用 存储结构:红黑树 基于排列顺序实现元素不重复 实现了SortedSet接口,对集合元素自动排序 元素对象的类型必须实现Comparable接口,指定排序规则 通过ComparaTo方法确定是否为重复元素 */ public class TSet01 { public static void main(String[] args) { //1.创建集合 TreeSet<String> treeSet = new TreeSet<>(); treeSet.add("apple"); treeSet.add("plum"); treeSet.add("peach"); treeSet.add("pear"); System.out.println(treeSet); treeSet.add("plum");//添加重复元素,失败 //删除 treeSet.remove("pear"); System.out.println(treeSet); //遍历 System.out.println("********使用增强for********"); for (String s:treeSet){ System.out.println(s); } System.out.println("********使用迭代器********"); Iterator<String> it = treeSet.iterator(); while (it.hasNext()){ System.out.println(it.next()); } } }
运行结果:
2.
package com.java.leetcode.collection; import java.util.TreeSet; /* 使用TreeSet保存数据 存储结构:红黑树 */ public class TSet02 { public static void main(String[] args) { TreeSet<FruitBean> fruitTree = new TreeSet<>(); FruitBean apple = new FruitBean("苹果","红色"); FruitBean yellowPeach = new FruitBean("黄桃","黄色"); FruitBean pitaya = new FruitBean("火龙果","红色"); FruitBean snowPear = new FruitBean("雪梨","黄色"); FruitBean plum = new FruitBean("李子","青色"); fruitTree.add(apple); fruitTree.add(yellowPeach); fruitTree.add(pitaya); fruitTree.add(snowPear); fruitTree.add(plum); System.out.println(fruitTree); } }
若这样写会报错:
原因:TreeSet的存储结构为红黑树,需要实现Comparable接口,指定排序规则。
修改FruitBean类,使之实现Comparable接口:
package com.java.leetcode.collection; import java.util.Objects; public class FruitBean implements Comparable<FruitBean>{ private String name; private String color; public FruitBean(String name, String color) { this.name = name; this.color = color; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } @Override public String toString() { return "\n"+"name=" + name + ", color=" + color ; } @Override public int compareTo(FruitBean o) { //比较 int nn = this.getName().compareTo(o.getName()); int cn = this.getColor().compareTo(o.getColor()); return nn == 0?cn:nn; //如果名字一样就按颜色排序;如果名字不一样就按名字排序 } }
package com.java.leetcode.collection; import java.util.TreeSet; /* 使用TreeSet保存数据 存储结构:红黑树 要求:元素必须实现Comparable接口,指定排序规则 */ public class TSet02 { public static void main(String[] args) { TreeSet<FruitBean> fruitTree = new TreeSet<>(); FruitBean apple = new FruitBean("苹果","红色"); FruitBean yellowPeach = new FruitBean("黄桃","黄色"); FruitBean pitaya = new FruitBean("火龙果","红色"); FruitBean snowPear = new FruitBean("雪梨","黄色"); FruitBean plum = new FruitBean("李子","青色"); FruitBean plum2 = new FruitBean("李子","红色"); fruitTree.add(apple); fruitTree.add(yellowPeach); fruitTree.add(pitaya); fruitTree.add(snowPear); fruitTree.add(plum); fruitTree.add(plum2); System.out.println(fruitTree); //实现Comparable接口,重写compareTo方法后成功输出 fruitTree.remove(pitaya); fruitTree.remove(new FruitBean("雪梨","黄色"));//不重写equals()方法也能删除,因为已经实现了Comparable接口 System.out.println("删除后"+fruitTree); //遍历,增强for,迭代器。。。写太多了,不写了 //判断 System.out.println("集合中是否存在apple?"+fruitTree.contains(apple)); System.out.println("集合中是否存在红色的苹果?"+fruitTree.contains(new FruitBean("苹果","红色")));//同上,不需要重写equlas() } }
运行结果:
Comparator接口:
package com.java.leetcode.collection; import java.util.Comparator; import java.util.TreeSet; /* TreeSet的使用 Comparator:实现定制比较(比较器) Comparable:可比较的 */ public class TSet03 { public static void main(String[] args){ //匿名内部类 TreeSet<FruitBean> fruitTreeSet = new TreeSet<>(new Comparator<FruitBean>() { @Override public int compare(FruitBean o1, FruitBean o2) { int nn = o1.getName().compareTo(o2.getName()); int cn = o1.getColor().compareTo(o2.getColor()); return nn == 0 ? cn : nn; //如果名字一样就比较颜色;颜色一样就比较名字 } }); FruitBean apple = new FruitBean("苹果","红色"); FruitBean yellowPeach = new FruitBean("黄桃","黄色"); FruitBean pitaya = new FruitBean("火龙果","红色"); FruitBean snowPear = new FruitBean("雪梨","黄色"); FruitBean plum = new FruitBean("李子","青色"); FruitBean plum2 = new FruitBean("李子","红色"); fruitTreeSet.add(apple); fruitTreeSet.add(yellowPeach); fruitTreeSet.add(pitaya); fruitTreeSet.add(snowPear); fruitTreeSet.add(plum); fruitTreeSet.add(plum2); System.out.println(fruitTreeSet); } }
运行结果
实现Comparator后可不再实现Comparable接口
案例:使用TreeSet集合实现字符串按照长度排序
package com.java.leetcode.collection; import java.util.Comparator; import java.util.TreeSet; /* 使用TreeSet集合实现字符串按照长度排序 Comparator:定制比较 */ public class TSet04 { public static void main(String[] args) { TreeSet<String> treeSet = new TreeSet<>(new Comparator<String>() { @Override public int compare(String o1, String o2) { int n1 = o1.length() - o2.length(); int n2 = o1.compareTo(o2); return n1 == 0 ? n2 : n1 ; //先比较长度,如果长度一样,就比较内容 } }); treeSet.add("hello word"); treeSet.add("apple"); treeSet.add("pear"); treeSet.add("aaaaa"); treeSet.add("cat"); treeSet.add("first"); System.out.println(treeSet.toString()); } }
运行结果: