2021.2.1java集合框架2
JAVA集合框架2
四.泛型和工具类
1.泛型的基本概念
- 泛型其本质是参数化类型,把类型作为参数传递
- 常见的形式有泛型类、泛型接口、泛型方法
- 语法:<T,....>T称为占位符,表示一种引用类型,如果编写多个需要用逗号隔开
- 好处1:提高代码的重用性(能执行很多类型的数据)
- 好处2:防止类型转换异常,提高代码的安全性
2.泛型的基本运用
- 泛型类
//泛型类
public class G<T> {
//使用泛型T
//不能利用利用 T 进行实例化,不能new
//T这个数据类型并不知道,他的构造方法不一定有无参构造
//1.创建变量
public T t;
//2.泛型作为方法的参数
public void setT(T t) { this.t=t; }
//3. 泛型作为方法的返回值
public T getT(){
return t;
}
}
public class Test {
//1.泛型只能使用引用类型
//2.不同的泛型类型对象之间不能互相赋值
public static void main(String[] args) {
G<String> g1 = new G<String>();
g1.t = "hello";
System.out.println(g1.t);
g1.setT("girl!");
System.out.println(g1.getT());
G<Integer> g2 = new G<Integer>();
g2.t = 110;
System.out.println(g2.t);
g2.setT(120);
System.out.println(g2.getT());
G<String> g3 = g1;
//G<String> g4=g2;报错
}
}
/*结果:
hello
girl!
110
120
*/
- 泛型接口
//泛型接口
//语法:接口名<T,E,...>
//T是类型占位符,表示一种引用类型,如果编写多个可以使用逗号隔开
public interface G2<T> {
//接口中定义的所有变量都是常量,隐藏public static final
//但是注意!!!不能定义!!!泛型常量!!!定义常量时必须先初始化,而T的类型并不知道,不能new,无法初始化------->T t;编译出错
String name="lyj";
//接口中定义的所有方法都是 public abstract
T add (T t);
//参数是T类型,返回值也是T
}
//泛型接口G2的实现类G2Impl
//需要写好泛型的类型
public class G2Impl implements G2<String>{
@Override
public String add(String s) {
return s;
}
}
//泛型接口G2的实现类G2Impl
//可以不写好泛型的类型
public class G2Impl2<T> implements G2<T>{
@Override
public T add(T t) {
return t;
}
}
public static void main(String[] args) {
G2Impl gg=new G2Impl();
System.out.println(gg.add("hhhhhh"));
G2Impl2<Integer> ggg=new G2Impl2<Integer>();
System.out.println(ggg.add(555));
}
/*结果:
hhhhhh
555
*/
- 泛型方法
//泛型方法
//语法:<T> 返回值类型
//使用泛型方法,在执行程序时,需要编辑的类型可以自己把握
public class G3 {
public <T> void show(T t){
System.out.println(t);
}
public <T> T show2(T t){
System.out.println(t);
return t;
}
}
public static void main(String[] args) {
G3 g31=new G3();
g31.show("wawawaawa");//输入什么数据类型的数据,就执行什么类型的数据
g31.show(1000);
g31.show2("heiheihei");
g31.show2(1000.05);
}
/*结果:
wawawaawa
1000
heiheihei
1000.05
*/
使用泛型方法就像使用普通方法一样
3.泛型集合
- 参数化类型、类型安全的集合,强调集合元素的类型
- 访问时,不必要类型转换(拆箱)
- 不同泛型之间引用不能相互赋值,泛型不存在多态
//泛型集合
public class H {
public static void main(String[] args) {
//利用之前List接口下的ArrayList类创建一个泛型集合
ArrayList<String> arrayList1 = new ArrayList<String>();
arrayList1.add("lyj");
// arrayList1.add(111);报错
arrayList1.add("zyx");//应用了泛型集合,类型是什么,只能添加什么类型的数据
//遍历集合,使用增强for,不会出现类型转换的问题,此处的数据都是一种类型
for (String s : arrayList1) {
System.out.println(s.toString());
}
//泛型集合的类型也可以是自己定义的类
ArrayList<Student> arrayList2 = new ArrayList<Student>();
Student s1 = new Student("aaa", 5);
Student s2 = new Student("bbb", 10);
Student s3 = new Student("ccc", 15);
Student s4 = new Student("ddd", 20);
arrayList2.add(s1);
arrayList2.add(s2);
arrayList2.add(s3);
arrayList2.add(s4);
//arrayList2.add("xxx");报错
//遍历集合,利用迭代器,不会出现类型转换的问题,此处的数据都是一种类型
Iterator<Student> it = arrayList2.iterator();
while (it.hasNext()) {
Student student = it.next();
System.out.println(student.toString());
}
}
}
/*结果:
lyj
zyx
name:aaa age:5
name:bbb age:10
name:ccc age:15
name:ddd age:20
*/
五.Set接口与实现类
1.Set子接口
- 特点:无序、无下标、元素不可重复
- 方法:全部继承自Collection中的方法
2.Set接口的使用
//Set接口的使用
//特点:1.无序,没有下标 2.不能重复
public class I {
public static void main(String[] args) {
//创建集合,接口不能实例化,但是能创建对象;需要利用实现类
Set<String> set1 = new HashSet<String>();
//1.添加元素
set1.add("aaa");
set1.add("bbb");
set1.add("ccc");
set1.add("bbb");//不能重复添加
System.out.println("元素个数:" + set1.size());//集合长度(个数)
System.out.println(set1.toString());//无序的
System.out.println("====================================");
//2.删除元素
set1.remove("ccc");//删除不能靠角标
System.out.println("元素个数:" + set1.size());//集合长度(个数)
System.out.println(set1.toString());//无序的
System.out.println("====================================");
//set1.clear()全部清除
// 3.遍历数据(只能使用增强for和迭代器)
//1)增强for
System.out.println("使用增强for来遍历");
for (String s : set1) {
System.out.println(s.toString());
}
//2)使用迭代器Iterator遍历,迭代器是个接口,方法如下
//hasNext();判断有没有下一个元素
//next();获取下一个元素
//remove();删除当前元素
System.out.println("使用迭代器Iterator来遍历");
Iterator<String> it = set1.iterator();
while (it.hasNext()) {
String s = it.next();
System.out.println(s.toString());
}
System.out.println("====================================");
//4.判断
System.out.println(set1.contains("000"));
System.out.println(set1.isEmpty());
}
}
/*结果:
元素个数:3
[aaa, ccc, bbb]
====================================
元素个数:2
[aaa, bbb]
====================================
使用增强for来遍历
aaa
bbb
使用迭代器Iterator来遍历
aaa
bbb
====================================
false
false
*/
3.Set接口的实现类
-
HashSet类
- 基于HashCode计算元素存放的位置
- 当存入的元素的哈希码值相同时,会调用equals进行确认,如结果为true,则拒绝后者进入
- 存储结构:哈希表(数组+链表)
public static void main(String[] args) { //新建集合 HashSet<String> hashSet1=new HashSet<>();//后面<>的类型可以写也可以不写 //1.添加元素 hashSet1.add("aaa"); hashSet1.add("bbb"); hashSet1.add("ccc"); hashSet1.add("ddd"); hashSet1.add("bbb");//不能重复添加 System.out.println("元素个数:" + hashSet1.size());//集合长度(个数) System.out.println(hashSet1.toString());//无序的 System.out.println("===================================="); //2.删除元素 hashSet1.remove("ccc");//删除不能靠角标 System.out.println("元素个数:" + hashSet1.size());//集合长度(个数) System.out.println(hashSet1.toString());//无序的 System.out.println("===================================="); //set1.clear()全部清除 // 3.遍历数据(只能使用增强for和迭代器) //1)增强for System.out.println("使用增强for来遍历"); for (String s : hashSet1) { System.out.println(s.toString()); } //2)使用迭代器Iterator遍历,迭代器是个接口,方法如下 //hasNext();判断有没有下一个元素 //next();获取下一个元素 //remove();删除当前元素 System.out.println("使用迭代器Iterator来遍历"); Iterator<String> it = hashSet1.iterator(); while (it.hasNext()) { String s = it.next(); System.out.println(s.toString()); } System.out.println("===================================="); //4.判断 System.out.println(hashSet1.contains("000")); System.out.println(hashSet1.isEmpty()); } /*结果 元素个数:4 [aaa, ccc, bbb, ddd] ==================================== 元素个数:3 [aaa, bbb, ddd] ==================================== 使用增强for来遍历 aaa bbb ddd 使用迭代器Iterator来遍历 aaa bbb ddd ==================================== false false */
//HashSet存储过程 //1.根据hashCode计算保存的位置,如果位置为空,则直接保存,如果不为空,则执行第2步 //2.再执行equals方法,如果equals方法为true,则认为重复,不保存,false则形成链表 public static void main(String[] args) { //创建集合 HashSet<Student> students=new HashSet<>(); //1.添加元素 //在Student类中进行有参构造 Student s1=new Student("aaa",5); Student s2=new Student("bbb",10); Student s3=new Student("ccc",15); Student s4=new Student("ddd",20); students.add(s1); students.add(s2); students.add(s3); students.add(s3);//重复,不会添加 students.add(s4); students.add(new Student("ddd",20));//未修改hasdCode、equals方法前是可以添加,修改完添加不了 System.out.println("元素个数:"+students.size());//集合长度(个数) System.out.println(students.toString());//此处的toString方法需要重写 System.out.println("==================================="); //2.删除元素 //删除元素需要用到hasCode()方法找到他的存储位置,再equals()方法进行比较 //不重写hasCode、equals()方法,没法删除下面(元素相同,对象名不同)的集合元素 students.remove(new Student("aaa",5)); System.out.println("元素个数:"+students.size());//集合长度(个数) System.out.println(students.toString()); System.out.println("===================================="); //3.遍历元素 //(1)使用增强for循环遍历 System.out.println("使用增强for来遍历"); for(Student student:students){ System.out.println(student.toString()); } //(2)使用迭代器遍历 System.out.println("使用迭代器Iterator来遍历"); Iterator<Student> it=students.iterator(); while(it.hasNext()){ Student s=it.next(); System.out.println(s.toString()); } System.out.println("===================================="); //4.判断元素是否存在 //也需要用到hasCode()、equals()方法,此处方法已被重写 System.out.println(students.contains(s2)); System.out.println(students.contains(new Student("ccc",15))); System.out.println(students.isEmpty()); System.out.println("===================================="); } /*结果: 元素个数:4 [name:ccc age:15, name:aaa age:5, name:ddd age:20, name:bbb age:10] =================================== 元素个数:3 [name:ccc age:15, name:ddd age:20, name:bbb age:10] ==================================== 使用增强for来遍历 name:ccc age:15 name:ddd age:20 name:bbb age:10 使用迭代器Iterator来遍历 name:ccc age:15 name:ddd age:20 name:bbb age:10 ==================================== true true false ==================================== */
public class Student { //封装属性 private int age; private String name; //构造器,new之后,程序先运行构造器再生成对象 public Student(){ } public Student(String name,int age) { super(); this.age=age; this.name=name; } //可以通过快捷键Alt+Insert:重写常用的方法 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 int hashCode() { int n1=this.name.hashCode(); int n2=this.age; return n1+n2; } @Override public boolean equals(Object obj) { // 1.判断这两个对象是不是同一个引用 if(this==obj){ return true; } // 2.判断obj是否为null if(obj==null){ return false; } // 3.判断两个对象是否为同一类型 if(obj instanceof Student)//左边为对象,右边为类; //obj所指的实际类型是Student的子类型,则true { // 4.强制转换 Student student=(Student) obj; // 5. if(this.name==student.name&&this.age==student.age) return true; } return false; } @Override public String toString() { return "name:"+name+" "+"age:"+age; } }
-
TreeSet类
- 基于排列顺序实现元素不重复
- 实现了SortedSet接口,对集合元素自动排序
主要看CompareTo()是如何重写的
- 元素对象的类型必须实现Comparable接口,指定排序规则
- 通过CompareTo方法确定是否为重复元素
- 存储结构:红黑树
//TreeSet的基本使用
public static void main(String[] args) {
//新建集合
TreeSet<String> treeSet=new TreeSet<>();//后面<>的类型可以写也可以不写
//1.添加元素
treeSet.add("aaa");
treeSet.add("bbb");
treeSet.add("ccc");
treeSet.add("ddd");
treeSet.add("abc");
treeSet.add("bbb");//不能重复添加
System.out.println("元素个数:" + treeSet.size());//集合长度(个数)
System.out.println(treeSet.toString());//自动排序,有一定的规律但是没有下标
System.out.println("====================================");
//2.删除元素
treeSet.remove("ccc");//删除不能靠角标
System.out.println("元素个数:" + treeSet.size());//集合长度(个数)
System.out.println(treeSet.toString());//自动排序,有一定的规律但是没有下标
System.out.println("====================================");
//set1.clear()全部清除
// 3.遍历数据(只能使用增强for和迭代器)
//1)增强for
System.out.println("使用增强for来遍历");
for (String s : treeSet) {
System.out.println(s.toString());
}
//2)使用迭代器Iterator遍历,迭代器是个接口,方法如下
//hasNext();判断有没有下一个元素
//next();获取下一个元素
//remove();删除当前元素
System.out.println("使用迭代器Iterator来遍历");
Iterator<String> it = treeSet.iterator();
while (it.hasNext()) {
String s = it.next();
System.out.println(s.toString());
}
System.out.println("====================================");
//4.判断
System.out.println(treeSet.contains("000"));
System.out.println(treeSet.isEmpty());
}
/*结果:
元素个数:5
[aaa, abc, bbb, ccc, ddd]
====================================
元素个数:4
[aaa, abc, bbb, ddd]
====================================
使用增强for来遍历
aaa
abc
bbb
ddd
使用迭代器Iterator来遍历
aaa
abc
bbb
ddd
====================================
false
false
*/
注意:因为TreeSet集合的存储结构是红黑树,存放数据需要比较然后排序,然后才放入集合中,所以需要告诉其怎么进行排序。数据能放入集合、要实现必须要用到Comparable接口
所以:实现类---------->>>>public class Student implements Comparable
若compareTo()返回值为0--->则为重复,不能放入集合
//使用TreeSet集合保存数据
//存储结构:红黑树
//要求:元素必须要实现Comparable接口,重写的方法CompareTo()返回值为0,则为重复
public static void main(String[] args) {
//创建集合
TreeSet<Student> students=new TreeSet<>();//引用自己创建的类,需要让他继承Comparable接口
//继承了接口,需要重写接口的方法CompareTo(),制定比较规则
//1.添加元素
//在Student类中进行有参构造
Student s1=new Student("aaa",5);
Student s2=new Student("bbb",10);
Student s3=new Student("ccc",15);
Student s4=new Student("ccc",20);
students.add(s1);
students.add(s2);
students.add(s3);
students.add(s3);//重复,不会添加
students.add(s4);
students.add(new Student("ccc",20));//未重写CompareTo()方法前是可以添加,修改完添加不了
System.out.println("元素个数:"+students.size());//集合长度(个数)
System.out.println(students.toString());//此处的toString方法需要重写
//TreeSet的排序方法是有一定顺序可言的,主要看CompareTo()是如何重写的
System.out.println("===================================");
//2.删除元素
//删除元素需要用到CompareTo()方法
students.remove(new Student("aaa",5));
System.out.println("元素个数:"+students.size());//集合长度(个数)
System.out.println(students.toString());
System.out.println("====================================");
//3.遍历元素
//(1)使用增强for循环遍历
System.out.println("使用增强for来遍历");
for(Student student:students){
System.out.println(student.toString());
}
//(2)使用迭代器遍历
System.out.println("使用迭代器Iterator来遍历");
Iterator<Student> it=students.iterator();
while(it.hasNext()){
Student s=it.next();
System.out.println(s.toString());
}
System.out.println("====================================");
//4.判断元素是否存在
//也需要用到CompareTo()方法,此处方法已被重写
System.out.println(students.contains(s2));
System.out.println(students.contains(new Student("ccc",15)));
System.out.println(students.isEmpty());
System.out.println("====================================");
}
/*
结果:
元素个数:4
[name:aaa age:5, name:bbb age:10, name:ccc age:15, name:ccc age:20]
===================================
元素个数:3
[name:bbb age:10, name:ccc age:15, name:ccc age:20]
====================================
使用增强for来遍历
name:bbb age:10
name:ccc age:15
name:ccc age:20
使用迭代器Iterator来遍历
name:bbb age:10
name:ccc age:15
name:ccc age:20
====================================
true
true
false
====================================
*/
public class Student implements Comparable<Student> {
//封装属性
private int age;
private String name;
//构造器,new之后,程序先运行构造器再生成对象
public Student(){
}
public Student(String name,int age) {
super();
this.age=age;
this.name=name;
}
//可以通过快捷键Alt+Insert:重写常用的方法
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 int hashCode() {
int n1=this.name.hashCode();
int n2=this.age;
return n1+n2;
}
@Override
public boolean equals(Object obj) {
// 1.判断这两个对象是不是同一个引用
if(this==obj){
return true;
}
// 2.判断obj是否为null
if(obj==null){
return false;
}
// 3.判断两个对象是否为同一类型
if(obj instanceof Student)//左边为对象,右边为类;
//obj所指的实际类型是Student的子类型,则true
{
// 4.强制转换
Student student=(Student) obj;
// 5.
if(this.name==student.name&&this.age==student.age)
return true;
}
return false;
}
@Override
public String toString() {
return "name:"+name+" "+"age:"+age;
}
@Override
public int compareTo(Student o) {
//先比姓名
int n1=this.name.compareTo(o.name);
int n2=this.age-o.age;
return n1==0?n2:n1;//如果n1比较的结果为0(名字相同),返回n2值,否则返回n1值
}
}
- TreeSet集合补充
使用Comparator:实现定制比较器,来创建集合,并指定比较规则
//TreeSet集合的使用不使用Comparable接口
//使用Comparator:实现定制比较器(这是一个接口)
public static void main(String[] args) {
//创建集合,并制定比较规则------利用到匿名内部类
TreeSet<Student> students=new TreeSet<>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
int n1=o1.getAge()-o2.getAge();
int n2=o1.getName().compareTo(o2.getName());
return n1==0?n2:n1;//如果n1比较的结果为0(年龄相同),返回n2值(名字的值相减),否则返回n1值
}
});
Student s1=new Student("aaa",5);
Student s2=new Student("bbb",10);
Student s3=new Student("ccc",15);
Student s4=new Student("ccc",20);
students.add(s1);
students.add(s2);
students.add(s3);
students.add(s3);//重复,不会添加
students.add(s4);
students.add(new Student("ccc",20));
//利用匿名内部类重写Comparator接口的compare()方法前是可以添加,修改完添加不了
System.out.println("元素个数:"+students.size());//集合长度(个数)
System.out.println(students.toString());//此处的toString方法需要重写
}
/*结果:
元素个数:4
[name:aaa age:5, name:bbb age:10, name:ccc age:15, name:ccc age:20]
*/
- TreeSet集合的实例
- 要求:使用TreeSet集合实现字符串按照长度进行排序
- helloworld zhangsan lisi wangwu beijing guangzhou
//TreeSet集合的实例
//- 要求:使用TreeSet集合实现字符串按照长度进行排序
//- helloworld zhangsan lisi beijing guangzhou
public static void main(String[] args) {
//利用Comparator接口实现定制比较
//1.创建集合,比制定比较规则
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;
}
});
//2.添加数据
treeSet.add("helloworld");
treeSet.add("zhangsan");
treeSet.add("lisi");
treeSet.add("beijing");
treeSet.add("guangzhou");
System.out.println(treeSet.toString());
}
/*结果:
[lisi, beijing, zhangsan, guangzhou, helloworld]
*/
六.Map接口与实现类
1.Map父接口
-
特点:存储一对数据(Key--Value)--->键值对
无序无下标,键不能重复,值可以重复
//Map父接口
//方法的使用
public static void main(String[] args) {
//创建Map集合(Map为接口,不能实例化)但是能创建对象;需要利用实现类
Map<String,String> map=new HashMap<>();
//1.添加元素----->put()方法
map.put("b","5");
map.put("a","5");
map.put("c","5");
map.put("xyz","10");
map.put("a","5");//不能添加相同的key和value
map.put("a","10");//当key相同,value不同时,取代上一个key的value值
//key不允许重复
System.out.println("元素个数:"+map.size());
System.out.println(map.toString());//无序的
System.out.println("=============================");
//2.删除元素----->remove()方法
//map.remove("xyz");
map.remove("xyz","10");//两者都是将一对数据删除
System.out.println("删除之后元素个数:"+map.size());
System.out.println(map.toString());
System.out.println("=============================");
//3.遍历元素
//使用keySet()方法
System.out.println("使用keySet()方法");
Set<String> key= map.keySet();//keySet方法之后得到的是Set集合,得到key部分的集合数据
for(String s:key){
System.out.println(s+" "+map.get(s));//get()方法是得到该key的value值
}
//使用entrySet()方法
System.out.println("使用entrySet()方法");
Set<Map.Entry<String,String>> key_value =map.entrySet();
//entrySet方法之后得到的是Set集合,得到key+value的一对集合数据,所以泛型的类型也是要一对
for(Map.Entry<String,String> ss:key_value){
System.out.println(ss.getKey()+" "+ss.getValue());
//getkey()方法是得到key,getvalue()方法是得到value
}
System.out.println("=============================");
//4.查找元素
System.out.println(map.containsKey("d"));// 查看是否有该key
System.out.println(map.containsValue("5"));//查看是否有该value值
}
/*结果:
元素个数:4
{a=10, b=5, c=5, xyz=10}
=============================
删除之后元素个数:3
{a=10, b=5, c=5}
=============================
使用keySet()方法
a 10
b 5
c 5
使用entrySet()方法
a 10
b 5
c 5
=============================
false
true
*/
2.Map集合的实现类
1)HashMap集合
-
!!HashSet其实就是用了HashMap的key!!
-
存储结构:哈希表(数组+链表)
-
key值不能重复,value值可以重复
-
可以用hashcode()和equals()方法的重写来确定key值(键)是否重复,重复则不加入集合
public static void main(String Args[]){
//1.创建集合
HashMap<Student,String> hm1=new HashMap<>();
//2.添加数据
Student s1=new Student("aaa",5);
Student s2=new Student("bbb",10);
Student s3=new Student("ccc",15);
Student s4=new Student("ddd",20);
hm1.put(s1,"AAA");
hm1.put(s2,"BBB");
hm1.put(s3,"CCC");
hm1.put(s4,"EEE");
hm1.put(s4,"DDD");//Key值唯一,value值改变,取代上一个value值
hm1.put(new Student("ddd",20),"DDD");//未修改hasdCode、equals方法前是可以添加,修改完添加不了
System.out.println("元素个数:"+hm1.size());//集合长度(个数)
System.out.println(hm1.toString());//此处的toString方法需要重写
System.out.println("===================================");
//3.删除数据
hm1.remove(s4);
//或者 hm1.remove(s4,"DDD");
System.out.println("元素个数:"+hm1.size());//集合长度(个数)
System.out.println(hm1.toString());//此处的toString方法需要重写
System.out.println("===================================");
//4.遍历数据
//使用keySet()方法
System.out.println("使用keySet()方法");
// Set<Student> key = hm1.keySet();
// keySet方法之后得到的是Set集合,得到key部分的集合数据
for (Student s : hm1.keySet()) {
System.out.println(s + " " + hm1.get(s));//get()方法是得到该key的value值
}
//使用entrySet()方法
System.out.println("使用entrySet()方法");
//Set<Map.Entry<Student, String>> key_value = hm1.entrySet();
//entrySet方法之后得到的是Set集合,得到key+value的一对集合数据,所以泛型的类型也是要一对
for (Map.Entry<Student, String> ss : hm1.entrySet()) {
System.out.println(ss.getKey() + " " + ss.getValue());
//getkey()方法是得到key,getvalue()方法是得到value
}
System.out.println("=============================");
//4.查找元素
System.out.println(hm1.containsKey(s1));// 查看是否有该key
System.out.println(hm1.containsValue("DDD"));//查看是否有该value值
}
/*
结果:
元素个数:4
{name:ccc age:15=CCC, name:aaa age:5=AAA, name:ddd age:20=DDD, name:bbb age:10=BBB}
===================================
元素个数:3
{name:ccc age:15=CCC, name:aaa age:5=AAA, name:bbb age:10=BBB}
===================================
使用keySet()方法
name:ccc age:15 CCC
name:aaa age:5 AAA
name:bbb age:10 BBB
使用entrySet()方法
name:ccc age:15 CCC
name:aaa age:5 AAA
name:bbb age:10 BBB
=============================
true
false
*/
public class Student {
//封装属性
private int age;
private String name;
//构造器,new之后,程序先运行构造器再生成对象
public Student(){
}
public Student(String name,int age) {
super();
this.age=age;
this.name=name;
}
//可以通过快捷键Alt+Insert:重写常用的方法
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 int hashCode() {
int n1=this.name.hashCode();
int n2=this.age;
return n1+n2;
}
@Override
public boolean equals(Object obj) {
// 1.判断这两个对象是不是同一个引用
if(this==obj){ return true; }
// 2.判断obj是否为null
if(obj==null){ return false; }
// 3.判断两个对象是否为同一类型
if(obj instanceof Student)//左边为对象,右边为类;
//obj所指的实际类型是Student的子类型,则true
{// 4.强制转换
Student student=(Student) obj;
// 5.
if(this.name==student.name&&this.age==student.age)
return true; }
return false;
}
@Override
public String toString() {
return "name:"+name+" "+"age:"+age;
}
}
-
HashMap源码分析
-
- 刚创建HashMap之后没有添加元素 则table=null size=0;
- 添加一个元素之后,HashMap的初始容量table就变为16
- 当容量达到默认加载因子所要求的阈值(16*0.75)时,就扩容,每次为上一次的2倍
备注:
①1左移4位=2^4=16:1<<4
②默认加载因子0.75f的意思是:当map集合内部元素超过75%就要扩容
2)TreeMap
-
!!TreeSet其实就是用了TreeMap的key!!
-
实现了SortedMap接口(为Map的子接口)
-
可以对key自动排序 主要看CompareTo()是如何重写的
-
元素对象的类型必须实现Comparable接口,指定排序规则
-
通过CompareTo方法确定是否为重复元素
-
存储结构:红黑树
//存储结构:红黑树
//要求:元素必须要实现Comparable接口,重写的方法CompareTo()返回值为0,则为重复
public static void main(String[] args) {
TreeMap<Student,String> tm1=new TreeMap<>();//引用自己创建的类,需要让他继承Comparable接口
//继承了接口,需要重写接口的方法CompareTo(),制定比较规则
//2.添加数据
Student s1=new Student("aaa",5);
Student s2=new Student("bbb",10);
Student s3=new Student("ccc",15);
Student s4=new Student("ddd",20);
tm1.put(s1,"AAA");
tm1.put(s2,"BBB");
tm1.put(s3,"CCC");
tm1.put(s4,"EEE");
tm1.put(s4,"DDD");//Key值唯一,value值改变,取代上一个value值
tm1.put(new Student("ddd",20),"DDD");//未重写CompareTo()方法前是可以添加,修改完添加不了
System.out.println("元素个数:"+tm1.size());//集合长度(个数)
System.out.println(tm1.toString());//此处的toString方法需要重写
//TreeSet的排序方法是有一定顺序可言的,主要看CompareTo()是如何重写的
System.out.println("===================================");
//3.删除数据
//删除元素需要用到CompareTo()方法
tm1.remove(new Student("ddd",20));
//tm1.remove(s4);
//或者 hm1.remove(s4,"DDD");
System.out.println("元素个数:"+tm1.size());//集合长度(个数)
System.out.println(tm1.toString());//此处的toString方法需要重写
System.out.println("===================================");
//4.遍历数据
//使用keySet()方法
System.out.println("使用keySet()方法");
// Set<Student> key = hm1.keySet();
// keySet方法之后得到的是Set集合,得到key部分的集合数据
for (Student s : tm1.keySet()) {
System.out.println(s + " " + tm1.get(s));//get()方法是得到该key的value值
}
//使用entrySet()方法
System.out.println("使用entrySet()方法");
//Set<Map.Entry<Student, String>> key_value = hm1.entrySet();
//entrySet方法之后得到的是Set集合,得到key+value的一对集合数据,所以泛型的类型也是要一对
for (Map.Entry<Student, String> ss : tm1.entrySet()) {
System.out.println(ss.getKey() + " " + ss.getValue());
//getkey()方法是得到key,getvalue()方法是得到value
}
System.out.println("=============================");
//4.查找元素
//也需要用到CompareTo()方法,此处方法已被重写
System.out.println(tm1.containsKey(s1));// 查看是否有该key
System.out.println(tm1.containsKey(new Student("aaa",5)));
System.out.println(tm1.containsKey(new Student("aaa",10)));
System.out.println(tm1.containsValue("DDD"));//查看是否有该value值
}
public class Student implements Comparable<Student> {
//封装属性
private int age;
private String name;
//构造器,new之后,程序先运行构造器再生成对象
public Student(){
}
public Student(String name,int age) {
super();
this.age=age;
this.name=name;
}
//可以通过快捷键Alt+Insert:重写常用的方法
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 int hashCode() {
int n1=this.name.hashCode();
int n2=this.age;
return n1+n2;
}
@Override
public boolean equals(Object obj) {
// 1.判断这两个对象是不是同一个引用
if(this==obj){ return true; }
// 2.判断obj是否为null
if(obj==null){ return false; }
// 3.判断两个对象是否为同一类型
if(obj instanceof Student)//左边为对象,右边为类;
//obj所指的实际类型是Student的子类型,则true
{// 4.强制转换
Student student=(Student) obj;
// 5.
if(this.name==student.name&&this.age==student.age)
return true; }
return false;
}
@Override
public String toString() {
return "name:"+name+" "+"age:"+age;
}
@Override
public int compareTo(Student o) {
//先比姓名
int n1=this.name.compareTo(o.name);
int n2=this.age-o.age;
return n1==0?n2:n1;//如果n1比较的结果为0(名字相同),返回n2值,否则返回n1值
}
}