一、Collection
框架图:
Collection父接口:
- 特点:代表一组任意类型的对象,无序、无下标。
常用方法:
方法 | 描述 |
---|---|
boolean add(Object obj) | 添加一个对象数据 |
boolean addAll(Collection c) | 将一个集合中的所有对象添加到此集合中 |
void clear() | 清空此集合中的所有对象 |
boolean contains(Object o) | 检查此集合中是否包含o对象 |
boolean equals(Object o) | 比较此集合是否与指定对象相等 |
boolean isEmpty() | 判断此集合是否为空 |
boolean remove(Object o) | 在此集合中移除o对象 |
int size() | 返回此集合中的元素个数 |
Object[] toArray() | 将此集合转换成数组 |
注:遍历的同时不能使用集合删除方法,否则出现并发修改异常,可使用迭代器的删除方法。
1.1迭代器
iterator
Collection extends Iterable;
意味着只要是Collection的子类都有迭代器
含义:遍历集合中的数据
分类:Iterator 和 ListIterator
Iterator 和 ListIterator 区别
Iterator :Collection接口下所有的实现类都可以获取的迭代器,可以在遍历时删除元素
ListIterator :List接口下所有的实现类可以获取的迭代器,可以在遍历时删除、替换、添加元素,也可以指定下标开始遍历,还可以倒叙遍历
//获取迭代器
Iterator<T> itor = 集合.iterator();
//while
while(itor.hasNext()){
T t = itor.next();
}
注意:迭代器可以在迭代的同事删除当前元素
反向迭代器(功能更加强大--复杂情况是考虑使用)
使用列表迭代器 ,和Iterator的区别,ListIterator可以向前或向后遍历,添加、删除、修改元素
ListIterator lit=list.listIterator(); // 可以放东西的 listIterator(list.size())
System.out.println("------使用列表迭代器从前往后-------");
while(lit.hasNext()) {
System.out.println(lit.nextIndex()+":"+lit.next());
}
System.out.println("------使用列表迭代器后往前-------");
while(lit.hasPrevious()) {
System.out.println(lit.previousIndex()+":"+lit.previous());
}
1.2比较器
作用:排序时使用
分类:
内置比较器:Comparable - compareTo()
外置比较器:Comparator - compare()
使用场景:
内置比较器:对象要想存入TreeSet、TreeMap中,对象所属的类必须要实现内置比较器
外置比较器:当内置比较的规则不满足现在的需求,但又不能改动内置比较器规则时
优先级别:外置比较器 > 内置比较器
二、List
- 特点:有序、有下标、元素可以重复。
- 继承Collection接口。
常用方法:
方法 | 描述 |
---|---|
void add(int index, Object o) | 在index位置插入对象o。 |
boolean addAll(int index, Collection c) | 将一个集合中的元素添加到此集合中的index位置。 |
Object get(int index) | 返回集合中指定位置的元素。 |
List subList(int fromIndex, int toIndex) | 返回fromIndex和toIndex之间的集合元素。 |
List的创建及4种遍历方式:
public class Test {
public static void main(String[] args) {
// 创建
List<String> list=new ArrayList<>();
//1添加元素
list.add("苹果");
list.add("小米");
list.add("华为");
// 直接输出
System.out.println(list);
System.out.println("-------------");
// 遍历方法1 for循环
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
System.out.println("-------------");
// 遍历方法2 增强for循环
for (String string : list) {
System.out.println(string);
}
System.out.println("-------------");
// 遍历方法3 使用迭代器
Iterator ito = list.iterator();
while(ito.hasNext()) {
System.out.println(ito.next());
}
System.out.println("-------------");
// 遍历方法4 使用列表迭代器 (功能比Iterator更多可向前、向后,增加删除)
ListIterator lit=list.listIterator(list.size());
while(lit.hasPrevious()) {// 演示倒序
System.out.println(lit.previousIndex()+":"+lit.previous());
}
}
}
2.1ArrayList
- 数组结构实现,查询快、增删慢。
- JDK1.2版本、线程不安全。
- 底层数据结构是一维数组
2.2LinkedList
-
链表结构实现,增删快,查询慢。
-
JDK1.2版本、队列模式、栈模式,线程不安全
-
底层数据结构是双向链表
-
ArrayList和LinkedList区别:
-
ArrayList存储结构是数据,查找、遍历效率高。
-
LinkedList存储结构是双向链表,删除、添加效率高。
添加 - 不扩容的情况:ArrayList快
添加 - 扩容的情况:LinkedList快
删除:LinkedList快
查询:ArrayList快
修改:ArrayList快
注意:工作中常用ArrayList,因为很多需求都需要使用查询功能,ArrayList查询更快
2.3Vector
数组结构实现,查询快、增删慢。
JDK1.0版本,线程安全、运行效率比ArrayList较慢。
2.4Stack
弃用,线程安全
三、Set
- 特点:无序、无下标、元素不可重复。
- 方法:全部继承自Collection中的方法。
- 使用foreach循环遍历:
for(数据类型 局部变量 : 集合名){
//循环内部的局部变量,代表当次循环从集合中取出的对象
}
Set的创建和遍历方法:
public class TestSet {
public static void main(String[] args) {
// 创建
Set<String> set=new HashSet<>();
//1添加元素
set.add("苹果");
set.add("小米");
set.add("华为");
// 直接输出
System.out.println(set);
System.out.println("-------------");
// 遍历方法1 增强for循环
for (String string : set) {
System.out.println(string);
}
System.out.println("-------------");
// 遍历方法2 使用迭代器
Iterator ito = set.iterator();
while(ito.hasNext()) {
System.out.println(ito.next());
}
System.out.println("-------------");
}
}
3.1HashSet
- 基于HashCode实现元素不重复。线程不安全
- 当存入元素的哈希码相同时,会调用==或equals进行确认,结果为true,拒绝后者存入。
3.2LinkedHashSet
LinkedHashSet是在HashSet的基础上新维护了一个双向链表
链表实现的HashSet,按照链表进行存储,即可保留元素的插入顺序。
线程不安全
3.3TreeSet
- 基于排列顺序实现元素不重复。
- 实现了SortedSet接口,对集合元素自动排序。
- 元素对象的类型必须实现Comparable接口,指定排序规则(自然排序)。
- 通过CompareTo方法确定是否为重复元素。
- 线程不安全
必须实现:
用匿名内部类在构造TreeSet的时候放一个Comparator
或者
用需要排序的类去实现Comparable
注:两个都实现时,Comparator优先级要高
/**
* 向TreeSet集合中加入5个员工的对象,根据员工的年龄(升序)进行排序,
* 若年龄相同,再根据工龄(降序)来排序,若工龄相同,根据薪水(降序)排序
*/
public static void main(String[] args) {
// 第一种排序方法,Comparator
TreeSet<Staff> workers = new TreeSet<>(new Comparator<Staff>() {
public int compare(Staff o1, Staff o2) {
if (o1.age!=o2.age) {// 升序
return o1.age-o2.age;
}else if (o1.ageOfWork!=o2.ageOfWork) {// 降序
return o2.ageOfWork-o1.ageOfWork;
}else if (o1.wages!=o2.wages) {// 降序
return o2.wages-o1.wages;
}
return o1.hashCode()-o2.hashCode();
}
});
// 添加
workers.add(new Staff("zhang3", 20, 1, 3000));
workers.add(new Staff("li4", 20, 2, 3000));
workers.add(new Staff("wang5", 20, 1, 4000));
workers.add(new Staff("zhao6", 30, 5, 3000));
workers.add(new Staff("zhang3s", 30, 5, 6000));
// 遍历
for (Staff staff : workers) {
System.out.println(staff);
}
}
class Staff implements Comparator<Staff>{ // 第二种
String name;
int age;
int ageOfWork;
int wages;
public Staff(String name, int age, int ageOfWork, int wages) {
super();
this.name = name;
this.age = age;
this.ageOfWork = ageOfWork;
this.wages = wages;
}
@Override
public String toString() {
return "[name=" + name + ", age=" + age + ", ageOfWork=" + ageOfWork + ", wages=" + wages + "]";
}
// Comparator接口实现
public int compare(Staff o1, Staff o2) {
if (o1.age!=o2.age) {// 升序
return o1.age-o2.age;
}else if (o1.ageOfWork!=o2.ageOfWork) {// 降序
return o2.ageOfWork-o1.ageOfWork;
}else if (o1.wages!=o2.wages) {// 降序
return o2.wages-o1.wages;
}
return o1.hashCode()-o2.hashCode();
}
}
四、Map
4.1HashMap
- JDK1.2版本,线程不安全,运行效率快。
- 允许用null 作为key或是value。
- 存储结构:哈希表。
- 存key+value,key去重,无序
public class TestMap {
public static void main(String[] args) {
HashMap<String,String> countries = new HashMap<String,String>();
countries.put("CN", "CHINA");
countries.put("US", "AMERICA");
countries.put("RU", "RUSSIA");
countries.put("JP", "JAPAN");
countries.put("FR", "FRANCE");
// 遍历 foreach
// 1.循环键
for (String k : countries.keySet()) {
System.out.println(k +"--"+countries.get(k));
}
// 2.循环值
for (String v : countries.values()) {
System.out.println(v);
}
// 3.循环键值对
Set<Entry<String,String>> entrySet = countries.entrySet();
for (Entry<String,String> kv : entrySet) {
System.out.println(kv.getKey()+"--"+kv.getValue());
}
}
}
4.2Hashtable
JDK1.0版本,线程安全,运行效率慢;不允许null作为key或是value。
弃用,存key+value,key去重,无序,线程安全,方法加锁-效率低
4.3LinkedHashMap
概念:
HashMap是哈希表结构,可以保证键的唯一性,并不保证有序性,而LinkedHashMap是Map接口的哈希表和链表实现,具有可预知的迭代顺序。哈希表保证键的唯一性、链表保证键的有序(进出一致)
存key+value,key去重,有序,线程不安全
public class TestLinkedHashMap {
public static void main(String[] args) {
HashMap<Student,String> hmap = new HashMap<Student,String>();
// 乱序(对HashMap来说不是乱序,它有自己的算法)
hmap.put(new Student("zhang3", 10, 40), "A");
hmap.put(new Student("li4", 20, 30), "B");
hmap.put(new Student("wang5", 30, 20), "C");
hmap.put(new Student("zhao6", 40, 10), "D");
for (Student k : hmap.keySet()) {
System.out.println(k +"--"+hmap.get(k));
}
System.out.println("------------");
// 链表 值进出一致
LinkedHashMap<Student, String> map = new LinkedHashMap<Student,String>();
map.put(new Student("zhang3", 10, 40), "A");
map.put(new Student("li4", 20, 30), "B");
map.put(new Student("wang5", 30, 20), "C");
map.put(new Student("zhao6", 40, 10), "D");
for (Student k : map.keySet()) {
System.out.println(k +"--"+map.get(k));
}
}
}
运行结果:
Student [name=wang5, age=30, salary=20]--C
Student [name=zhang3, age=10, salary=40]--A
Student [name=li4, age=20, salary=30]--B
Student [name=zhao6, age=40, salary=10]--D
------------
Student [name=zhang3, age=10, salary=40]--A
Student [name=li4, age=20, salary=30]--B
Student [name=wang5, age=30, salary=20]--C
Student [name=zhao6, age=40, salary=10]--D
4.4TreeMap
实现了SortedMap接口(Map的子接口),可以对key自动排序,Key需实现Comparable接口。
排序,线程不安全
public class TestTreeMap {
public static void main(String[] args) {
TreeMap<Student,String> map = new TreeMap<Student,String>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
// 按salary升序
return o1.salary-o2.salary;
}
});
map.put(new Student("zhang3", 10, 40), "A");
map.put(new Student("li4", 20, 30), "B");
map.put(new Student("wang5", 30, 20), "C");
map.put(new Student("zhao6", 40, 10), "D");
System.out.println(map);
}
}
4.5Properties
Hashtable的子类,要求key和value都是String。通常用于配置文件的读取。
public class TestProp {
public static void main(String[] args) {
// 操作文件
Properties prop = new Properties();
InputStream is = TestProp.class.getClassLoader().getResourceAsStream("db.properties");//填写文件
try {
prop.load(is);
System.out.println(prop.getProperty("username"));
System.out.println(prop.getProperty("password"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
五、泛型
5.1 概念
概念:
- Java泛型是JDK1.5中引入的一个新特性,其本质是参数化类型,把类型作为参数传递。
- 常见形式有泛型类、泛型接口、泛型方法。
语法:
- <T,…> T称为类型占位符,表示一种引用类型。
泛型限定:
?表示什么类型都可以
? extends A 表示元素必须是A类或A的子类
? super A 表示元素必须是A类或A的父类
优点:
- 提高代码的重用性。
- 防止类型转换异常,提高代码的安全性。
5.2 泛型集合
- 参数化类型、类型安全的集合,强制集合元素的类型必须一致。
- 特点:
- 编译时即可检查,而非运行时抛出异常。
- 访问时,不必类型转换(拆箱)。
- 不同泛型之间引用不能相互赋值,泛型不存在多态。
六、Collections工具类
集合工具类,定义了除了存取以外的集合常用方法。
方法 | 描述 |
---|---|
public static void reverse(List<?> list) | 反转集合中元素的顺序 |
public static void shuffle(List<?> list) | 随机重置集合元素的顺序 |
public static void sort(List list) / | 升序排序(元素类型必须实现Comparable接口) |
public static int binarySearch( list, T key) | 二分查找 |
//Collections工具类
List<Integer> list = new ArrayList<>();
// 批量添加
Collections.addAll(list, 1,4,2,6,3,5 );
System.out.println(list);// [1, 4, 2, 6, 3, 5]
// 第一种sort()排序 (默认的)
Collections.sort(list); // 默认正序
System.out.println(list); // [1, 2, 3, 4, 5, 6]
// 第二种sort() (自定义排序)
Collections.sort(list, new Comparator<Integer>() {
public int compare(Integer o1, Integer o2) {
return o2-o1; // 降序 (自定义)
}
});
System.out.println(list); // [6, 5, 4, 3, 2, 1]