集合框架总结:
1. 什么是集合,有什么特点,集合用来做什么的。和数组有什么区别?
1.1 集合就是用来存储对象的容器,它只能存对象,不能存基本数据类型,长度是可变的。
虽然数组可以存储对象也可以存储基本数据类型,但是长度是固定的,一旦定义不可改变。![](https://img-blog.csdn.net/20131210222345953?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhhbmd0aWFuaGFvN182/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
2. Collection接口
2.1 Collection接口是集合体系的跟接口,拥有集合体系的共性内容。
2.2 拥有的常见方法:
2.2.1 add(E e) 向集合中添加元素,返回值类型为boolean,添加成功返回true。
2.2.2 addAll(Collection<? extends E> c) 将指定集合中的所有元素添加到此集合中
2.2.3 remove(Object o) 从集合中删除指定单个元素,返回值类型为boolean,删除成功返回true。
2.2.4 removeAll(Collection<?> c) 移除此集合中包含指定集合的元素,移除交集。返回值类型为boolean。
2.2.5 retainAll(Collection<?> c) 移除保留两个集合中交集的元素在此集合中。返回值类型为boolean。
2.2.6 clear() 移除此集合中的所有元素。返回值类型为void。
2.2.7 contains(Object o) 此集合中是否包含指定元素。
2.2.8 ContainsAll(Collection<?> c) 此集合中是否包含指定集合。
2.2.9 isEmpty() 此集合中时候还有元素,没有则返回true。
2.2.10 size() 返回此集合中元素的个数。
2.2.11 iterator() 返回在此集合的元素上进行迭代的迭代器。
2.2.12 toArray() 将集合转成数组。
3. Iterator接口
3.1 对集合进行迭代的迭代器,用于从集合中取出元素。它在迭代时,不能对集合进行操作,否则出现并发修改异常。
3.2 迭代器中的方法:
3.2.1 hasNext() 如果还有元素可以迭代则返回true。
3.2.2 next() 返回迭代的下一个元素。
3.3.3 remove() 移除迭代器返回的最后一个元素。返回值类型为void。
3.3 在迭代过程中不能出现多个Nexta()方法,否则会造成数据错乱(元素个数为偶数)或出现没有元素可以迭代异常(NoSuchElementException)
for(Iterator<Person> it = al.iterator(); it.hasNext(); ){
String name = it.next().getName(); // 获取姓名
int age = it.next().getAge(); // 获取年龄。此处是在迭代中第二次调用next()方法,会造成数据错乱。
// 可以通过下面解决此问题
Person p = it.nexta();
String name = p.getName();
int age = p.getAge();
}
4. List接口
4.1 List体系的集合容器中的元素是有序的,可重复的,可通过索引对集合中指定元素进行操作。
4.2 拥有的常见方法
4.2.1 add(int index, E element) 在集合的指定位置插入元素。返回值类型为void。
4.2.2 addAll(int index, Collection<? extends E> c) 在集合的指定位置插入指定集合中的元素。返回值类型为boolean.
4.2.3 indexOf(Object o) 返回集合中首次出现指定元素的位置索引,如果没有返回-1。
4.2.4 lastIndexOf(Object o) 返回集合中最后一次出现此元素的位置,没有则返回-1.
4.2.5 listIterator() 返回此集合特有的迭代器。
4.2.5.1 Iterator的子接口,是List体系特有的迭代器,可以逆向迭代,迭代过程可以对集合进行操作。
4.2.5.2 此迭代器的特有方法:
4.2.5.2.1 add(E e) 迭代过程中向集合中添加元素
4.2.5.2.2 hasPrevious() 逆向遍历此集合,要想逆向遍历取出元素,遍历前要正向遍历一次。麻烦,没这必要,一般不用。
4.2.5.2.3 previous() 返回迭代时的前一个元素。
4.2.5.2.4 set(E e) 用指定元素替换迭代时的最后一个元素。
4.2.5.2.4 nextIndex() 返回对 next 的后续调用所返回元素的索引
4.2.5.2.4 previousIndex() 返回对previous的后续调用所返回元素的索引。
4.2.6 remove(int index) 移除集合中指定位置的元素。
4.2.7 set(int index, E element) 用指定元素替换集合中指定位置的元素。
4.2.8 subList(int fromIndex, int toIndex) 返回集合中指定区间的一个新集合,包含头,不包含尾。
4.2.9 get(int index) 返回此集合中指定位置上的元素。
5. ArrayList类
5.1 List接口的实现类,底层实现是可变的数组结构,默认可以存储10个元素,超出后,自动增加50%。
5.2 线程不安全的,增删慢,查找快。
5.3 特有的方法:
5.3.1 removeRange(int fromIndex, int toIndex) 移除集合中指定区间的元素,包含头部包含尾。
6. LinkedList类
6.1 List接口的实现类,底层数据结构式链表结构,增删快,查询慢。线程不安全的。
6.2 特有方法:
6.2.1 addFirst(E e) 将指定元素添加到列表的开头
6.2.2 addLast(E e) 将指定元素添加到列表的结尾
6.2.3 descendingIterator() 返回以逆向顺序在此双端队列的元素上进行迭代的迭代器。
6.2.4 element() 获取且不移除此列表的头。
6.2.5 getFirst() 获取此列表的第一个元素。如果列表为空,抛出NoSuchElementException异常
6.2.6 getLast() 获取此列表的最后一个元素。
6.2.7 offerFirst(E e) 将指定元素插入到列表的开头。返回值类型是boolean。
6.2.8 offerLast(E e) 将指定元素插入到列表的结尾。返回值类型是boolean。
6.2.9 peekFirst() 获取但不移除此列表的第一个元素。和getgetFirst()的区别是,如果此列表为空,则返回 null。
6.2.10 peekLast() 和上一个同解。
6.2.11 pollFirst() 获取并移除此列表的第一个元素;如果此列表为空,则返回 null。
6.2.12 pollLast() 和上一个同解。
6.2.13 remove() 获取并移除此列表的头,还有几个重载形式也一样。
6.2.14 removeFirst() 移除并返回此列表的第一个元素。
6.2.15 removeLast() 移除并返回此列表的最后一个元素
7. vector类
7.1 底层结构也是可变长度的数组结构,默认长度为10,超出后增长100%。是线程安全的。效率低下。其它和ArrayList一样。
8. Set接口
8.1 Set体系集合的元素是不重复的,也是无序的。
8.2 对于Set体系中的元素取出方式只能通过迭代器,不能使用循环。
9. HashSet类
9.1 HashSet的底层数据结构式哈希表,桶状结构。是线程安全的。
9.2 HashSet调用的是HashMap来实现的。
9.3 判断对象是否是同一个对象,依照hashCode方法和equals共同决定的。
9.3.1 两个对象用equals方法比较的结果相等时,它们的哈希码也必须相等,但哈希吗相等的两个对象,equals方法比较不一定相等。
9.3.2 当一个对象存储进HashSet集合后,就不能修改这个对象中参与计算哈希值的字段了,否则,对象修改后的哈希值与最初
存储进hashSet集合中是的哈希值就不同了,在这种情况下即使在contains方法中使用该对象的当前引用做为参数去hashSet
集合中去检索对象时,也会返回找不到对象的结果。
关键代码:
// Person类中计算哈希值的方法
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
// main函数中执行代码
public static void main(String[] args) {
HashSet<Person> hs = new HashSet<Person>();
Person p = new Person("zhangsan", 23);
hs.add(p); // 将p这个对象存入集合中
p.setAge(12); // 改变对象参与计算哈希值的字段的值
System.out.println(hs.contains(p)); // 查看集合中时候有p这个对象,结果是false
}
9.4 存储到HashSet中的对象,重写hashCode和equals两个方法
9.4.1 重写equals方法的实现步骤:
9.4.1.1 对本对象和彼对象(this obj)进行地址的判断,如果地址一样,直接返回true
9.4.1.2 对象obj这个参数进行类型的判断,再次进行类型的强制转换
9.4.1.3 使用this和被转后的obj,进行所有成员变量的比较
9.4.1.4 如果传递的obj参数,不是本类类型直接返回false
9.4.2 重写hashCode方法的实现步骤
9.4.2.1 将对象中的引用变量取哈希值和基本数据类型直接相加或者相乘
10. TreeSet类
10.1 TreeSet集合底层数据结构是二叉树。线程不安全的。
10.2 对于存储在TreeSet集合中的元素,有自然顺序的排序。
10.2.1 自然顺序要求对象对应的类要实现Comparabler接口并覆盖compareTo方法。
10.3 或者让集合自省具备可比性,在实例化TreeSet集合时将自定义比较器作为参数。
10.3.1 自定义比较器要求实现Comparator接口,覆盖compare方法。
11. Map集合
11.1 Map体系的集合是个双列的集合,一次存储的是一个键值对象。
11.1.1 将键映射到值上,一个键映射一个值,允许重复的值,不允许重复的键。
11.2 Map集合的常用方法:
11.2.1 clear() 从此集合中移除所有映射关系。
11.2.2 containsKey(Object key) 如果此集合包含指定的键则返回true。
11.2.3 containsValue(Object value) 如果此集合中有指定的值则返回true。
11.2.4 get(Object key) 返回指定的键映射的值,如果没有此键,则返回null。
11.2.5 isEmpty() 如果此集合没有键值映射关系则返回true。
11.2.6 put(K key, V value) 将指定的键值映射存入此集合中。
11.2.7 putAll(Map<? extends K,? extends V> m) 将另一个map集合中的所有映射添加到此集合中
11.2.8 remove(Object key) 从集合中移除此键对应的映射,返回值为此键所映射的值。
11.2.9 size() 返回键值映射对数的个数
11.2.10 values() 返回此集合中的值的一个Collection集合。结果是collection类型。可以用此方法不通过键得到值。
11.2.11 keySet() 返回集合中此键的Set集合。返回值类型是Set。
11.2.12 entrySet() 返回集合中此键值对对象的集合。返回值类型是Set,里面的值的类型是Map.Entry类型的。
11.2.12.1 Map.Entry有两个常用方法:
11.2.12.1.1 getKey() 返回键值对象的键的对象
11.2.12.1.2 getValue() 返回键值对象的值的对象
12. HashMap类
12.1 HashMap集合的底层数据结构是哈希表,线程不安全的。操作效率高。允许null键和null值。
案例:给定字符,找出所有出现的字符,统计字符出现的次数。import java.util.HashMap;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Set;
/*
* 要求:接收任意一串输入,统计每个字符出现的次数。count统计 rate频率
* 分析:实际上要我们统计的是两个量,一个是哪个字符出现过,还有就是它出现了几次,
* 而且这两个量是对应存在的,可以用map集合来解决此问题。字符做键,出现次数做值。
* 步骤:
* 1,接收控制台输入,遍历获取字符串单个字符 char charAt(int x)
* 2,创建HashMap的实例,在对字符串遍历中按条件将字符作为键存入集合中
* (1)判断单个字符是否在集合的键中存在,如果存在,将键值对应值+1 boolean containsKey(Object key)
* (2)如果不存在,将字符直接存入集合
*/
public class CountRate {
public static void main(String[] args) {
System.out.println("请输入:");
show(getRate(getIn()));
//System.out.println(getRate("sf sdf ask skj sadff slkk fla asdjf"));
}
// 定义一个功能,获取控制台输入
static String getIn() {
Scanner sc = new Scanner(System.in);
return sc.next();
}
// 此功能统计字符串中单个字符和出现的次数
static HashMap<Character, Integer> getRate(String str) {
// 创建一个HashMap集合
HashMap<Character, Integer> hm = new HashMap<Character, Integer>();
for (int i = 0, start = 0; i < str.length(); i++) {
char ch = str.charAt(i);
// Integer num = hm.get(ch);
// hm.put(ch, num == null ? 1 : num + 1);
// 判断单个字符是否在集合的键中存在
if(!hm.containsKey(ch)){
// 集合中的键上没有此字符
hm.put(ch,1);
}else{
// 如果存在,在次存入,将键对应的值+1
hm.put(ch,hm.get(ch) + 1);
}
}
return hm;
}
// 用来显示出现过的字符和出现次数
static void show(HashMap<Character, Integer> hm) {
// 取元素keySet()
Set<Character> set = hm.keySet();
System.out.println("统计结果如下:");
// 遍历set集合,取出原来集合中的键
for (Iterator<Character> it = set.iterator(); it.hasNext();) {
char ch = it.next();
int rate = hm.get(ch);
System.out.println(ch + "出现了" + rate + "次。");
}
}
}
13. TreeMap类
13.1 TreeMap的底层数据结构是红黑树,是线程不安全的。
13.2 该集合根据键的自然顺序进行排序,或者根据比较器进行排序。具体排序依据是有构造方法决定的。
13.2.1 要求做为键的对象要具有可比性,实现Comparabler接口并覆盖compareTo方法。
13.2.2 自定义比较器要求实现Comparator接口,覆盖compare方法。
14. Hashtable集合
14.1 Hashtable的底层也是哈希表结构的,它是线程安全的,操作效率低。
14.2 它不允许出现null键和null值。
15. Properties集合
15.1 Hashtable的子类,是线程安全的。和IO配合使用,用于配置文件的读写操作。
15.2 Properties特有的读取操作:
15.2.1 getProperty(String key) 用指定的键在此属性列表中搜索属性
15.2.2 setProperty(String key, String value) 调用 Hashtable 的方法 put。
16. Collections工具类。操作集合常见的静态方法:
16.1 binarySearch()有序集合的折半查找法
16.2 sort(集合)对List集合进行排序
sort(集合,比较器)
16.3 reverseOrder()强行逆转对象的自然顺序,实现Comparable接口的顺序
reverseOrder(比较器)强行的逆转比较器
16.4 swap()集合换位
16.5 shuffle()集合中的元素的位置,随机变化
16.6 synchronized关键字开头的方法,将线程不安全的集合,变成线程安全的集合
17. Arrays工具类,操作数组的常用静态方法
17.1 binarySearch()有序数组的折半查找法
17.2 sort()对数组进行升序排序
17.3 static toString()将数组变成字符串
// Person类中计算哈希值的方法
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
// main函数中执行代码
public static void main(String[] args) {
HashSet<Person> hs = new HashSet<Person>();
Person p = new Person("zhangsan", 23);
hs.add(p); // 将p这个对象存入集合中
p.setAge(12); // 改变对象参与计算哈希值的字段的值
System.out.println(hs.contains(p)); // 查看集合中时候有p这个对象,结果是false
}
import java.util.HashMap;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Set;
/*
* 要求:接收任意一串输入,统计每个字符出现的次数。count统计 rate频率
* 分析:实际上要我们统计的是两个量,一个是哪个字符出现过,还有就是它出现了几次,
* 而且这两个量是对应存在的,可以用map集合来解决此问题。字符做键,出现次数做值。
* 步骤:
* 1,接收控制台输入,遍历获取字符串单个字符 char charAt(int x)
* 2,创建HashMap的实例,在对字符串遍历中按条件将字符作为键存入集合中
* (1)判断单个字符是否在集合的键中存在,如果存在,将键值对应值+1 boolean containsKey(Object key)
* (2)如果不存在,将字符直接存入集合
*/
public class CountRate {
public static void main(String[] args) {
System.out.println("请输入:");
show(getRate(getIn()));
//System.out.println(getRate("sf sdf ask skj sadff slkk fla asdjf"));
}
// 定义一个功能,获取控制台输入
static String getIn() {
Scanner sc = new Scanner(System.in);
return sc.next();
}
// 此功能统计字符串中单个字符和出现的次数
static HashMap<Character, Integer> getRate(String str) {
// 创建一个HashMap集合
HashMap<Character, Integer> hm = new HashMap<Character, Integer>();
for (int i = 0, start = 0; i < str.length(); i++) {
char ch = str.charAt(i);
// Integer num = hm.get(ch);
// hm.put(ch, num == null ? 1 : num + 1);
// 判断单个字符是否在集合的键中存在
if(!hm.containsKey(ch)){
// 集合中的键上没有此字符
hm.put(ch,1);
}else{
// 如果存在,在次存入,将键对应的值+1
hm.put(ch,hm.get(ch) + 1);
}
}
return hm;
}
// 用来显示出现过的字符和出现次数
static void show(HashMap<Character, Integer> hm) {
// 取元素keySet()
Set<Character> set = hm.keySet();
System.out.println("统计结果如下:");
// 遍历set集合,取出原来集合中的键
for (Iterator<Character> it = set.iterator(); it.hasNext();) {
char ch = it.next();
int rate = hm.get(ch);
System.out.println(ch + "出现了" + rate + "次。");
}
}
}