1.集合
存多个引用数据类型的数据的集合.它的长度可变.(动态)
2.集合中常用概念:
-
有序性:按照添加顺序来排列.
-
可排序性:按照一定规则来排序(eg:数字由小到大,或由大到小来排序)
-
唯一性:只有一个,不可重复.
-
集合家族系谱图:
3 List
3.1:Collection接口
存储无序,可重复的单一对象.
3.1.1 List接口
存储有序,可重复的单一对象.
- ArrayList类:存储有序,可重复的单一对象.底层采用Object[]存值.
- LinkedList类:存储有序,可重复的单一对象.底层采用双向链表结构存值.
3.1.2 Set接口
存储无序,唯一的单一对象.
- HashSet类:存储无序,唯一的单一对象.底层采用HashMap的Key存值.
- TreeSet类:存储无序,但是可排序,唯一的单一对象.底层采用TreeMap的Key存值.
3.2 Map接口
按照Key-value对存值.
- HashMap:按照Key-value对存值,Key无序,唯一的.底层采用数组+链表结构存值.
- TreeMap:按照Key-value对存值,Key无序可排序,唯一的.底层采用二叉树结构存值.
4.ArrayList
存储有序的,可重复的单一对象.底层采用Object[]存值.默认按照1.5倍扩容.
- 优点:按顺序添加和修改及遍历的效率高.
- 缺点:删除元素或按指定索引添加元素效率低.
public static void main(String[] args) {
//创建集合对象
List stuAges=new ArrayList();
//向集合中添加元素
stuAges.add(11);
stuAges.add(99);
stuAges.add(61);
//向集合中指定索引位置添加元素时,索引范围:[0,集合.size()]
stuAges.add(2, 33);
stuAges.add(3, 71);
stuAges.add(11);
//遍历集合
for (int i = 0; i < stuAges.size(); i++) {
System.out.println(stuAges.get(i));
}
System.out.println("------------------------------");
//修改集合中元素,修改元素索引范围为:[0,集合.size()-1]
stuAges.set(2, 44);
//遍历集合
for (Object ob : stuAges) {
System.out.println(ob);
}
System.out.println("________________________________");
//删除集合中元素,删除的索引范围:[0,集合.size()-1]
stuAges.remove(1);
//删除集合中元素
stuAges.remove((Object)11);
//根据过滤器,删除满足条件元素
stuAges.removeIf(new Predicate() {
/**
* 过滤方法
*/
@Override
public boolean test(Object t) {
//将判断集合中每个元素转换字符串类型,再判断元素是否以1结尾
if (t.toString().endsWith("1")) {
return true;
}
return false;
}
});
//遍历集合
for (int i = 0; i < stuAges.size(); i++) {
System.out.println(stuAges.get(i));
}
System.out.println("------------------------------");
//清空集合
stuAges.clear();
//遍历集合
for (Object ob : stuAges) {
System.out.println(ob);
}
System.out.println("________________________________");
}
5.过滤器(filter)
将需要数据留下,不需要的数据剔除掉.
6.LinkedList
存储有序的,可重复的单一对象.底层采用双向链表结构存值.
- 优点:添加和删除元素效率高.
- 缺点:遍历和修改元素效率低.
public static void main(String[] args) {
//创建集合对象
LinkedList stuAges=new LinkedList();
//向集合中添加元素
stuAges.add(11);
stuAges.add(99);
stuAges.add(61);
//向集合中指定索引位置添加元素时,索引范围:[0,集合.size()]
stuAges.add(2, 33);
stuAges.add(11);
//向集合中添加第一个元素
stuAges.addFirst(22);
//向集合中添加最后一个元素
stuAges.addLast(55);
//遍历集合
for (int i = 0; i < stuAges.size(); i++) {
System.out.println(stuAges.get(i));
}
System.out.println("------------------------------");
//修改集合中元素,修改元素索引范围为:[0,集合.size()-1]
stuAges.set(2, 44);
//遍历集合
for (Object ob : stuAges) {
System.out.println(ob);
}
System.out.println("________________________________");
//删除集合中第一个元素
stuAges.removeFirst();
//删除集合中最后一个元素
stuAges.removeLast();
//删除集合中元素,删除的索引范围:[0,集合.size()-1]
stuAges.remove(1);
//删除集合中元素
stuAges.remove((Object)11);
//根据过滤器,删除满足条件元素
stuAges.removeIf(new Predicate() {
/**
* 过滤方法
*/
@Override
public boolean test(Object t) {
//将判断集合中每个元素转换字符串类型,再判断元素是否以1结尾
if (t.toString().endsWith("1")) {
return true;
}
return false;
}
});
//遍历集合
for (int i = 0; i < stuAges.size(); i++) {
System.out.println(stuAges.get(i));
}
System.out.println("------------------------------");
//清空集合
stuAges.clear();
//遍历集合
for (Object ob : stuAges) {
System.out.println(ob);
}
System.out.println("________________________________");
}
7.ArrayList VS Vector(面试)
相同点存储的都是有序的可重复单一对象,底层采用Object[]存值.
- 1:推出时间不同:Vector在JDK1.2之前就推出了;而ArrayList在JDK1.2后才推出.
- 2:线程安全性和效率不同:Vector是线程安全的集合,效率低;ArrayList是线程不安全的集合,效率高.
- 3:扩容不同:Vector按原来2倍扩容;ArrayList按原来1.5倍扩容.
- 4:方法不同:ArrayList拥有的所有方法Vector都有,Vector还有自己独有的方法.
8.迭代器(Iterator)
遍历访问collection集合中每个元素.
- 集合名.iterator();获得当前集合跌代器对象.
- 跌代器对象.hasNext();判断跌代器对象后面是否有元素可跌代.
- 跌代器对象.next();跌代元素(访问当前元素),
注意: 集合中每个元素只能调用一次next().
public static void main(String[] args) {
//创建集合对象
ArrayList stuAges=new ArrayList();
//向集合中添加元素
stuAges.add(11);
stuAges.add(99);
stuAges.add(61);
//获得集合的迭代器对象
Iterator it1=stuAges.iterator();
//循环判断迭代器对象后面是否有元素可迭代
while (it1.hasNext()) {
//迭代出当前元素
Object ob=it1.next();
System.out.println(ob);
}
}
public static void main(String[] args) {
//创建集合对象
ArrayList stus=new ArrayList();
//向集合中添加元素
stus.add(new Student("张三",88));
stus.add(new Student("李四",38));
stus.add(new Student("田七",48));
//获得集合的迭代器对象
Iterator it2=stus.iterator();
//循环判断迭代器后面是否有元素可迭代
while (it2.hasNext()) {
//迭代当前元素,并存在变量中
Student stu=(Student)it2.next();
//用变量调用属性输出
System.out.println(stu.sname+","+stu.sage);
}
}
9.Collections
collection集合家族工具类.
10.泛型
将引用数据类型参数化.(将引用数据类型作为参数来传递).语法:<数据类型>
10.1:泛型集合
将数据类型作为集合的参数,集合中每个元素必须都是这个泛型的数据类型。
- 1:泛型集合的使用:因为普通集合,存数据时要频繁的装箱(什么类型的数据存到集合中都要封装成Object类型),取出数据时要频繁的拆箱(将元素转换原来的类型),使用不方法.所以想到用泛型集合可以减少频繁的装箱和拆箱.
编译时即可检查,而非运行时抛出异常. - 2:泛型集合:一个集合中只能存同一种数据类型.
- 3:语法: 集合类型<数据类型> 集合名=new 集合类型<数据类型>;
public static void main(String[] args) {
//准备集合
List<Student> alist=new ArrayList<Student>();
//向集合添加元素
alist.add(new Student("张三1", 18));
alist.add(new Student("张三2", 18));
alist.add(new Student("张三3", 18));
//遍历集合
for (Student stu1 : alist) {
System.out.println(stu1.sname+"\t"+stu1.sage);
}
}
10.2:泛型迭代器
将数据类型作为迭代器的参数,迭代出来的每个元素是泛型的数据类型。
- 1:泛型迭代器的作用:减少频繁的类型转换的问题。
- 2:语法:Iterator<数据类型> 跌代器对象名=集合名.iterator();
- 3:泛型跌代器与泛型集合是黄金搭挡,集合用什么数据类型作为泛型,泛型跌代器就用相同的数据类型作为泛型的数据类型.
public static void main(String[] args) {
//准备集合
List<Student> alist=new ArrayList();
//向集合添加元素
alist.add(new Student("张三1", 18));
alist.add(new Student("张三2", 18));
alist.add(new Student("张三3", 18));
//获得集合的迭代器
Iterator<Student> it1=alist.iterator();
//循环判断迭代器后面是否有元素可迭代
while (it1.hasNext()) {
Student stu1=it1.next();
System.out.println(stu1.sname+"\t"+stu1.sage);
}
}
10.3:(扩展)泛型类
将引用数据类型作为类的参数,传到类中.
public class Teacher<T> {
public String tname;
public Integer tage;
//将泛型类型作为成员变量数据类型
public T num;
@Override
public String toString() {
return "Teacher [tname=" + tname + ", tage=" + tage + ", num=" + num + "]";
}
}
public static void main(String[] args) {
//创建对象
Teacher<Double> t1=new Teacher();
t1.tname="张三";
t1.tage=11;
t1.num=3.14;
System.out.println(t1);
//创建对象
Teacher<String> t2=new Teacher();
t2.tname="张三";
t2.tage=11;
t2.num="哈哈";
System.out.println(t2);
}
10.4:(扩展)泛型方法
将数据类型作为参数传到方法中用.
/**
* 泛型方法
* @param count
*/
public <T> void show(T count) {
System.out.println("参数为:"+count);
}
public static void main(String[] args) {
//创建对象
Student2 stu2=new Student2();
stu2.show("最近天气真不错哦");
stu2.show(3.14);
stu2.show(11);
}
10.5:泛型属性不能与static或final一起使用.
泛型类,泛型方法可以与static,final,abstract一起使用.
10.6:(扩展)受限泛型:
<?>:指代任意类型.
<? extends T>: T的子类
<? super T>: T的父类
11.(扩展)Stack继承自Vector类,是按压栈的方法存值,取值是按后进先出的方式取值.
12 Set
12.1 HashSet
HashSet:存储无序,唯一的单一对象.底层采用hashMap的key存值.
- 唯一性:通过HashSet泛型的类中hashCode()和equals()来去重.
优点:去重.
public static void main(String[] args) {
//准备一个集合
HashSet<Student> hset1=new HashSet<>();
//向集合中添加元素
hset1.add(new Student("张三", 18));
hset1.add(new Student("李四", 28));
hset1.add(new Student("王五", 48));
hset1.add(new Student("赵六", 38));
hset1.add(new Student("张三", 18));
//获得集合的迭代器
Iterator<Student> it1=hset1.iterator();
//循环判断迭代器后面是否有元素可迭代
while (it1.hasNext()) {
Student i=it1.next();
System.out.println(i);
}
System.out.println("---------------------------------");
//删除集合中元素
hset1.remove(new Student("李四", 28));
//遍历集合
for (Student i2 : hset1) {
System.out.println(i2);
}
System.out.println("*******************************");
//清空集合
hset1.clear();
//遍历集合
for (Student i2 : hset1) {
System.out.println(i2);
}
}
12.2 (了解)LinkedHashSet
存储有序的,唯一的单一对象.底层采用哈希表和链表实现了Set接口,具有可预测的迭代次序.
12.3 TreeSet
存储无序可排序的,唯一单一对象.底层采用TreeMap的Key存值.
注意: TreeSet是一定要用排序器,如果TreeSet的构造方法没有传自定义排序器对象,默认用的是自然排序器,要求TreeSet的泛型类一定要实现自然排序器接口,重写排序方法;如 果TreeSet的构造方法传自定义排序器对象,就按这个对象的排序方法来排序.
-
可排序性:通过排序器的排序方法返回正数,负数来排序的,返回负数排在左子节点(前面),返回正数排在右子节点(后面).
-
唯一性:通过排序器的排序方法返回0,静态两相节点相同,去重
-
优点:可排序,去重性.
public static void main(String[] args) {
//创建一个集合
TreeSet<Integer> tset1=new TreeSet<>();
//向集合中添加元素
tset1.add(66);
tset1.add(55);
tset1.add(88);
tset1.add(44);
tset1.add(77);
tset1.add(66);
//获得集合迭代器
Iterator<Integer> it1=tset1.iterator();
//循环判断迭代器后面是否有元素可迭代
while (it1.hasNext()) {
Integer n1=it1.next();
System.out.println(n1);
}
System.out.println("------------------------------");
//删除集合中元素
tset1.remove(44);
//遍历集合
for (Integer n2 : tset1) {
System.out.println(n2);
}
System.out.println("------------------------------");
//清空集合
tset1.clear();
//遍历集合
for (Integer n2 : tset1) {
System.out.println(n2);
}
}
12.4 排序器:
12.4.1:自然排序器(Comparable):
/**
* 自定义的类型,实现自然排序器接口,重写排序方法
*/
public class Student implements Comparable<Student>{
public String sname;
public Integer sage;
public Student() {
}
public Student(String sname, Integer sage) {
super();
this.sname = sname;
this.sage = sage;
}
@Override
public String toString() {
return "Student [sname=" + sname + ", sage=" + sage + "]";
}
/**
* 重写自然排序器接口的排序方法
* 排序规则:先根据姓名降序排序,当姓名相同时,按年龄升序排序
* @param o 表示每一个要比较节点,刚开始指根节点
*/
@Override
public int compareTo(Student o) {
if (this.sname.compareTo(o.sname)!=0) {
return -this.sname.compareTo(o.sname);
} else {//姓名相同
return this.sage.compareTo(o.sage);
// if (this.sage>o.sage) {
// return 1;//大的排在后面
// } else if (this.sage<o.sage){
// return -1;//小的排在前面
// }else {//姓名和年龄都相同
// return 0;//相同对象
// }
}
}
}
12.4.2:自定义排序器(Comparator):
/**
* 自定义排序器类,重写排序方法
*/
public class MyComparator implements Comparator<StudentA>{
/**
* 重写自定义接口中排序方法
* 排序规则:先年龄降序排序,年龄相同再按姓名降序排序
*/
@Override
public int compare(StudentA o1, StudentA o2) {
if (o1.sage.compareTo(o2.sage)!=0) {
return -o1.sage.compareTo(o2.sage);
} else {//年龄相同
return -o1.sname.compareTo(o2.sname);
}
}
}
public static void main(String[] args) {
//创建一个排序器对象
MyComparator mc=new MyComparator();
//创建一个集合,将自定义的排序器对象作为treeSet的构造方法参数
TreeSet<StudentA> tset1=new TreeSet<>(mc);
//向集合中添加元素
tset1.add(new StudentA("hh", 66));
tset1.add(new StudentA("dd", 66));
tset1.add(new StudentA("kk", 88));
tset1.add(new StudentA("aa", 44));
tset1.add(new StudentA("yy", 77));
tset1.add(new StudentA("hh", 16));
//获得集合迭代器
Iterator<StudentA> it1=tset1.iterator();
//循环判断迭代器后面是否有元素可迭代
while (it1.hasNext()) {
StudentA n1=it1.next();
System.out.println(n1);
}
System.out.println("------------------------------");
//删除集合中元素
tset1.remove(new StudentA("aa", 44));
//遍历集合
for (StudentA n2 : tset1) {
System.out.println(n2);
}
System.out.println("------------------------------");
//清空集合
tset1.clear();
//遍历集合
for (StudentA n2 : tset1) {
System.out.println(n2);
}
}
12.4.3:匿名内部类自定义排序器:
public static void main(String[] args) {
//创建一个集合,将自定义的排序器对象作为treeSet的构造方法参数
TreeSet<StudentB> tset1=new TreeSet<>(new Comparator<StudentB>() {
/**
* 重写自定义排序器接口中排序方法
* 排序规则:年龄升序排序,年龄相同按姓名升序排序
*/
@Override
public int compare(StudentB o1, StudentB o2) {
if (o1.sage.compareTo(o2.sage)!=0) {
return o1.sage.compareTo(o2.sage);
} else {//年龄相同
return o1.sname.compareTo(o2.sname);
}
}
});
//向集合中添加元素
tset1.add(new StudentB("hh", 66));
tset1.add(new StudentB("dd", 66));
tset1.add(new StudentB("kk", 88));
tset1.add(new StudentB("aa", 44));
tset1.add(new StudentB("yy", 77));
tset1.add(new StudentB("hh", 16));
//获得集合迭代器
Iterator<StudentB> it1=tset1.iterator();
//循环判断迭代器后面是否有元素可迭代
while (it1.hasNext()) {
StudentB n1=it1.next();
System.out.println(n1);
}
System.out.println("------------------------------");
//删除集合中元素
tset1.remove(new StudentB("aa", 44));
//遍历集合
for (StudentB n2 : tset1) {
System.out.println(n2);
}
System.out.println("------------------------------");
//清空集合
tset1.clear();
//遍历集合
for (StudentB n2 : tset1) {
System.out.println(n2);
}
}
13 Map
13.1.HashMap
存储key-value对.Key无序的,唯一的单一对象.底层采用数组+链表结构存值.
- Key的唯一性:通过HashCode()和equals()来保证.
注意: HashMap的key的泛型类中要重写HashCode()和equals().
public static void main(String[] args) {
//创建一个集合
Map<Integer, String> hmap1=new HashMap<>();
//向集合中存值
hmap1.put(55, "kk");
hmap1.put(11, "cc");
hmap1.put(44, "aa");
hmap1.put(55, "bb");
//将map集合转换为set集合,set集合中每个空间存key-value对
Set<Entry<Integer, String>> hset1=hmap1.entrySet();
/*遍历set集合*/
//获得set集合迭代器对象
Iterator<Entry<Integer, String>> it1=hset1.iterator();
//循环判断迭代器后面是否有元素可迭代
while (it1.hasNext()) {
Entry<Integer, String> e1=it1.next();
System.out.println(e1.getKey()+","+e1.getValue());
}
System.out.println("--------------------------------");
//删除集合中元素
hmap1.remove(11);
//将map集合中所有Key存在set集合中
Set<Integer> set2=hmap1.keySet();
//遍历所有Key
for (Integer k : set2) {
//通过K得到value
System.out.println(k+","+hmap1.get(k));
}
}
public static void main(String[] args) {
//创建一个集合
Map<Worker, String> hmap1=new HashMap<>();
//向集合中存值
hmap1.put(new Worker("唐三", 1000.0), "kk");
hmap1.put(new Worker("比比东", 3000.0), "cc");
hmap1.put(new Worker("千仞雪", 5000.0), "aa");
hmap1.put(new Worker("唐昊", 10000.0), "bb");
hmap1.put(new Worker("唐三", 1000.0), "uu");
//将map集合转换为set集合,set集合中每个空间存key-value对
Set<Entry<Worker, String>> hset1=hmap1.entrySet();
/*遍历set集合*/
//获得set集合迭代器对象
Iterator<Entry<Worker, String>> it1=hset1.iterator();
//循环判断迭代器后面是否有元素可迭代
while (it1.hasNext()) {
Entry<Worker, String> e1=it1.next();
System.out.println(e1.getKey()+","+e1.getValue());
}
System.out.println("--------------------------------");
//删除集合中元素
hmap1.remove(new Worker("比比东", 3000.0));
//将map集合中所有Key存在set集合中
Set<Worker> set2=hmap1.keySet();
//遍历所有Key
for (Worker k : set2) {
//通过K得到value
System.out.println(k+","+hmap1.get(k));
}
}
13.2.TreeMap
存key-value对.Key无序但是可排序,唯一的单一对象.底层采用二叉树结构存值.
注意: TreeMap一定要用排序器,如果TreeMap的构造方法中没有传递排序器对象,默认用的是自然排序器,要求TreeMap的Key的泛型类中要实现Comparable接口,重写排序方法;如果TreeMap的构造方法中传递排序器对象,用的是自定义排序器,在自定义排序器类中重写排序方法.
- Key的唯一性:通过排序器的排序方法返回0,表示Key相同Key不存Value覆盖.
- Key的可排序性:通过排序器的排序方法返回正数排在右子节点(后面),返回负数排在左子节点(前面).
public static void main(String[] args) {
//创建一个集合
Map<Integer, String> hmap1=new TreeMap<>();
//向集合中存值
hmap1.put(55, "kk");
hmap1.put(11, "cc");
hmap1.put(44, "aa");
hmap1.put(55, "bb");
//将map集合转换为set集合,set集合中每个空间存key-value对
Set<Entry<Integer, String>> hset1=hmap1.entrySet();
/*遍历set集合*/
//获得set集合迭代器对象
Iterator<Entry<Integer, String>> it1=hset1.iterator();
//循环判断迭代器后面是否有元素可迭代
while (it1.hasNext()) {
Entry<Integer, String> e1=it1.next();
System.out.println(e1.getKey()+","+e1.getValue());
}
System.out.println("--------------------------------");
//删除集合中元素
hmap1.remove(11);
//将map集合中所有Key存在set集合中
Set<Integer> set2=hmap1.keySet();
//遍历所有Key
for (Integer k : set2) {
//通过K得到value
System.out.println(k+","+hmap1.get(k));
}
}
13.3.排序器:
13.3.1:自然排序器(Comparable)
/**
* 员工类,实现自然排序器接口,重写排序方法
*/
public class WorkerA implements Comparable<WorkerA>{
public String wname;
public Double salary;
public WorkerA() {
// TODO Auto-generated constructor stub
}
public WorkerA(String wname, Double salary) {
super();
this.wname = wname;
this.salary = salary;
}
@Override
public String toString() {
return "Worker [wname=" + wname + ", salary=" + salary + "]";
}
/**
* 重写自然排序器接口中排序方法
* 排序规则:先按工资降序,工资相同按姓名升序
* @param this当前添加员工对象
* @param o表示从根节点开始,每个要比较的员工对象
*/
@Override
public int compareTo(WorkerA o) {
if (this.salary.compareTo(o.salary)!=0) {
return -this.salary.compareTo(o.salary);
} else {//工资相同,按姓名排序
return this.wname.compareTo(o.wname);
}
}
}
public static void main(String[] args) {
//创建集合
TreeMap<WorkerA, String> tmap2=new TreeMap<>();
//向集合中添加元素
tmap2.put(new WorkerA("a小舞", 20000.0), "aa");
tmap2.put(new WorkerA("c荣荣", 20000.0), "ii");
tmap2.put(new WorkerA("b竹青", 50000.0), "ww");
tmap2.put(new WorkerA("c比比东", 20000.0), "cc");
//将map集合转换为set集合,set集合中每个空间存key-value
Set<Entry<WorkerA, String>> set2=tmap2.entrySet();
//获得集合的迭代器
Iterator<Entry<WorkerA, String>> it2=set2.iterator();
//循环判断
while (it2.hasNext()) {
Entry<WorkerA, String> e2=it2.next();
System.out.println(e2.getKey()+"="+e2.getValue());
}
System.out.println("**********************************");
//删除集合中元素
tmap2.remove(new WorkerA("小舞", 20000.0));
//获得map集合中所有的Key存set中
Set<WorkerA> set3=tmap2.keySet();
//遍历
for (WorkerA k : set3) {
//通过key得到value值
System.out.println(k+"="+tmap2.get(k));
}
}
13.3.2:自定义排序器(Comparator)
:/**
* 自定义排序器类,重写排序方法
*/
public class MyComparator implements Comparator<WorkerB>{
/**
* 重写自定义排序器接口中排序方法
* 排序规则:工资降序,工资相同按姓名升序
* @param o1当前要添加对象
* @param o2从根节点开始每个要比较对象
*/
@Override
public int compare(WorkerB o1, WorkerB o2) {
if (o1.salary.compareTo(o2.salary)!=0) {
return -o1.salary.compareTo(o2.salary);
} else {//工资相同
return o1.wname.compareTo(o2.wname);
}
}
}
public static void main(String[] args) {
//创建排序器对象
MyComparator mc=new MyComparator();
//创建集合,将自定义排序器对象作为构造方法的参数
TreeMap<WorkerB, String> tmap2=new TreeMap<>(mc);
//向集合中添加元素
tmap2.put(new WorkerB("a小舞", 20000.0), "aa");
tmap2.put(new WorkerB("c荣荣", 20000.0), "ii");
tmap2.put(new WorkerB("b竹青", 50000.0), "ww");
tmap2.put(new WorkerB("c比比东", 20000.0), "cc");
//将map集合转换为set集合,set集合中每个空间存key-value
Set<Entry<WorkerB, String>> set2=tmap2.entrySet();
//获得集合的迭代器
Iterator<Entry<WorkerB, String>> it2=set2.iterator();
//循环判断
while (it2.hasNext()) {
Entry<WorkerB, String> e2=it2.next();
System.out.println(e2.getKey()+"="+e2.getValue());
}
System.out.println("**********************************");
//删除集合中元素
tmap2.remove(new WorkerB("小舞", 20000.0));
//获得map集合中所有的Key存set中
Set<WorkerB> set3=tmap2.keySet();
//遍历
for (WorkerB k : set3) {
//通过key得到value值
System.out.println(k+"="+tmap2.get(k));
}
}
13.4:匿名内部类自定义排序器
public static void main(String[] args) {
//创建集合,将自定义排序器对象作为构造方法的参数
TreeMap<WorkerC, String> tmap2=new TreeMap<>(new Comparator<WorkerC>() {
/**
* 重写自定义排序器接口中排序方法
* 排序规则:工资降序,工资相同按姓名升序
* @param o1当前要添加对象
* @param o2从根节点开始每个要比较对象
*/
@Override
public int compare(WorkerC o1, WorkerC o2) {
if (o1.salary.compareTo(o2.salary)!=0) {
return -o1.salary.compareTo(o2.salary);
} else {//工资相同
return o1.wname.compareTo(o2.wname);
}
}
});
//向集合中添加元素
tmap2.put(new WorkerC("a小舞", 20000.0), "aa");
tmap2.put(new WorkerC("c荣荣", 20000.0), "ii");
tmap2.put(new WorkerC("b竹青", 50000.0), "ww");
tmap2.put(new WorkerC("c比比东", 20000.0), "cc");
//将map集合转换为set集合,set集合中每个空间存key-value
Set<Entry<WorkerC, String>> set2=tmap2.entrySet();
//获得集合的迭代器
Iterator<Entry<WorkerC, String>> it2=set2.iterator();
//循环判断
while (it2.hasNext()) {
Entry<WorkerC, String> e2=it2.next();
System.out.println(e2.getKey()+"="+e2.getValue());
}
System.out.println("**********************************");
//删除集合中元素
tmap2.remove(new WorkerC("小舞", 20000.0));
//获得map集合中所有的Key存set中
Set<WorkerC> set3=tmap2.keySet();
//遍历
for (WorkerC k : set3) {
//通过key得到value值
System.out.println(k+"="+tmap2.get(k));
}
}
13.5.(了解)Hashtable
哈希表.线程安全,运行效率慢;不允许null作为key或者是value.
public static void main(String[] args) {
//创建一个集合
Map<Integer, String> hmap1=new Hashtable();
//向集合中存值
hmap1.put(55, "kk");
hmap1.put(11, "cc");
hmap1.put(44, "aa");
hmap1.put(55, "bb");
//HashTable不可以存null
//hmap1.put(null, null);
//将map集合转换为set集合,set集合中每个空间存key-value对
Set<Entry<Integer, String>> hset1=hmap1.entrySet();
/*遍历set集合*/
//获得set集合迭代器对象
Iterator<Entry<Integer, String>> it1=hset1.iterator();
//循环判断迭代器后面是否有元素可迭代
while (it1.hasNext()) {
Entry<Integer, String> e1=it1.next();
System.out.println(e1.getKey()+","+e1.getValue());
}
System.out.println("--------------------------------");
//删除集合中元素
hmap1.remove(11);
//将map集合中所有Key存在set集合中
Set<Integer> set2=hmap1.keySet();
//遍历所有Key
for (Integer k : set2) {
//通过K得到value
System.out.println(k+","+hmap1.get(k));
}
}
13.6.HashMap VS HashTable
都按Key-value对存值,实现Map接口,底层采用数组+链表结构存值.
- 1:推出时间不同:在jdK1.2推出HashMap,HashTable在Jdk1.2之前就推出.
- 2:初始容量和扩容不同:HashMap的默认初始容量为16,底层按2的倍数扩容;
HashTable的默认初始容量为11,底层按2倍+1扩容; - 3:存null不同:HashMap允许null作为key或者是value;
HashTable不允许null作为key或者是value; - 4:线程安全性不同:HashMap在单线程中使用效率较高,在多线程中使用不安全.
HashTable在单线程中使用效率较低,在多线程中使用安全. - 5:HashTable有HashMap所有的方法,还有自己独有方法.
13.7.Properties
配置文件类,按key-value存取值,要求key和value都是String类型.
- 适用场景:一般用于配置文件的读取.
public static void main(String[] args) {
//创建Properties对象
Properties pp=new Properties();
//存值
pp.setProperty("uname", "root");
pp.setProperty("pwd", "123456");
//获取值
System.out.println("用户名:"+pp.get("uname")+",密码:"+pp.get("pwd"));
}
14.小结
-
1.ArrayList:存储有序,可重复的单一对象.底层采用Object[]存值.
优点:遍历效率高,按顺序添加和修改
缺点:删除和按索引添加效率低 -
2.LinkedList:存储有序,可重复的单一对象.底层采用双向链表结构存值.
优点:删除和添加效率高
缺点:遍历效率低,修改效率低. -
3.HashSet:存储无序的,唯一的单一对象.底层采用HashMap的Key存值.
唯一性(去重):通过泛型类中重写HashCode()和equals(); -
4.TreeSet:存储无序的可排序的,唯一的单一对象.底层采用TreeMap的Key存值.
注意:TreeSet一定要用排序器,如果TreeSet的构造方法中没有传对象,默认用的自然排序器,要 求TreeSet的泛型类中实现自然排序器(Comparable)接口,重写排序方法;如果 TreeSet的构造方法中传对象了,用自定义排序器,重写排序方法.
唯一性(去重):通过排序器的排序方法返回0来去重.
可排序性:通过排序器的排序方法返回负数排在前面,返回正数排在后面. -
5.HashMap:按Key-value对存值.Key存储无序的,唯一的单一对象.底层采用数组+链表结构存值.
Key的唯一性:通过Key的泛型类中重写HashCode()和equals(); -
6.TreeMap:按Key-value对存值.Key存储无序的可排序的,唯一的单一对象.
底层采用二叉树结构存值.
注意: TreeMap一定要用排序器,如果TreeMap的构造方法中没有传对象,默认用的自然排序器,要 求TreeMap的Key的泛型类中实现自然排序器(Comparable)接口,重写排序方法;如果 TreeMap的构造方法中传对象了,用自定义排序器,重写排序方法.
Key的可排序性:通过排序器的排序方法返回负数排在前面,返回正数排在后面.
Key的唯一性(去重):通过排序器的排序方法返回0来去重. -
7.去重:用HashSet,HashMap,TreeSet,TreeMap去重.首选HashSet.
HashSet和HashMap采用重写HashCode()和equals()去重;
TreeSet和TreeMap采用排序器的排序方法返回0去重. -
8.排序:用TreeSet和TreeMap来排序.首选TreeSet排序.
TreeSet和TreeMap采用排序器的排序方法返回负数排在前面,返回正数排在后面来排序的.
个人笔记,思路,仅供参考