一.Set集合:无序(存储和取出不一致),能够保证元素唯一
(1)
HashSet:底层数据结构是一个哈希表(桶结构)线程不安全的类---->不同步---->执行效率高
String类型:String类型本身已经重写了hashCode()和equals
如果现在存储是自定义对象,如何保证元素唯一?
首先要比较元素的哈希码值相同----->hash()就相同,还要比较成员信息是否相同,
对应存储自定的类必须要重写Object的equals方法和HashCode()
应用场景:
在一些需求中,如果没有明确要求元素重复,那就可以使用hashSet,保证元素唯一
类型:String,Integer,Long,....常用类都已经重写了hashCode和equals方法
(2)
TreeSet :无序性,元素唯一
底层依赖于TreeMap集合, 红黑树结构(也称为 "自平衡的二叉树结构"),可以实现Map的自然排序以及比较器排序取决于使用的构造方法
TreeSet能够实现两种排序:
自然排序/比较器排序,取决于构造方法
自然排序:TreeSet<E>(),E类型必须实现Comparable接口,实现自然排序(实现的compareTo(T t))
比较器排序:
public TreeSet(Comparator<? super E> comparator)
Comparator是一个接口类型
1)自定义一个类实现Comparator接口,重写compare方法
2)使用接口的匿名内部类(推荐)
使用TreeSet存储Student类型,遍历元素(使用比较器排序完成)
使用TreeSet存储Student类型,遍历元素,排序条件:
主要条件:按照学生的年龄从小到大排序次要条件:年龄相同,还要比较姓名的内容是否相同
实现自然排序
//实现自然排序 实现一个接口Comparable
public class Student implements Comparable<Student>{
private String name ;//姓名
private int age ;//年龄
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.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
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
//排序的代码
@Override
public int compareTo(Student s) { //后面需要和学生对象对比
//主要条件:就是按照年龄从小到大排序
//定义一个变量
//年龄int类型
int num = this.age - s.age ;
int num = s.age - this.age ;//从大到小
//次要条件:年龄相同,还要比较姓名的内容是否相同
int num2 = (num==0)?(this.name.compareTo(s.name)):num; //字符串的字典顺序比较
//gaoyuanyuan
//jacky
return num2;
}
}
-----------------------------------------------------------------------------------------
import java.util.TreeSet;
public class TreeSetDemo2 {
public static void main(String[] args) {
//创建TreeSet,无参构造方法
TreeSet<Student> ts = new TreeSet<>() ;
//创建几个学生对象
Student s1 = new Student("gaoyuanyuan",42) ;
Student s2 = new Student("gaoyuanyuan",42) ;
Student s3 = new Student("jacky",40) ;
Student s4 = new Student("rose",40) ;
Student s5 = new Student("tomcat",35) ;
Student s6 = new Student("jeffry",35) ;
Student s7 = new Student("liushishi",54) ;
Student s8 = new Student("liudehua",60) ;
//添加
ts.add(s1) ;
ts.add(s2) ;
ts.add(s3) ;
ts.add(s4) ;
ts.add(s5) ;
ts.add(s6) ;
ts.add(s7) ;
ts.add(s8) ;
//遍历
for(Student s : ts){
System.out.println(s.getName()+"---"+s.getAge());
}
}
}
实现比较器排序
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.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
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class TreeSetDemo {
public static void main(String[] args) {
//接口的匿名内部类
TreeSet<Student> ts = new TreeSet<>(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
//主要条件:按照学生的年龄从小到大排序
//s1---->就是刚才自然排序里面this
//s2---->就是刚才自然排序里面s
int num = s1.getAge() - s2.getAge() ;
//如果年龄相同,比较姓名是否一样
int num2 = (num==0)? (s1.getName().compareTo(s2.getName())): num ;
return num2;
}
}) ;
//创建几个学生对象
Student s1 = new Student("gaoyuanyuan",42) ;
Student s2 = new Student("gaoyuanyuan",42) ;
Student s3 = new Student("jacky",40) ;
Student s4 = new Student("rose",40) ;
Student s5 = new Student("tomcat",35) ;
Student s6 = new Student("jeffry",35) ;
Student s7 = new Student("liushishi",54) ;
Student s8 = new Student("liudehua",60) ;
ts.add(s1) ;
ts.add(s2) ;
ts.add(s3) ;
ts.add(s4) ;
ts.add(s5) ;
ts.add(s6) ;
ts.add(s7) ;
ts.add(s8) ;
for (Student s:ts) {
System.out.println(s.getName()+"---"+s.getAge());
}
}
}
二.Map集合:键映射到值的对象,可以多个值,但键必须唯一
Map(key,value)
key(键)
value(值)
Map集合的功能:
V put(K key,V value):添加键值对元素注意事项:
如果key是第一次添加,那么返回的结果为null
如果key是否重复添加,第二次添加,返回的上一次添加的键对应的值
V remove(Object key):删除指定的键,返回被删除键对应的值
void clear()
boolean containsKey(Object key) :是否包含指定的键 (使用居多)
boolean containsValue(Object value):是否包含指定的值
高级功能:
Map遍历功能方式1:
Set<K> keySet() :获取当前Map集合中的所有的键的集合 (将所有的丈夫集中起来,找对应的妻子)+V get(Object key):通过键获取值
方式2:
获取所有的结婚证 (键值对对象)
Set<Map.Entry<K,V>> entrySet()
通过键值对象 获取键 /获取值(通过结婚证找男方/女方)
K getKey()
V getValue()public class MapDemo2 { public static void main(String[] args) { //创建Map集合对象 Map<String,String> map = new HashMap<>() ; //添加元素 map.put("令狐冲","东方不败") ; map.put("杨过","小龙女") ; map.put("陈玄风","梅超风") ; map.put("郭靖","黄蓉") ; // Set<K> keySet() :获取当前Map集合中的所有的键的集合 Set<String> keySet = map.keySet(); //推荐第一种方式 //增强for遍历 for(String key: keySet){ //获取所有的键的元素 // V get(Object key):通过键获取值 String value = map.get(key); System.out.println(key+"="+value); } System.out.println("--------------------------------------"); //方式2: //Set<Map.Entry<K,V>> entrySet() Set<Map.Entry<String, String>> entry = map.entrySet(); //增强for:遍历键值对对象获取到 for(Map.Entry<String, String> en: entry){ //获取键和值 //K getKey() // V getValue() String key = en.getKey(); String value = en.getValue(); System.out.println(key+"="+value); } } }
Map和Collection集合的区别:
Collection:只能存储一种类型 Collection<E>
Map集合:可以两种类型的,键的类型,值的类型 Map<K,V>
遍历方式不同
Collection:就通过5种方式(List)
object[] toArray()
size() + get(int index)
Iterator iterator()
ListIterator listIterator()
for-each语句
Map:两种方式:
方式1:获取所有的K的集合(键的集合)
通过键获取值
方式2: 获取所有的键值对对象Map.Entry<K,V> ("结婚证")
通过键值对对象获取所有的键("结婚证男方")
通过键值对对象获取所有的值("结婚证女方")