双列集合 :由2根单列集合组成的集合叫双列集合
双列集合的特点 : 夫妻对集合/键值对集合
1. 长度可变
2. 只能存对象 (基本数据类型使用包装类型进行存储)
3. 左边的一列集合(键集) : Set 集合 / 右边的一列集合(值集) : Collection集合 (大概率是List)
4. 双列集合键集的特点 : 元素唯一,元素无索引,元素存取无序
双列集合值集的特点 : 元素可重复,元素无索引,元素存取无序(夫唱妇随)
//双列集合 : 一妻多父制 奶量--露露 Pone--露露
5.
成对出现的数据 :
账号--密码,姓名--年龄,学生学号--学生对象, 属性名--属性值
Map
创建集合对象
Map
增删改查四类功能
增 / 改:
V put(K key, V value) : 往集合中添加一对映射关系 添加成功 : 返回 null 添加失败 : 返回 oldValue 键对应的老值 //当添加的键存在于集合中,修改此键对应的值,并且把老值返回
删 :
V remove(Object key) : 根据传入的键,删除集合中的这一对元素,方法的返回值是被删除的键值对中的值 boolean remove(Object key,Object value) : 按照传入的键值对删除集合中的这一对元素,返回删除是否成功 void clear(): 清空集合中所有的元素
查 :
V get(K key) : 根据传入的键找到其对应的值 -> 通过丈夫找媳妇 int size() : 获取双列集合中元素的个数 (有几对元素) boolean containsKey(Object key) : 查询集合中是否包含传入的键 boolean containsValue(Object value) : 查询集合中是否包含传入的值 boolean isEmpty() : 查询集合是否为空 SetkeySet() : 获取双列集合中所有的键集元素并存储到Set集合中 -> 召集所有的丈夫 Collection values() : 获取双列集合中所有的值集元素并存储到Collection集合中 -> 召集所有的媳妇
遍历
方式1 : keySet()方法和get()方法
a. 召集所有的键
b. 遍历键集 Set集合
c. 通过双列集合对象get方法,键找值
方式2 : 利用结婚证对象进行遍历
a. 召集所有的结婚证对象(键值对对象[Entry]) -> Set
b. 遍历键值对对象集合 Set集合
c. 通过每一个键值对对象获取每一个键值对对象内部封装的键和值
Entry接口 : K getKey()/V getValue()
HashMap
LinkedHashMap
LinkedHashMap
TreeMap
红黑树结构 : 排序 和 去重 --> 对key进行排序和去重
TreeMap
TreeMap
Hashtable
从JDK1.2板块开始并入到集合体系,被HashMap取代;
Hashtable
如果不需要线程安全 : 推荐使用 HashMap 集合
如果需要线程安全 : 推荐使用 ConcurrentHashMap 集合 (线程安全的[同步的],效率虽然低但是比Hashtable高)
虽然Hashtable很废, 但是它的儿子 Properties 非常常用!!
student.java:
import java.util.Objects; public class Student implements Comparable{ 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 boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Student student = (Student) o; return age == student.age && Objects.equals(name, student.name); } @Override public int hashCode() { return Objects.hash(name, age); } @Override public String toString() { return "Student{" + "name='" + name + ''' + ", age=" + age + '}'; } @Override public int compareTo(Student o) { return this.age - o.age; } }
案例1:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Test1 {
public static void main(String[] args) {
//创建班级集合
ArrayList basic = new ArrayList<>();
basic.add(new Student("张三",18));
basic.add(new Student("李四",17));
basic.add(new Student("王五",22));
ArrayList job = new ArrayList<>();
job.add(new Student("赵六",18));
job.add(new Student("田七",17));
job.add(new Student("朱八",22));
//创建学校集合
HashMap> school = new HashMap<>();
school.put("大三班",basic);
school.put("大四班",job);
//遍历集合
Set>> entries = school.entrySet();
for (Map.Entry> entry : entries) {
//通过键值对对象获取键和值
String className = entry.getKey();
ArrayList clazz = entry.getValue();
//遍历班级集合
for (Student student : clazz) {
//获取学生的属性
String name = student.getName();
int age = student.getAge();
System.out.println("班级名称 : " + className + ", 学生姓名 : " + name + ", 学生年龄 : " + age);
}
}
}
}
案例2:
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Test2 {
public static void main(String[] args) {
//学校集合
HashMap> school = new HashMap<>();
//班级集合
HashMap basic = new HashMap<>();
basic.put("basic001",new Student("张三",18));
basic.put("basic002",new Student("李四",19));
basic.put("basic003",new Student("王五",20));
HashMap job = new HashMap<>();
job.put("job001",new Student("赵六",18));
job.put("job002",new Student("田七",19));
job.put("job003",new Student("朱八",20));
//把班级集合添加到学校集合中
school.put("大三班",basic);
school.put("大四班",job);
//遍历外层集合
Set classNames = school.keySet();
for (String className : classNames) {
//键找值
HashMap clazz = school.get(className);
//遍历内层集合
Set> entries = clazz.entrySet();
for (Map.Entry entry : entries) {
//获取entry对象中封装的学生学号和学生对象
String sid = entry.getKey();
Student student = entry.getValue();
//取出学生对象的信息
String name = student.getName();
int age = student.getAge();
System.out.println("班级类型 : " + className + " , 学生学号 : " + sid + " , 学生姓名 : " + name + " , 学生年龄 : " + age);
}
}
}
}
泛型
泛型 : generic
泛 : 广泛,泛指,泛泛之辈 --> 意:说不清楚
型 : 数据类型
泛型 -> 说不清楚的引用数据类型
使用过的泛型 :
泛型的定义格式 : <字母>
注意事项 :
1. 规范是 字母全是大写 -> 不规范 :
2. 规范是 单个大写字母 -> 不规范 :
3. 一个尖括号类可以表示多个泛型类型,中间使用 逗号 分隔 -->
泛型的注意事项 :
1. 如果类中定义时有泛型,但是使用时忽略泛型,此时的泛型是 Object
2. 泛型只是停留在编译阶段的类型约束 (泛型概念 : jdk5),如果代码到了运行阶段,泛型就消失了
泛型类 : 在类的声明上有泛型类型的声明 (ArrayList
格式 :
public class 类名<泛型>{
//如果一个类声明时定义了泛型类型,那么久代表在此类中有一种 "泛型类型" 供此类使用
//泛型类型在类中是不知道指向一种具体类型 (只知道是一种不明确的引用数据类型)
//只有等到具体使用此类时,再明确泛型的具体类型
}
泛型方法
泛型方法 : 在方法的声明上有泛型类型的声明
(Arrays 工具类中的 : static
格式 :
方法的修饰符 <泛型> 返回值类型 方法名(形参列表){
方法体;
//retrun 值;
}
//泛型方法上的泛型一定在形参上有使用的. 它会根据调用方式传入的实参类型而随时改变
泛型接口
泛型接口 : 在接口的声明上有泛型类型的声明 (ArrayList
格式 :
public interface 接口<泛型>{
//如果一个接口声明时定义了泛型类型,那么久代表在此接口中有一种 "泛型类型" 供此接口使用
//泛型类型在接口中是不知道指向一种具体类型 (只知道是一种不明确的引用数据类型)
//只有等到具体使用此接口时,再明确泛型的具体类型
}
泛型沿用问题 : 如果子类继承父类/实现类实现父接口,子类没有沿用父类泛型类型,那么子类/实现类就不可以再享受泛型福利了 (例如 : Properties)
泛型的通配符和泛型的上限下限问题Object > Number > Integer
泛型的通配符 : 用在方法的形参上声明的泛型
? : 任意泛型类型都可以
泛型的下限 : ? super Number (此时的泛型是Number类或者Number的父类)
泛型的上限 : ? extends Number (此时的泛型是Number类或者Number的子类)
不管上限下限都是包含本类的!!
暑期编程PK赛 得CSDN机械键盘等精美礼品!


