集合大满贯 II
Set接口常用方法
add(E e)
确保此 collection 包含指定的元素(可选操作)。
addAll(Collection<? extends E> c)
将指定 collection 中的所有元素都添加到此 collection 中(可选操作)。
clear()
移除此 collection 中的所有元素(可选操作)。
contains(Object o)
如果此 collection 包含指定的元素,则返回true。
containsAll(Collection<?> c)
如果此 collection 包含指定 collection 中的所有元素,则返回 true。
equals(Object o)
比较此 collection 与指定对象是否相等。
isEmpty()
如果此 collection 不包含元素,则返回true。
iterator()
返回在此 collection 的元素上进行迭代的迭代器。
remove(Object o)
从此 collection 中移除指定元素的单个实例,如果存在的话(可选操作)。
removeAll(Collection<?> c)
移除此 collection 中那些也包含在指定 collection 中的所有元素(可选操作)。
retainAll(Collection<?> c)
仅保留此 collection 中那些也包含在指定 collection 的元素(可选操作)。
size()
返回此 collection 中的元素数。
toArray()
返回包含此 collection 中所有元素的数组。
set存储特点
相对无序存储,不可以存储相同的元素(排重),不能通过下标访问
set方法 代码上机
package com.qf.day16;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/**
* Set接口
* 特点:无序,不可重复
* @author wgy
*
*/
public class Demo1 {
public static void main(String[] args) {
//创建对象
Set<String> set=new HashSet<String>();
//1添加
set.add("菊花");
set.add("枸杞");
set.add("红枣");
set.add("人参");
set.add("灵芝");
set.add("枸杞");
System.out.println("元素个数:"+set.size());
System.out.println(set);
//2删除
//2.1删除一个
// set.remove("灵芝");
// System.out.println("删除之后:"+set);
// //2.2清空
// set.clear();
//3遍历
//3.1foreach
System.out.println("--------增强for----------");
for (String string : set) {
System.out.println(string);
}
//3.2使用迭代器
System.out.println("---------迭代器-------");
Iterator<String> it=set.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
//4判断
System.out.println(set.contains("菊花"));
}
}
Set常用实现类
HashSet
此类实现Set接口,存储结构:哈希表(数组+链表)。它不保证set的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用null元素。
哈希表:数组加链表,既有数组的优点也有链表的优点。
重写hashCode()
hashCode()是Object中的方法,每个对象的hashCode值是唯一的,所以可以理解成hashCode值表示这个对象在内存中的位置
字符串String的hashCode(),是根据内容计算的。
public int hashCode()
{
//覆盖hashCode的时候,最好根据他的成员属性来返回值
return name.hashCode() + age*3 ;
}
重写equals()
equals()方法是Object类中的方法,表示比较两个对象是否相等,若不重写相当于比较对象的地址
public boolean equals(Object obj)
{
//类型不相同,肯定不是同一个事物
if(!(obj instanceof Student1))
return false;
Student1 p = (Student1)obj;
//名字和年龄都相同的话,那肯定是同一个人
return this.name.equals(p.name) && this.age == p.age;
}
HashSet集合实现排重
1.先根据hashCode计算位置
2.再判断equals 如果相同,重复元素
如果不同,不是重复元素 存入
if(hashCode相同并且equals相同 只能添加一个元素)
HashSet的重复依据: hashCode和equals
需要同时重写hashCode和equals方法,实现排重。
案例:设计一个Student类,同时重写hashCode和equals方法,检查是否实现排重
代码实现
public class Student {
private String name;
public Student(String name) {
super();
this.name = name;
}
public Student() {
super();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student [name=" + name + "]";
}
@Override
//重写equals
public boolean equals(Object obj) {
//先判断传入的参数对象是否是Student对象,
//若不是直接返回false
if(obj instanceof Student) {
//若是,强转成Student对象,并比较属性的值
Student s = (Student) obj;
if(this.name.equals(s.name)) {
//若属性的值相同,则返回true
return true;
}
}
return false;
}
@Override
public int hashCode(){
/*hashCode方法返回值是int类型,
所以重写时需要找到int类型的数据返回,
还要保证此方法的返回值与对象的所有属性都相关,
所以返回姓名属性的字符串的长度*/
return this.name.length();
}
}
LinkedHashSet
LinkedHashSet类是具有可预知迭代顺序(相对有序)的Set接口的哈希表和链接列表实现。是HashSet的子类。
存储特点:
有序存储,不可以存储相同元素(排重),通过链表实现的集合(注定相对有序)
LinkedHashSet集合的元素排重与HashSet集合排重方法一致。
如果我们需要迭代的顺序为插入顺序或者访问顺序,那么 LinkedHashSet 是需要你首先考虑的。
TreeSet集合
TreeSet集合是可以给元素进行重新排序的一个Set接口的实现。使用元素的自然顺序对元素进行排序,或者根据创建 set 时提供的Comparator进行排序,具体取决于使用的构造方法。
存储特点:
无序存储,排重,通过二叉树实现的集合,可以给元素进行重新排序
TreeSet集合的元素排序[自然排序、定制排序]
自然排序
元素所属的类需要实现java.lang.Comparable接口,并重写compareTo方法。
compareTo方法除了可以进行排序外,还有排重的功能,但是必须在compareTo方法中对类中所有的属性值都进行判断,否则不比较那个属性,排重就会忽略哪个属性
案例:设计一个Person类,实现将Person对象添加到TreeSet集合中时,对所有的元素进行排序
public class Person implements Comparable<Person> {
private String name;
private int age;
public Person() {
super();
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + 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
//重写compareTo方法,按照年龄升序,若年龄相同按照姓名降序排序
public int compareTo(Person o) {
//Person中有两个属性,此方法中必须对name和age两个属性都进行比较,否则将无法正确排重
if(this.age != o.age) {
return this.age - o.age;//升序
}else {
return o.name.compareTo(this.name);
}
}
}
定制排序
元素需要通过java.util.Comparator接口(比较器)中的compare方法进行比较大小,并排序。
compare方法除了可以进行排序外,还有排重的功能,但是必须在compare方法中对类中所有的属性值都进行判断,否则不比较那个属性,排重就会忽略哪个属性
TreeSet集合中的无参数构造方法默认使用自然排序的方式对元素进行排序,使用TreeSet集合的定制排序时,创建集合对象不可以直接使用无参数构造方法,需要使用传入一个Comparator比较器的构造方法创建集合对象。
public class Animal {
private String name;
private int age;
@Override
public String toString() {
return "Animal [name=" + name + ", age=" + 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;
}
public Animal(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Animal() {
super();
}
}
public class AnimalDemo{
public static void main(String[]args){
//创建一个TreeSet集合,使用Comparator接口的匿名内部类的匿名对象作为比较器
TreeSet<Animal> treeSet = new TreeSet<>(new Comparator() {
@Override
public int compare(Animal o1, Animal o2) {
if(o1.age!=o2.age) {
return o2.age - o1.age;
}else {
return o1.name.compareTo(o2.name);
}
}
});
//添加元素
treeSet.add(new Animal("大黄", 1));
treeSet.add(new Animal("旺财", 2));
//遍历集合
Iterator<Animal> it = treeSet.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}
//利用匿名内部类的简写
public static void main(String[] args) {
// TODO Auto-generated method stub
TreeSet<Animal> ts=new TreeSet<Animal>((o1, o2)->{
// TODO Auto-generated method stub
if(o1.getAge()!=o2.getAge()) {
return o2.getAge()-o1.getAge();
}else {
return o1.getName().compareTo(o2.getName());
}
});
//添加元素
ts.add(new Animal("大黄",1));
ts.add(new Animal("旺财",2));
for(Animal a:ts) {
System.out.println(a);
}
}
SortedSet接口
TreeSet除了实现了Set接口外,还实现了SortedSet接口
SortedSet接口中常用的方法:
first()
返回此 set 中当前第一个(最低)元素。
last()
返回此 set 中当前最后一个(最高)元素。
headSet(E toElement)
返回此 set 的部分视图,其元素严格小于toElement。
tailSet(E fromElement)
返回此 set 的部分视图,其元素大于等于fromElement。
subSet(E fromElement, E toElement)
返回此 set 的部分视图,其元素从 fromElement(包括)到 toElement(不包括)。
Last Demo
package com.qf.day16_2;
import java.util.Comparator;
import java.util.TreeSet;
/**
* 上机练习:按照字母的长度来排列字符串 ,如果长度一样 按照编码顺序排列
*"dog" "hello" "beijing" "tianjin" "shanghai" "guangzhou"
*/
public class Demo1 {
public static void main(String[] args) {
TreeSet<String> treeSet=new TreeSet<String>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
int n=o1.length()-o2.length();//升序
int m=o1.compareTo(o2);//升序
return n!=0?n:m;
}
});
treeSet.add("beijing");
treeSet.add("guangzhou");
treeSet.add("shanghai");
treeSet.add("tianjin");
treeSet.add("hello");
treeSet.add("dog");
treeSet.add("no");
System.out.println(treeSet);
}
}
下一篇讲解map接口。1
文章太长了 https://blog.csdn.net/l1996729/article/details/106639660 ↩︎