1.集合
概念:对象的容器,定义了对多个对象进行操作的常用方法,可实现对象的功能
2、认识集合
变量 ---》 数组 ---》集合
数组的缺陷:长度固定
数据类型相同
存储结构单一
概念:动态数组 存储任意引用类型 支持key-value存储结构
父接口:Collection
子接口1:List 存放数据特点:有序(索引) 可以重复
子接口2:Set 存放数据特点:无序 唯一
List接口的实现类
ArrayList:有序、可重复
3、collection体系集合
4、List子接口
特点:有序、有下标、元素可以重复
1)ArrayList(数组)
数组结构实现,查询快,增删慢
JDK1.2版本,运行效率快、线程不安全
import java.util.ArrayList;
import java.util.List;
public class Demo5 {
public static void main(String[] args) {
List list = new ArrayList();
//最多存放Integer.MAX_VALUE - 8个元素
//也就是2147483647个元素
System.out.println(Integer.MAX_VALUE);
//添加元素 不能添加基本数据类型,只能添加引用类型
//基本数据类型添加的是包装类
//add()追加 第一个索引的是 0 1 2
list.add(0);
list.add("张三");
list.add(false);
list.add(3.14);
//循环集合
System.out.println(list.get(0));
System.out.println(list.get(1));
System.out.println(list.get(2));
System.out.println(list.get(3));
System.out.println("----------------------");
//集合的索引范围 0~集合元素的个数-1,不能越界
//循环遍历集合中的元素
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
System.out.println("----------------------");
//把对象的元素存进集合当中
Student stu = new Student();
stu.setName("张三");
//把对象名存进集合当中
list.add(stu);
Teacher tea = new Teacher();
tea.setName("王老师");
list.add(tea);
//从集合中默认获取到的都是Object类
//必须要用父类来接收,所有的父类就是Object类
//在这里输出new对象的时候输出的是地址,所以就要在对象里重写toString
for(Object str : list) {
System.out.println(str.toString());
}
System.out.println("----------------------");
//获取集合中的第三个元素
//从集合中获取的都是Object类型
//如果需要判断还需要instancce来进行判断
Object obj = list.get(4);
//因为在子类当中重写了toString方法,所以可输出,要不然就输出地址
//就只能强制转换类型通过地址在堆内存当中找到值
Student stu1 = (Student)obj;
//输出值
System.out.println(stu1.getName());
}
}
import java.util.ArrayList;
import java.util.List;
public class Demo6 {
public static void main(String[] args) {
//限定集合中元素的类型
//list是个接口所以就只能new类
//<>里只能存包装类
List<String> list1 = new ArrayList<String>();
list1.add("aaa");
list1.add("bbb");
//此时因为上边限定String类型了,所以就只能存String类型
//new Student类型
Student stu = new Student();
//给stu赋值
stu.setName("张三");
//定义一个只存学生类型的集合
List<Student> stuList = new ArrayList<Student>();
//集合里放Student类型里的东西
stuList.add(stu);
Teacher tea = new Teacher();
tea.setName("王老师");
//stuList.add(tea);只能存学生的类型,老师的类型就存不进去了
System.out.println(stuList.get(0).getName());
System.out.println("---------------------");
//给list1赋值ccc
list1.add("ccc");
//长度 0~2
//遍历输出
for (int i=0; i<list1.size(); i++) {
System.out.println(list1.get(i));
}
System.out.println("---------------------");
//往集合当中插入元素
System.out.println("插入前,索引1对应的元素:" + list1.get(1));
//往集合当中插入元素
//索引为1时就放在1的那个位置
list1.add(1,"ddd");
// //在这之后再加入一个同样的元素,
// list1.add("ddd");
System.out.println("插入元素后");
for (int i=0; i<list1.size(); i++) {
System.out.println(list1.get(i));
}
System.out.println("插入后,索引1对应的元素:" + list1.get(1));
System.out.println("---------------------");
//删除集合中的元素
//参数是索引,按照索引删除
System.out.println("把索引1删除之后");
list1.remove(1);
for (int i=0; i<list1.size(); i++) {
System.out.println(list1.get(i));
}
System.out.println("---------------------");
//如果我此时同时添加两个ddd,再删除ddd
list1.add(1,"ddd");
list1.add("ddd");
//按照对象值进行删除,从前往后找到第一个值进行删除
list1.remove("ddd");
System.out.println("删除后,索引1对应的元素:"+list1.get(1));
for (int i=0; i<list1.size(); i++) {
System.out.println(list1.get(i));
}
}
}
import java.util.ArrayList;
import java.util.List;
public class Demo7 {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
//添加元素
list.add("aaa");
list.add("bbb");
list.add("ccc");
list.add("ddd");
//求集合的个数,也就是长度
System.out.println(list.size());
System.out.println("----------------------");
//清空集合
//第一种方法:
// list.clear();
//第二种方法:
//隔一个删一个,所以不可取
// for (int i=0; i<list.size(); i++) {
// list.remove(i);
// }
// for (int i=list.size()-1; i >= 0; i--) {
// list.remove(i);
// }
System.out.println("清除后,元素个数:"+list.size());
System.out.println("----------------------");
//isEmpty() 集合中元素个数为0时,此方法的返回值为true
System.out.println("集合中的元素是否为空?" + list.isEmpty());
System.out.println("----------------------");
List<String> list1 = new ArrayList<String>();
list1.add("xxx");
list1.add("yyy");
list1.add("zzz");
//把一个集合添加到另一个集合当中
//把list1中的元素添加到list当中去
list.addAll(list1);
System.out.println("追加后:");
//因为都是String类型,所以可以添加String类型
for(String stu : list) {
System.out.println(stu);
}
//判断集合之中是否包含某元素用contains
System.out.println("集合中是否包含元素xxx:" + list.contains("xxx"));
}
}
[注意]:集合取不了长度,只能求元素个数用size();
2)Vector(数组)
【说明】Vector的存储结构和操作方法同ArrayList集合相同
Vector 线程安全、效率低
ArrayList 线程不安全、效率高
数组结构实现,查询快,增删慢
JDK1.0版本,运行效率慢,线程安全
import java.util.List;
import java.util.Vector;
public class Demo1 {
public static void main(String[] args) {
List<Student> list = new Vector<Student>();
list.add(new Student("aaa"));
list.add(new Student("bbb"));
list.add(new Student("ccc"));
for(Student stu : list) {
System.out.println(stu);
}
}
}
3)LinkedList(双链表)
存储结构:不连续 是双向链表
特点:遍历时效率低 增加、删除效率高
链表结构实现,增删快,查询慢
import java.util.LinkedList;
import java.util.List;
public class Demo2 {
public static void main(String[] args) {
// 用LinkedList来接收,因为LinkedList是子类,List是接口无法调用子类方法
LinkedList<String> list = new LinkedList<String>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
System.out.println("--------------------");
//LinkedList作为List接口的子类额外增加了6个方法
//添加首元素
list.addFirst("xxx");
//添加尾元素
list.addLast("yyy");
for (int i=0; i<list.size(); i++) {
System.out.println(list.get(i));
}
System.out.println("--------------------");
//获取首元素
System.out.println("首元素:" + list.getFirst());
//获取尾元素
System.out.println("尾元素:" + list.getLast());
//删除首元素
list.removeFirst();
//删除尾元素
list.removeLast();
System.out.println("--------------------");
for (int i=0; i<list.size(); i++) {
System.out.println(list.get(i));
}
}
}
toArray使用的两种方式
import java.io.ObjectInputStream.GetField;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
public class Test1 {
public static void main(String[] args) {
LinkedList<String> link = new LinkedList<String>();
link.add("aaa");
link.add("bbb");
//不能把整个集合直接转换成数组
//要把数组中的每一个元组转换成数组的类型
//ClassCastException 类转换异常
// String[] str = (String[])link.toArray();
//既然toArray就是Object类型的那么直接用Object类型的数组来接收
//遍历集合的每一个元素
Object[] str = link.toArray();
for(int i=0 ;i<str.length;i++) {
System.out.println(str[i]);
}
//toArray的两种方式
//把学生的数据类型加进ArrayList集合当中
List<Student> list = new ArrayList<Student>();
list.add(new Student("张三"));
list.add(new Student("李四"));
Object[] obj = list.toArray();
for(int i=0;i<obj.length;i++) {
System.out.println(obj[i].toString());
Student stu = (Student)obj[i];
System.out.println(stu.getName());
}
//通过list.toArray这个方法
//告诉stuAry这个student类型的数组,
//把stuAry转换成student类型
//用toArray这个类型的参数
//放的是student这个数组的值,放零是因为这个数组一定有值的,最少也得有一个
//所以用零代表转换成第一个类型的值
//把集合转换成数组的同时,数组的类型就是目标类型
Student[] stuAry = list.toArray(new Student[0]);
for (int i = 0; i < stuAry.length; i++) {
System.out.println(stuAry[i].getName());
}
}
}
判断赋的值是否是同一个
import java.util.ArrayList;
import java.util.List;
//判断数组中的值是否是同一个值,但按值来看,
public class Demo3 {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
//定义一个新数组添加元素
list.add("aaa");
list.add("bbb");
//定义一个同类型的数组添加元素
List<String> list2 = new ArrayList<String>();
list2.add("aaa");
list2.add("bbb");
//地址值不一样,所以就是false
System.out.println(list == list2);
//第二种比较的是值,所以是false
System.out.println(list.equals(list2));
//把集合转成数组
//这种方式强转会造成报错 java.lang.ClassCastException
// String[] ary = (String[])list.toArray();
//第一种方法
Object[] ary = list.toArray();
for (int i = 0; i < ary.length; i++) {
System.out.println(ary[i].toString());
}
//【注意】 把集合转换成数组的时候,不要强制转换数组的类型,会报错
//可以对数组里的元素进行转换
List<Student> stu = new ArrayList<Student>();
stu.add(new Student("王xxx"));
stu.add(new Student("李XXX"));
Object[] objs = stu.toArray();
for (int i = 0; i < objs.length; i++) {
//每一个类型逐一进行转换
Student stus = (Student)objs[i];
System.out.println(stus.getName());
}
System.out.println("---------------------");
//把集合转成数组的同时,数组的类型就是目标类型
Student[] aryStus = stu.toArray(new Student[0]);
for (int i = 0; i < aryStus.length; i++) {
System.out.println(aryStus[i].getName());
}
}
}
5、泛型
Java泛型是JDK1.5中引入的新概念,其本质是参数化类型,把类型作为参数传递
常见类型有 泛型类 泛型接口 泛型方法
语法:<T> T称为类型占位符,表示一种引用类型
好处:提高代码的重用性 防止类型转换异常,提高代码的安全性
6、泛型集合
概念:参数化类型,类型安全的集合,强制集合元素的类型必须一致
特点:
编译时即可检查,而非运行时抛出异常
访问时,不必类型转换(拆箱)
不同泛型之间引用不能相互赋值,泛型不存在多态
7、Colletions工具类
概念:集合工具类,定义了除了存取以外的集合常用方法
方法:
public static void reverse(List<?> list) // 反转集合中元素的顺序
public static void shuffle(List<?> list) //随即重置集合元素的顺序
public static void sort(List<T> list) //升序排序(元素类型必须实现Comparable接口)
return this.name.compareTo(o.getName()); //名字排序
return o1.getName().compareTo(o2.getName()); //名字排序
public class Student implements Comparable<Student>{
private String name;
private int age;
public Student() {
}
public Student(String name) {
this.name = name;
}
public Student(int age) {
this.age = age;
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
// return this.name = name;
}
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 compareTo(Student o) {
//按照年龄排序
//当此时的年龄和传入进来的年龄进行做差
//例如:
// 16 -20 --> -4
// 16 -19 --> -3
// 19 20
// -3 -4
//从而排好 升序!
//20 - 16 --> 4
//19 - 16 --> 3
// 20 19
// 3 4
//从而排好 降序!
// return this.age - o.getAge();
return this.name.compareTo(o.getName());//换姓名升序排序
}
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Vector;
public class Test3 {
public static void main(String[] args) {
List<String> list1 = new ArrayList<String>();
list1.add("aaa");
list1.add("bbb");
list1.add("ccc");
list1.add("ddd");
//参数1 :截取的开始索引
//参数2 :截取的结束索引。但是不包含该索引
//返回值:截取到的元素
List<String> subList= list1.subList(1, 3);
for (int i = 0; i < subList.size(); i++) {
System.out.println(subList.get(i));
}
System.out.println("==============================");
//Collections工具类
List<String> list2 = new ArrayList<String>();
list2.add("ccc");
list2.add("aaa");
list2.add("ddd");
list2.add("bbb");
System.out.println("先前顺序:");
for(String newList2 : list2) {
System.out.println(newList2);
}
System.out.println("==============================");
//打乱集合中的顺序 --> 在第一次顺序的基础上进行打乱
Collections.shuffle(list2);
System.out.println("打乱后的顺序:");
for(String newList2 : list2) {
System.out.println(newList2);
}
System.out.println("==============================");
//升序排元素中的顺序
Collections.sort(list2);
System.out.println("排序后的顺序");
for(String newList2 : list2) {
System.out.println(newList2);
}
System.out.println("==============================");
//反转元素中的顺序
Collections.reverse(list2);
System.out.println("反转元素中的顺序");
for(String newList2 : list2) {
System.out.println(newList2);
}
System.out.println("==============================");
List<Student> stu = new ArrayList<Student>();
stu.add(new Student("002李四",50));
stu.add(new Student("001张三",20));
stu.add(new Student("003王五",30));
//排序方式1:
//Student类实现Comparable接口 用CompareTo进行排序
Collections.sort(stu);
System.out.println("排序方式1 ---> stu排序后:");
for(Student newStu : stu) {
System.out.println(newStu);
}
System.out.println("==============================");
//排序方式2:
//
Collections.sort(stu, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
//按照年龄排序
//升序排序 o1 - o2
//降序排序 o2 - o1
// return o1.getAge() - o2.getAge();
//按照名字排序
return o1.getName().compareTo(o2.getName());
}
});
System.out.println("排序方式2 ---> stu排序后:");
for(Student newStu : stu) {
System.out.println(newStu);
}
}
}
8、Set集合
特点:无索引 无序 唯一
全部继承自Collection中的方法
不能单个获取,只能使用foreach进行遍历,也就是说不能单个获取,要获取就一起获取到
实现类:HashSet,
数据结构:数组
链表
哈希表(数组加单链表)
树
HashSet添加元素的过程:先判断hashCode是否相同,如果不同则添加
如果hashCode相同,则equals 判断,如果equals也相同才拒绝添加
HashSet重点:
存储结构是哈希表
基于HashCode实现元素不重复
当存入元素的哈希码相同时,会调用 == 或equals进行确认,结果为true拒绝后者存入
所以HashCode的值不同 元素值也不同的 情况下才往里添加
import java.util.HashSet;
import java.util.Set;
public class Test4 {
public static void main(String[] args) {
Set<String> set = new HashSet<String>();
set.add("aaa1");
set.add("aaa2");
set.add("aab");
for(String s : set) {
System.out.println(s);
}
}
}
判断值的话重写完HashCode之后还要重写equals方法要不就会出现
3+5 = 8 和 5 + 3 = 8 的情况 也就是说值总共的哈希值相同但单个比较不相同
不重写HashCode和equals方法
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name) {
this.name = name;
}
public Student(int age) {
this.age = age;
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student [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;
}
}
import java.util.HashSet;
import java.util.Set;
public class Test4 {
public static void main(String[] args) {
Set<Student> set = new HashSet<Student>();
Student s1 = new Student("001张三",50);
Student s2 = new Student("003李四",18);
Student s3 = new Student("002王五",30);
Student s4 = new Student("002王五",30);
Student s5 = s1;
set.add(s1);
set.add(s2);
set.add(s3);
set.add(s4);
//地址相同,所以HashCode根据地址计算出值相同,值相同,就不往里添加了
//拒绝后添加的对象
set.add(s5);
//此时存的是new后的地址,所以HashCode值代表的是计算地址,不是值,
//如果单纯的想比较值,需要重写HashCode方法和equals方法
System.out.println("没有重写HashCode和equals方法之前:");
System.out.println();
for(Student s : set) {
System.out.println(s);
}
}
}
重写HashCode和equals方法
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name) {
this.name = name;
}
public Student(int age) {
this.age = age;
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student [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
public int hashCode() {
return name.hashCode() + age;
}
@Override
public boolean equals(Object obj) {
//判断传进来的是否为空,空就不是一个,返回false
if(obj == null) {
return false;
}
//判断类型是否为一样,不一样就不是一个,返回false
if(obj.getClass() != this.getClass()) {
return false;
}
//判断地址的是否一样,一样就证明是从一个数据类型里边传出来的
//就证明是一个,返回true
if(obj == this) {
return true;
}
//将传进来的obj强制转换成Student类型,因为泛型里放的是Student
//传进来的虽然是obj类型,但是他的原始类型就是Student
//再分别用当前Student类的每一个值去和obj传进来强制转换成的Student去比较
//如果每一个值都相等,则证明是一个值,返回true
Student stu = (Student)obj;
if(this.getName().equals(stu.getName()) && this.getAge() == stu.age) {
return true;
//除了这几种情况,剩下的所有情况都返回为false
}else {
return false;
}
}
}
import java.util.HashSet;
import java.util.Set;
public class Test4 {
public static void main(String[] args) {
Set<Student> set = new HashSet<Student>();
Student s1 = new Student("001张三",50);
Student s2 = new Student("003李四",18);
Student s3 = new Student("002王五",30);
//再写一遍一模一样的
Student s4 = new Student("002王五",30);
Student s5 = s1;
set.add(s1);
set.add(s2);
set.add(s3);
set.add(s4);
//地址相同,所以HashCode根据地址计算出值相同,值相同,就不往里添加了
//拒绝后添加的对象
set.add(s5);
//此时存的是new后的地址,所以HashCode值代表的是计算地址,不是值,
//如果单纯的想比较值,需要重写HashCode方法和equals方法
for(Student s : set) {
System.out.println(s);
}
}
}
LinkedHashSet:
链表实现的HashSet,按照链表进行存储,即可保留元素的插入顺序
存储结构是双向链表,有序但是值唯一
/*
学生类和上边相同,所以不再展示
*/
import java.util.LinkedHashSet;
import java.util.Set;
public class Test5 {
public static void main(String[] args) {
//LinkedHashSet 有序但是值唯一
//存储结构是双向链表
Set<Student> set = new LinkedHashSet<Student>();
Student s1 = new Student("001张三",50);
Student s2 = new Student("003李四",18);
Student s3 = new Student("002王五",30);
set.add(s2);
set.add(s1);
set.add(s3);
for(Student s : set) {
System.out.println(s);
}
}
}
TreeSet:
基于排序顺序实现元素不重复
实现了SortedSet接口,对集合元素自动排序
元素对象的类型必须实现Comparable接口,指定排序规则
通过CompareTo方法确定是否为重复元素
public class Teacher implements Comparable<Teacher>{
private String teaName;
private String teaNo;
private int age;
public Teacher(String teaNo, String teaName, int age) {
super();
this.teaName = teaName;
this.teaNo = teaNo;
this.age = age;
}
@Override
public String toString() {
return "Teacher [teaName=" + teaName + ", teaNo=" + teaNo + ", age=" + age + "]";
}
public String getTeaName() {
return teaName;
}
public void setTeaName(String teaName) {
this.teaName = teaName;
}
public String getTeaNo() {
return teaNo;
}
public void setTeaNo(String teaNo) {
this.teaNo = teaNo;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int compareTo(Teacher o) {
// return this.age - o.getAge();
// return this.teaName.compareTo(o.getTeaName());
return this.teaNo.compareTo(o.teaNo);
}
}
import java.util.Collections;
import java.util.Comparator;
import java.util.SortedSet;
import java.util.TreeSet;
public class Test6 {
public static void main(String[] args) {
//存储结构是树
//sorted是代表排序的意思,所以,数据类型必须得实现Comparable里的compareTo进行排序
SortedSet<Teacher> sort = new TreeSet<Teacher>();
Teacher tea1 = new Teacher("002", "张老师", 30);
Teacher tea2 = new Teacher("001", "王老师", 50);
Teacher tea3 = new Teacher("003", "李老师", 18);
sort.add(tea1);
sort.add(tea2);
sort.add(tea3);
for(Teacher t : sort) {
System.out.println(t);
}
//基本数据类型和String类型, 会自动排序
SortedSet<String> sort1 = new TreeSet<String>();
sort1.add("111");
sort1.add("bbb");
sort1.add("222");
for(String s : sort1) {
System.out.println(s);
}
}
}
9、Map
1)HashMap
public class Teacher implements Comparable<Teacher>{
private String teaName;
private String teaNo;
private int age;
public Teacher(String teaNo, String teaName, int age) {
super();
this.teaName = teaName;
this.teaNo = teaNo;
this.age = age;
}
@Override
public String toString() {
return "Teacher [teaName=" + teaName + ", teaNo=" + teaNo + ", age=" + age + "]";
}
public String getTeaName() {
return teaName;
}
public void setTeaName(String teaName) {
this.teaName = teaName;
}
public String getTeaNo() {
return teaNo;
}
public void setTeaNo(String teaNo) {
this.teaNo = teaNo;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int compareTo(Teacher o) {
// return this.age - o.getAge(); //年龄
// return this.teaName.compareTo(o.getTeaName()); //名字
return this.teaNo.compareTo(o.teaNo); //编号
}
}
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class Test7 {
public static void main(String[] args) {
Teacher zhang = new Teacher("001", "张老师", 25);
Teacher zheng = new Teacher("002", "郑老师", 40);
Teacher huang = new Teacher("003", "黄老师", 18);
//创建Map集合
//Map存入键值对,第一个是key的类型,第二个是value的类型
Map<String, Teacher> map = new HashMap<String, Teacher>();
//添加元素
//调用map方法,因为key是String类型的,所以说必须得用teacher里边唯一的一个做key
//所以就用工号做key ,因为value只能存Teacher类型的,所以只能存Teacher类型的对象
map.put(zhang.getTeaNo(), zhang);
map.put(zheng.getTeaNo(), zheng);
map.put(huang.getTeaNo(), huang);
System.out.println("添加元素之前map集合中元素的个数:" + map.size());
//添加元素
Teacher zhao = new Teacher("004", "赵老师", 35);
//key是唯一的,如果重复,那么用新的value覆盖掉原来的value
map.put("001", zhao);
System.out.println("key重复value不重复------map集合中元素的个数:" + map.size());
//value不是唯一的,只要key发生改变,那么就会添加新的元素
map.put("004", zheng);
System.out.println("key不重复value重复------map集合中元素的个数:" + map.size());
Map<String, Teacher> map1 = new HashMap<String, Teacher>();
//键值对可以存null
map1.put(null,null);
System.out.println("=================================");
System.out.println();
System.out.println("运用get(Object key)方法分别看一下各个key对应的元素:");
//获取map集合的元素
//这个key可以写.get也可以写本身对应的值
//key值和TeaNo是两回事,TeaNo可能是004,但是key用001存,
//那么用001搜索的就是TeaNo是004这个
Teacher teacher1 = map.get("001");
System.out.println(teacher1);
Teacher teacher2 = map.get("002");
System.out.println(teacher2);
Teacher teacher3 = map.get("003");
System.out.println(teacher3);
Teacher teacher4 = map.get("004");
System.out.println(teacher4);
System.out.println();
System.out.println("=================================");
//遍历map集合
System.out.println("方式一遍历HashMap:");
//方式一:
//获取key
//1、先获取到map集合中所有的key值,因为key是不能重复的所以可以用Set集合来接收
//数据类型要用key的数据类型
Set<String> keys = map.keySet();
//2、遍历获取得到的key
for(String key : keys) {
//3、根据key获取key所对应的value
// 因为我们后来要求的是Teacher里边的东西
// 所以用Teacher来接收
Teacher t = map.get(key);
System.out.println(t);
}
System.out.println("=================================");
System.out.println("方式二 1)遍历HashMap:");
//方式二:
//获取所有的value
//通过values()方法获取集合中所有的value
Collection<Teacher> collection = map.values();
//运用collection方法里边的toArray将其转换成数组
Object[] obj = collection.toArray();
//运用for循环遍历obj
for(int i=0;i<obj.length;i++) {
//将obj里边的每一个元素强制转换成Teacher类型
Teacher t = (Teacher)obj[i];
//输出Teacher类型里边的每一个元素
System.out.println(t);
}
System.out.println("---------------------------------");
System.out.println("方式二 2)遍历HashMap:");
//通过values()方法获取集合中所有的value
Collection<Teacher> collection1 = map.values();
//定义一个Teacher类型的数组 t
//将collection1中的元素按照new Teacher[0]进行转换
Teacher[] t = collection1.toArray(new Teacher[0]);
//遍历t
for(int i=0 ;i<t.length;i++) {
System.out.println(t[i]);
}
System.out.println("=================================");
System.out.println("方式二 3)遍历Map集合中每一个键值对:");
//方式三:
//运用Entry方法
//通过获取集合中的键值对(Entry)对象,获取键值对(Entry)对象中的键与值
//将key与value全部遍历出来
//以为key-value组合是唯一的所以用Set集合接收,
//获取所有的键值对对象, 数据类型为Map集合里的数据类型
Set<Entry<String, Teacher>> setEntry = map.entrySet();
//增强for循环进行遍历 数据类型为Set集合里的Entry类型
for(Entry<String, Teacher> entry : setEntry) {
//运用getKey方法,得到entry里边的key
//因为Entry里边的Key是String类型,所以用一个String类型的变量key来接收
String key = entry.getKey();
//运用getValue方法,得到entry里边的value
//因为Entry里边的Value是Teacher类型的,所以用一个Teacher类型的变量value来接收
Teacher value = entry.getValue();
//将key与value一起输出出来
System.out.println(key + value);
}
System.out.println("=================================");
//删除map集合中多余的元素
//删除的第一种方式
//只是删除Key
map.remove("004");
//重新获取所有的value值
System.out.println("删除key为004所代表的郑老师之后:");
Collection<Teacher> collection2 = map.values();
Object[] obj1 = collection2.toArray();
for(int i=0;i<obj1.length;i++) {
Teacher t1 = (Teacher)obj1[i];
System.out.println(t1);
}
//删除的第二种方式
//key -- value 一起删
//但是前提是 key与value必须输入正确
//如果key与value不对应的情况下,那么返回false 也就是删不掉
map.remove("003",huang);
System.out.println("--------------------------------------------");
Collection<Teacher> newCollection = map.values();
Object[] newObj = newCollection.toArray();
for(int i=0;i<newObj.length;i++) {
Teacher newT = (Teacher)newObj[i];
System.out.println(newT);
}
//输出集合中的元素
//集合的toString方法,把元素拼接成字符串
System.out.println(map);
}
}
2)TreeMap
public class Ceo implements Comparable<Ceo>{
private String ceoNo;
private String ceoName;
private int age;
public Ceo(String ceoNo, String ceoName, int age) {
super();
this.ceoNo = ceoNo;
this.ceoName = ceoName;
this.age = age;
}
@Override
public String toString() {
return "Ceo [ceoNo=" + ceoNo + ", ceoName=" + ceoName + ", age=" + age + "]";
}
public String getCeoNo() {
return ceoNo;
}
public void setCeoNo(String ceoNo) {
this.ceoNo = ceoNo;
}
public String getCeoName() {
return ceoName;
}
public void setCeoName(String ceoName) {
this.ceoName = ceoName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int compareTo(Ceo o) {
// TODO Auto-generated method stub
return this.getCeoNo().compareTo(o.getCeoNo());
}
}
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
public class Test8 {
public static void main(String[] args) {
//Map ---> SortedMap ---> TreeMap类
//newTreeMap对象
Map<String, Ceo> map1 = new TreeMap<String, Ceo>();
//newCeo对象并赋值
Ceo c1 = new Ceo("001", "张三", 20);
Ceo c2 = new Ceo("002", "李四", 19);
//将ceo对象的 c1 和 c2 存入进map集合中
map1.put(c1.getCeoNo(), c1);
map1.put(c2.getCeoNo(), c2);
//遍历map集合
Set<String> keys = map1.keySet();
for(String key : keys) {
System.out.println(map1.get(key));
}
System.out.println();
System.out.println("==============================");
System.out.println();
//用Ceo来作为key
//使用TreeMap存放数据时,key必须要实现Comparable接口,并且重写ComparaTo方法
//使用String不用实现Comparable接口以及重写CompareTo方法是因为String自己实现了这个方法
//所以也就是说想使用TreeMap存数据 key 必须得实现Comparable接口并重写CompareTo方法
//TreeMap的集合排序是按照key来排
Map<Ceo, Ceo> map2 = new TreeMap<Ceo, Ceo>();
Ceo ceo1 = new Ceo("002", "张三", 19);
Ceo ceo2 = new Ceo("001", "李四", 20);
map2.put(ceo1, ceo1);
map2.put(ceo2, ceo2);
System.out.println("用Ceo来作为key并且实现Comparable重写CompareTo之后:");
Set<Ceo> newKeys = map2.keySet();
for(Ceo newKey: newKeys) {
System.out.println(map2.get(newKey));
}
}
}
10、Map父接口
特点:称为“映射”存储一对数据(Key-Value),键不可重复,值可以重复
方法:
• V put(K key,V value) //将对象存入到集合中, 关联键值。key重复则覆盖原值。
• Object get(Object key) //根据键获取对应的值。
• Set<K> keySet//返回所有key。
• Collection<V> values()//返回包含所有值的Collection集合。
• Set<Map.Entry<K,V> > entrySet() //键值匹配的Set集合
11、Map集合的实现类
• HashMap【重点】:
• JDK1.2版本, 线程不安全, 运行效率快;允许用null 作为key或是value。
• Hashtable :
• JDK1.0版本, 线程 安全, 运行效率慢;不允许null作为key或是value。
• Properties :
• Hashtable的子类, 要求key和value都是String。 通常用于配置文件的读取。
• TreeMap :
· 实现了SortedMap接口(Map的齐妾口), 可以对key自动排序, Key需实现Comparable接口。
12、总结
· 集合的概念:
· 对象的容器, 存储对象的对象, 定义了对多个对象进行操作的常用方法。
• List集合:
· 有下标、 元素可以重复。 (Arraylist、 Linkedlist、 Vector}
• Set集合:
· 无下标、 元素不可重复。 (HashSet、 LinkedHashSet、 TreeSet}
• Map集合:
· 存储一对数据, 键不可重复, 值可重复。 (HashMap、 Hashtable、 Properties、 TreeMap}
• Collections:
· 集合工具类, 定义了除了存取以外的集合常用方法。