1、今天学了什么
(1)Set集合
Set也是集合中的一个容器,程序可以依次把若干个对象放进Set,但是Set无法保存元素添加的顺序,
Set不允许包含相同的元素,如果把两个相同的元素加入同一个Set中,则添加失败,add()方法会返回false,并且新元素不会被添加。
(2)HashSet
HashSet 是 Set 接口的典型实现,大多数时候使用 Set 集合时就是使用这个实现类。
HashSet 按 Hash算法来存储集合中的元素,因此具有很好的存取和查找性能。
特点:
不能保证元素的排列顺序,顺序可能与添加顺序不同,顺序也有可能发生变化。
HashSet 不是同步的,如果多个线程同时访问一个 HashSet,假设有两个或者两个以上线程同时
修改了HashSet集合时,则必须通过代码来保证其同步。
集合元素值可以是 null。
当向 HashSet 集合中存入一个元素时,HashSet 会调用该对象的 hashCode()方法来得到该对象的 hashCode 值,然后根据该hashCode 值决定该对象在 HashSet 中的存储位置。
如果有两个元素通过equals()方法比较返回 true,但它们的 hashCode()方法返回值不相等,HashSet 将会把它们存储在不同的位置,依然可以添加成功。
也就是说,HashSet 集合判断两个元素相等的标准是两个对象通过 equals()方法比较相等,并且两个对象的 hashCode()方法返回值也相等。
常用Api
public class Test2 {
public static void main(String[] args) {
Set<String> set = new HashSet<>();
//添加元素
set.add("秦始皇");
set.add("唐太宗");
set.add("武则天");
//移除元素
System.out.println(set.remove("贞观之治"));
//获取元素个数
System.out.println(set.size());
//判断是否空集合
System.out.println(set.isEmpty());
// for (String s:set) {
// System.out.println(s);
// }
// Iterator<String> it = set.iterator();
// while (it.hasNext()){
// System.out.println(it.next());
// }
set.forEach(e-> System.out.println(e));
}
}
public class Test {
public static void main(String[] args) {
Set<Student> set = new HashSet<>();
Student s1 = new Student("小明",18);
Student s2 = new Student("小明",18);
Student s3 = new Student("小明",19);
set.add(s1);
System.out.println(set.add(s2));//false
System.out.println(set.add(s3));//true
}
}
HashSet的特点可以知道HashSet中存放的元素不能重复,利用这个特性就可以做一些去重的业务 输入一个字符串,统计字符串中出现的字符及数量
public class HashSetDemo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入字符串:");
String s = sc.next();
char [] chars =s.toCharArray();
Set<Character> set = new HashSet<>();
Map<Character,Integer> map = new HashMap<>();
for(int i = 0;i<chars.length-1;i++){
if(set.add(chars[i])){
map.put(chars[i], 1);
}else{
Integer k = map.get(chars[i]);
map.put(chars[i],k+1);
}
}
map.forEach((key,value)->System.out.println(key+"==================="+value));
}
}
重写equals 和 HashCode 方法
public class Student {
public String name;
public int age;
public Student(String name,int age){
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
//Objects工具类下的equals和hash方法比较常用,后期使用较多
return age == student.age && Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
(3)LinkedHashSet
HashSet有一个子类LinkedHashSet,LinkedHashSet集合同HashSet一样,也是根据元素的hashCode值来确定元素的存储位置,并且通过链表维护元素的顺序,换句话说,遍历LinkedHashSet时,LinkedHashSet将会按照元素的添加顺序来访问集合里的元素。
如果在某些场景下要使用set容器保存元素,并且需要维护set中的存放元素的顺序,那么就可以使用LinkedHashSet
public class Test3 { public static void main(String[] args) { LinkedHashSet<String> set = new LinkedHashSet<>();
set.add("贞观之治");
set.add("开元盛世");
set.add("文景之治");
//添加进容器的元素和取出的元素顺序是一致的。
set.forEach(e-> System.out.println(e));
}
}
(4)TreeMap
TreeMap 就是一个红黑树数据结构,每个 key-value 对即作为红黑树的一个节点。TreeMap 存储 key-value 对(节点)时,需要根据 key 对节点进行排序。
public class TreeMapDemo {
public static void main(String[] args) {
TreeMap<Integer,String> map = new TreeMap<Integer,String>();
map.put(1,"苏轼");
map.put(2,"李白");
map.put(3,"杜甫");
map.put(4,"岑参");
//返回该 Map 中最小 key 所对应的 key-value 对,如果该Map为空,则返回 null。
System.out.println(map.firstEntry());
//返回该 Map 中的最小 key值,如果该 Map为空,则返回 null。> Map.Entry lastEntry()∶ 返回该 Map 中最大 key 所对应的 key-value 对,如果该 Map为空或不存在这样的 key-value 对,则都返回 null。
System.out.println(map.firstKey());
//返回该 Map 中的最大 key 值,如果该 Map 为空或不存在这样的 key,则都返回nulI。
System.out.println(map.lastKey());
//返回该 Map 中位于key 后一位的 key 值(即大于指定 key 的最小key 值)。如果该 Map 为空或不存在这样的 key-value 对,则都返回 nul 。
System.out.println(map.higherKey(2));
//返回该 Map 中位于key 后一位的 key-value 对(即大于指定key 的最小 key 所对应的 key-value 对)。如果该 Map 为空,则返回 null。
System.out.println(map.higherEntry(2));
//返回该Map 中位于key前一位的 key 值(即小于指定 key 的最大key 值)。如果该 Map 为空或不存在这样的 key,则都返回 null。
System.out.println(map.lowerKey(3));
//返回该 Map 中位于key 前一位的 key-value 对(即小于指定key 的最大 key 所对应的 key-value 对)。如果该 Map 为空或不存在这样的 key-value 对,则都返回 null。
System.out.println(map.lowerEntry(3));
}
}
(5)TreeSet
TreeSet 是 SortedSet 接口的实现类,TreeSet 可以确保集合元素处干排序状态。
/**
-
//凡是要在TreeSet中添加的元素必须要继承Comparable接口,并重写compareTo方法
-
//a.compareTo(b) >0 a>b
-
//a.compareTo(b) ==0 a=b
-
//a.compareTo(c) <0 a<b
-
//TreeSet中判断两个对象是否相等依赖于Comparable接口的compareTo方法,不依赖于equals方法。 */
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet<Student> treeSet = new TreeSet<>();
Student s1 = new Student("小明",18);
Student s2 = new Student("小红",18);
//添加成功
treeSet.add(s1);
//添加失败,因为通过compareTo方法判断出两个对象相等
treeSet.add(s2);
treeSet.forEach(student -> System.out.println(student));
}
}
常用API
public class TreeSetDemo1 {
public static void main(String[] args) {
TreeSet<Integer> treeSet = new TreeSet<Integer>();
treeSet.add(11);
treeSet.add(12);
treeSet.add(12);
treeSet.add(13);
treeSet.add(31);
System.out.println(treeSet.comparator());
//返回集合中的第一个元素。
System.out.println(treeSet.first());
//返回集合中的最后一个元素。
System.out.println(treeSet.last());
//返回集合中位于指定元素之前的元素
System.out.println(treeSet.lower(12));
//返回集合中位于指定元素之后的元素
System.out.println(treeSet.higher(12));
//返回此Set 的子集合,范围从fromElement(包含)到 toElement (不包含)。
System.out.println(treeSet.subSet(11,13));
//返回此 Set 的子集,由小于 toElement 的元素组成
System.out.println(treeSet.headSet(32));
//返回此 Set 的子集,由大于或等于 fromElement 的元素组成。
System.out.println(treeSet.tailSet(11));
}
}