一、Java集合框架
- 切合面向对象,以对象的形式存储
- 数组储存对象不方便,可以放在集合(容器)
二、Collection接口API
- 便是不安添加顺序存放对象的集合,集合内元素可以重复,即“无序可重复”集合
- 解决是批量对象的存储问题. 可以简单地看作是一个可变长度的Object[]
三、Iterator迭代器接口
3.1 特点
- 所有实现了Collection接口的集合都有此方法
- 本身不提供封装对象的能力
- 创建iterator对象必须本身是一个可被迭代的对象
3.2 方法
- it.hashNext() : 判断是否还有下一个元素
- it.next() : 取出下一个元素
3.3. 示例
Iterator iterator = coll.iterator();
while (iterator.hasNext()) {
Object obj = iterator.next();
System.out.println(obj);
}
四、Collection子接口之Set接口
4.1 特点
元素无序(插入顺序)且不可重复
4.2 HashSet
4.2.1 特点
- 不能保证元素排序顺序
- HashSet不是线程安全的
- 集合元素可以是null
4.2.2 判断
对象是否相同使用equals()方法且hashCode()相等
4.2.3 示例
单元测试:test3.java
@Test
public void test3() {
Set set = new HashSet(); // 无序不可重复
// 对象去重时依据的是两个对象的equals是否为true, 并且两个对象的哈希码也相同.
Student s1 = new Student(1, "小明", 3, 90);
Student s2 = new Student(1, "小明", 3, 90);
Student s3 = new Student(2, "小丽", 1, 100);
set.add(s1);
set.add(s2);
set.add(s3);
set.add(s3);
for (Object object : set) {
System.out.println(object);
}
}
Student.java:
class Student implements Comparable {
private int id;
private String name;
private int grade;
private double score;
public Student() {
}
public Student(int id, String name, int grade, double score) {
super();
this.id = id;
this.name = name;
this.grade = grade;
this.score = score;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getGrade() {
return grade;
}
public void setGrade(int grade) {
this.grade = grade;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", grade=" + grade + ", score=" + score + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + grade;
result = prime * result + id;
result = prime * result + ((name == null) ? 0 : name.hashCode());
long temp;
temp = Double.doubleToLongBits(score);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (grade != other.grade)
return false;
if (id != other.id)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (Double.doubleToLongBits(score) != Double.doubleToLongBits(other.score))
return false;
return true;
}
@Override
public int compareTo(Object o) {
if (o instanceof Student) {
return this.grade - ((Student)o).grade;
}
throw new RuntimeException("对象不可比");
}
}
4.3 LinkedHashSet
- 根据元素HashCode值来决定元素的存储位置
- 使用链表维护元素的次序
- 插入性能略低于hashSet,但迭代元素很强
- 元素不允许重复
4.4 TreeSet
TreeSet可以确保集合元素处于排序(不是插入顺序)状态
4.4.1 自然排序(默认)
- 调用集合元素的compareTo(Object obj)方法来比较怨怒之间的大小,按升序排列
- 如果试图把一个对象添加到 TreeSet 时,则该对象的类必须实现 Comparable 接口。
2.1. 实现 Comparable 的类必须实现 compareTo(Object obj) 方法,两个对象即通过 compareTo(Object obj) 方法的返回值来比较大小。
4.4.2 定制排序
第一种:用匿名内部类:
@Test
public void PersonSetTest() {
/*
* 写一个类Person, 包括属性name, age, gender, 创建一些对象,
使用定制排序把这些对象保存在Set集合中, 要求按照年龄倒序排序.
*/
System.out.println();
Set<Person> set = new TreeSet<Person>(new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
Integer x = o1.getAge();
Integer y = o2.getAge();
return -x.compareTo(y);
}
});
set.add(new Person("天天", 18, "男"));
set.add(new Person("丽丽", 17, "女"));
set.add(new Person("美美", 19, "女"));
for (Person person : set) {
System.out.println(person);
}
}
第二种定义类:
// 自定义比较器
class MyComparator implements Comparator {
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof Student && o2 instanceof Student) {
//return ((Student)o1).getGrade() - ((Student)o2).getGrade();
return (int)(((Student)o1).getScore() * 10 - ((Student)o2).getScore() * 10);
}
throw new RuntimeException("对象不可比");
}
}
五、Collection子接口之List接口
元素有序且可重复
5.1 方法
void add(int index, Object ele) // 添加
boolean addAll(int index, Collection eles) // 添加一个集合
Object get(int index) // 获取下标的值
int indexOf(Object obj)
int lastIndexOf(Object obj)
Object remove(int index) // 删除
Object set(int index, Object ele) // 按index插入值
List subList(int fromIndex, int toIndex) // 子集合
5.2 ArrayLists
5.2.1 特点
- 线程不安全
- 变长数组
- 检索速度高于LinkedList
- 在末端插入数据快
5.2.2 方法
Arrays.asList()返回一个固定长度的List集合
5.2.3 缺点
- 内存要求高(连续)
- 非末端数据插入删除满,要进行批量移动
5.2.4 示例
// 创建一个List集合, 保存10个20以内的随机整数
@Test
public void exer2() {
List list = new ArrayList();
for (int i = 0; i < 10; i++) {
int rand = (int)(Math.random() * 20);
list.add(rand);
}
// 遍历
for (Object object : list) {
System.out.println(object);
}
}
5.3 LinkedList
5.3.1 特点
- 适用于频繁的插入或删除元素的操作
- 适用于大批量数据的存放和管理
5.3.2 缺点
检索速度慢
5.3.3 方法
void addFirst(Object obj)
void addLast(Object obj)
Object getFirst()
Object getLast()
Object removeFirst()
Object removeLast()
5.4 Vector
- 线程安全
- 不推荐使用
六、Map接口
6.1 特点
- 具有映射关系“key-value”的集合
- key值不能重复
6.2 方法
Object put(Object key,Object value)
Set keySet()
Collection values()
Set entrySet()
Object get(Object key)
6.3 HashMap
6.3.1 特点
- 允许使用null键和null值
- 无序
- 两个key相等:equals和hashCode都相等
6.3.2 子类:LinkedHashMap
插入有顺序
6.3.3 示例
@Test
public void exer2() {
Map<Integer,Integer> map = new HashMap<Integer, Integer>();
for (int i = 1; i < 51; i++) {
int area = (int)(Math.PI * i * i);
map.put(i, area);
}
// 遍历
Set<Integer> keySet = map.keySet();
Iterator<Integer> iterator = keySet.iterator();
while (iterator.hasNext()) {
Integer radius = iterator.next();
Integer area = map.get(radius);
System.out.println(radius + " *********************** " + area);
}
}
6.4 TreeMap
6.4.1 自然排序
TreeMap 的所有的 Key 必须实现 Comparable 接口,而且所有的 Key 应该是同一个类的对象,否则将会抛出 ClasssCastException
6.4.2 定制排序
创建 TreeMap 时,传入一个 Comparator 对象,该对象负责对 TreeMap 中的所有 key 进行排序。此时不需要 Map 的 Key 实现 Comparable 接口
6.4.3 示例
@Test
public void fun3() {
// // 2.请把学生名与考试分数录入到Map中,并按分数显示前三名成绩学员的名字。
Map<Integer, Student> map = new TreeMap<Integer, Student>();
map.put(1, new Student("张三", 89));
map.put(2, new Student("李四", 45));
map.put(3, new Student("王五", 35));
map.put(4, new Student("刘备", 50));
map.put(5, new Student("关羽", 99));
List<Map.Entry<Integer, Student>> list = new ArrayList<Map.Entry<Integer, Student>>(map.entrySet());
// list.addAll((Collection<? extends Map<Integer, Student>>) map);
Collections.sort(list, new Comparator<Map.Entry<Integer, Student>>() {
@Override
public int compare(Entry<Integer, Student> o1, Entry<Integer, Student> o2) {
return o1.getValue().getScore() - o2.getValue().getScore();
}
});
for (Map.Entry<Integer, Student> entry : list) {
System.out.println(entry.getKey() + " " + entry.getValue());
}
}
6.5 Hashtable
6.5.1 特点
- 线程安全
- 不允许使用null作为键值
- 不能保证顺序
- 判断key或value相等与hashMap一样
6.5.2 子类:properties
- 用于处理属性文件
- key和value都是字符串类型
- 存取数据时,建议使用setProperty(String key,String value)方法和getProperty(String key)方法
6.5.3 示例
Properties pros = new Properties();
pros.load(new FileInputStream("jdbc.properties"));
String user = pros.getProperty("user");
System.out.println(user);
七、Collections工具类
提供了一系列静态的方法对集合元素进行排序、查询和修改等操作,还提供了对集合对象设置不可变、对集合对象实现同步控制等方法
7.1 排序操作(static)
reverse(List):反转 List 中元素的顺序
shuffle(List):对 List 集合元素进行随机排序
sort(List):根据元素的自然顺序对指定 List 集合元素按升序排序
sort(List,Comparator):根据指定的 Comparator 产生的顺序对 List 集合元素进行排序
swap(List,int, int):将指定 list 集合中的 i 处元素和 j 处元素进行交换
7.2 查找和替换
Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素
Object max(Collection,Comparator):根据 Comparator 指定的顺序,返回给定集合中的最大元素
Object min(Collection)
Object min(Collection,Comparator)
int frequency(Collection,Object):返回指定集合中指定元素的出现次数
void copy(List dest,List src):将src中的内容复制到dest中
boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替换 List 对象的所有旧值
7.3 同步控制
Collections 类中提供了多个 synchronizedXxx() 方法,该方法可使将指定集合包装成线程同步的集合,从而可以解决多线程并发访问集合时的线程安全问题
八、泛型(Generic)
- 提供了编译时的类型安全检查
- 泛型约束了集合所能存储的对象类型,不必再进行强制类型转换
- <>中的类型称为泛型的类型参数
九、hashCode()
- 程序运行时,同一个对象多次调用hashCode()方法应该返回相同的值
- 两个对象的equals比较返回为true,则对象的hashCode也应相等
- 对象中用作 equals() 方法比较的 Field,都应该用来计算 hashCode 值
十、小结
- 线程安全(Thread-safe)的集合对象:Vector、Hashtable、StringBuffer
- 集合的元素能是null的:HashMap、HashSet
- 支持定制排序,传入Comparator:TreeSet、TreeMap
十一、Life
"我们害怕的不是死亡,而是没有竭尽全力的活着" ,
“i dont care”