1.Collection接口
2. List接口
2.1 ArrayList
2.1.1 常用方法
增add
删remove
改set
查get
package com.qfedu.test2;
import java.util.ArrayList;
/**
* Collection
* List
* ArrayList
*
* 增add
* 删remove
* 改set
* 查get
* @author WHD
*
*/
public class TestArraysList1 {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add(20);
list.add('A');
list.add("abc");
list.add("中国");
System.out.println(list.size());
System.out.println(list.remove(0));
System.out.println(list.size());
System.out.println(list.set(0, "a"));
System.out.println(list.get(0));
System.out.println(list.isEmpty());
list.clear();
System.out.println(list.isEmpty());
System.out.println(list.size());
}
}
package com.qfedu.test3;
import java.util.ArrayList;
/**
* 泛型 :用于规定集合中的数据类型
* @author WHD
*
*/
public class TestArrayList1 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>(); // ctrl + shift + o
list.add("abc");
// list.add(20); 类型不匹配
list.add("hello");
ArrayList<Integer> list1 = new ArrayList<Integer>();
ArrayList<Boolean> list2 = new ArrayList<Boolean>();
}
}
2.1.2 遍历
三种方式:
1.普通for循环遍历
2.迭代器遍历
3.增强for循环遍历
package com.qfedu.test3;
import java.util.ArrayList;
import java.util.Iterator;
/**
* 集合的遍历
* 三种方式:
* 1.普通for循环遍历
* 2.迭代器遍历
* 3.增强for循环遍历
* @author WHD
*
*/
public class TestArrayList2 {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(20);
list.add(21);
list.add(22);
list.add(23);
list.add(24);
// 方式1 普通for循环遍历
for(int i = 0;i < list.size();i++) {
System.out.println(list.get(i));
}
System.out.println("-------------------------------");
// 方式2 迭代器遍历
Iterator<Integer> it1 = list.iterator();
while(it1.hasNext()) {
System.out.println(it1.next());
}
System.out.println("-------------------------------");
// 方式3 增强for循环 底层实现依然是迭代器 是JDK1.5的新写法
for(Integer i :list) {
System.out.println(i);
}
System.out.println("-------------------------------");
int [] nums = {1,2,3,4,5};
for(int num : nums) {
System.out.println(num);
}
}
}
2.1.3 底层实现
ArrayList特点:
有序,可以重复,可以为null,线程不安全
底层实现是一个Object类型的数组
当我们调用无参构造方法,底层维护一个空数组,当我们第一次添加元素,将数组的长度改为10
扩容为原数组的1.5倍
查询,修改快,因为有下标
增加慢,因为需要扩容
删除慢,因为需要移动元素
2.2 Vector
Vector类 和ArrayList的区别?
Vector是线程安全的 JDK1.0
ArrayList线程不安全 JDK1.2
Vector调用无参构造直接初始化一个长度为10的数组
ArrayList调用无参构造初始化一个空数组
ArrayList扩容1.5倍
Vector扩容两倍
package com.qfedu.test5;
import java.util.Vector;
/**
* Vector类 和ArrayList的区别?
* Vector是线程安全的 JDK1.0
* ArrayList线程不安全 JDK1.2
* Vector调用无参构造直接初始化一个长度为10的数组
* ArrayList调用无参构造初始化一个空数组
* ArrayList扩容1.5倍
* Vector扩容两倍
*
* @author WHD
*
*/
public class TestVector {
public static void main(String[] args) {
Vector<Double> v1 = new Vector<Double>();
v1.add(2.2);
v1.add(2.3);
v1.add(2.5);
v1.add(20.1);
System.out.println(v1.size());
System.out.println(v1.remove(0));
v1.set(0, 220.2);
System.out.println(v1.get(0));
System.out.println(v1.isEmpty());
v1.clear();
System.out.println(v1.isEmpty());
// 遍历方法 和ArrayLis相同 有三种
}
}
2.3 LinkedList
2.3.1 常用方法
LinkedList 基于双向链表实现的集合
除了与ArrayList相同的增删改查方法以外
还单独提供了用于操作头部和尾部的方法
package com.qfedu.test6;
import java.util.LinkedList;
/**
* LinkedList 基于双向链表实现的集合
* 除了与ArrayList相同的增删改查方法以外
* 还单独提供了用于操作头部和尾部的方法
* @author WHD
*
*/
public class TestLinkedList {
public static void main(String[] args) {
LinkedList<String> list = new LinkedList<String>();
list.add("a");
list.add("b");
list.addFirst("hello");
list.addFirst("C");
list.addLast("xyz");
System.out.println(list.size());
System.out.println(list.getFirst());
System.out.println(list.getLast());
System.out.println(list.get(2));
System.out.println(list.remove(0));
System.out.println(list.set(0, "HELLO"));
System.out.println(list.removeFirst());
System.out.println(list.removeLast());
list.clear();
System.out.println(list.isEmpty());
}
}
2.3.2 遍历
LinkedList三种遍历方式
1.普通for循环
2.迭代器
3.增强for循环
package com.qfedu.test6;
import java.util.Iterator;
import java.util.LinkedList;
/**
* LinkedList三种遍历方式
* 1.普通for循环
* 2.迭代器
* 3.增强for循环
* @author WHD
*
*/
public class TestLinkedList1 {
public static void main(String[] args) {
LinkedList<Integer> list = new LinkedList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
// 方式1
for(int i = 0;i < list.size();i++) {
System.out.println(list.get(i));
}
System.out.println("-----------------------------");
// 方式2
Iterator<Integer> it = list.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
System.out.println("-----------------------------");
// 方式3
for(Integer i : list) {
System.out.println(i);
}
}
}
2.3.3 底层实现
LinkedList特点:
有序的,允许重复,允许为null,线程不安全
根据下标查询,修改慢,因为不能直接查询到某个元素,必须先查询到相邻元素
增加和删除快,因为不需要扩容,不需要移动元素
get()方法优化:当我们根据下标查找LinkedList元素的时候
先对下标进行判断,如果下标是小于集合总长度中间值的 ,从前往后查询
否则,从后往前找
鉴于LinkedList数据结构特点,不要使用普通for循环遍历
3. Collections
针对集合提供的工具类
常用方法:
sort() 排序
binarySearch() 二分查找
max() 最大值
min() 最小值
reverse() 反转
shuffle() 乱序
3.1 排序
List<Integer> list = new ArrayList<Integer>();
list.add(10);
list.add(12);
list.add(6);
list.add(8);
list.add(30);
list.add(23);
// 排序
Collections.sort(list);
System.out.println(list);
// 第二个参数 比较器(两种方式:1 自定义类实现Comparator接口, 2匿名内部类)
Collections.sort(list, new MyComparator());
System.out.println(list);
// 匿名内部类,
// 针对接口、抽象类,不需要实现类
// new 接口名/抽象类名(){ 重写的方法 }
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
// TODO Auto-generated method stub
return o2 - o1;
}});
System.out.println(list);
3.2自定义类排序
List<Student> stuList = new ArrayList<Student>();
Student s1 = new Student(10, "zhangsan", 20);
Student s2 = new Student(9, "lisi", 10);
Student s3 = new Student(45, "lisiw", 25);
Student s4 = new Student(23, "gousheng", 12);
Student s5 = new Student(26, "liuneng", 40);
stuList.add(s1);
stuList.add(s2);
stuList.add(s3);
stuList.add(s4);
stuList.add(s5);
Collections.sort(stuList, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
// TODO Auto-generated method stub
return o1.getAge() - o2.getAge();
}
});
// System.out.println(stuList);
for(Student stu : stuList) {
System.out.println(stu);
}
System.out.println("---------------------------------");
Collections.sort(stuList, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
// TODO Auto-generated method stub
// 字符串中compareTo,比较字符串大小,比如s1, s2, 如果s1大于s2,返回1;s1等于s2,返回0;s1小于s2,返回-1
return o1.getName().compareTo(o2.getName());
}
});
for(Student stu : stuList) {
System.out.println(stu);
}
3.3 二分查找
List<Integer> list = new ArrayList<Integer>();
list.add(10);
list.add(12);
list.add(6);
list.add(8);
list.add(23);
// 6 8 10 12 23
Collections.sort(list);
System.out.println(list);
// 二分查找 针对有序的集合
int index = Collections.binarySearch(list, 12);
System.out.println(index);
3.4 其他
List<Integer> list = new ArrayList<Integer>();
list.add(10);
list.add(12);
list.add(6);
list.add(8);
list.add(23);
// 找最大值
Integer max = Collections.max(list);
System.out.println(max);
// 乱序
Collections.shuffle(list);
System.out.println(list);
// 反转
Collections.reverse(list);
System.out.println(list);
4. Map接口
4.1 HashMap
4.1.1 常用方法
put()
remove()
get()
size()
clear()
replace()
package com.qfedu.test1;
import java.util.HashMap;
/**
* Map
* HashMap
*
* put()
* remove()
* get()
* size()
* clear()
* replace()
* @author WHD
*
*/
public class TestHashMap {
public static void main(String[] args) {
HashMap<String,String> map = new HashMap<String,String>();
map.put("CN", "中国");
map.put("US", "美国");
map.put("RU", "俄罗斯");
map.put("KR", "棒子");
map.put("JP", "小日本");
System.out.println(map.size());
map.replace("JP", "鬼子");
System.out.println(map.get("JP"));
System.out.println("删除了:" + map.remove("JP"));
System.out.println(map.size());
map.clear();
System.out.println(map.isEmpty());
}
}
4.1.2 遍历
1.获取所有的键
2.获取所有的值
3.获取所有的键和值的组合
4.获取所有键的迭代器
5.获取所有值的迭代器
6.获取所有的键和值的组合的迭代器
package com.qfedu.test1;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;
/**
* HashMap集合遍历
*
* 1.获取所有的键
* 2.获取所有的值
* 3.获取所有的键和值的组合
*
* 4.获取所有键的迭代器
* 5.获取所有值的迭代器
* 6.获取所有的键和值的组合的迭代器
* @author WHD
*
*/
public class TestHashMap1 {
public static void main(String[] args) {
HashMap<String,String> map = new HashMap<String,String>();
map.put("CN", "中国");
map.put("US", "美国");
map.put("RU", "俄罗斯");
map.put("KR", "棒子");
map.put("JP", "小日本");
// 方式 1
Set<String> keySet = map.keySet();
for(String key : keySet) {
System.out.println(key + "====" + map.get(key));
}
System.out.println("-------------------------------------");
// 方式2
Collection<String> values = map.values();
for(String v : values) {
System.out.println(v);
}
System.out.println("-------------------------------------");
// 方式3
Set<Entry<String, String>> entrySet = map.entrySet();
for(Entry<String,String> entry : entrySet) {
System.out.println(entry.getKey() + "===" + entry.getValue());
}
System.out.println("-------------------------------------");
// 方式4
Iterator<String> it1 = map.keySet().iterator();
while(it1.hasNext()) {
String key = it1.next();
System.out.println(key + "====" +map.get(key));
}
System.out.println("-------------------------------------");
// 方式5
Iterator<String> it2 = map.values().iterator();
while(it2.hasNext()) {
System.out.println(it2.next());
}
System.out.println("-------------------------------------");
// 方式6
Iterator<Entry<String, String>> it3 = map.entrySet().iterator();
while(it3.hasNext()) {
Entry<String,String> entry = it3.next();
System.out.println(entry.getKey() + "===" + entry.getValue());
// System.out.println(it3.next());
}
}
}
4.1.3 数据结构
回顾之前所学习的数据结构
ArrayList:数组 因为有下标 所以查询快 修改快 删除、增加慢
LinkedList:双向链表 因为没有下标 (有序,有序号) 所以 删除、增加快 ,查询快 修改慢
HashMap数据结构:
JDK1.7 数组 + 单向链表
JDK1.8 数组 + 单向链表 + 红黑树
HashMap存放元素过程:根据key所计算出来的hash值,决定当前元素在数组的位置,
如果当前位置没有元素,则直接存放
如果当前位置有元素,则向下延伸为单向链表,如果单向链表的长度超过8,将转换为红黑树
后续链表以后的元素减少到6以下,再将红黑树转换为单向链表
扩容当数组的使用率达到75% 并且集合中的元素个数大于64 扩容2倍
4.2 Hashtable
HashMap 与Hashtable区别?
Hashtable线程安全 初始数组长度11 扩容2倍 + 1
HashMap线程不安全 初始数组长度16 扩容2倍
4.3 泛型
泛型:用于规范集合,或者接口,类中的数据类型
泛型书写位置:
类
接口上
形参
返回值
泛型通用的字母:
T Type 类型
E Element 元素
R Return 返回值
P Parameter 参数
K Key 键
V Value 值
package com.qfedu.test4;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
/**
* 泛型:用于规范集合,或者接口,类中的数据类型
*
* 泛型书写位置:
* 类
* 接口上
* 形参
* 返回值
*
* 泛型通用的字母:
* T Type 类型
* E Element 元素
* R Return 返回值
* P Parameter 参数
* K Key 键
* V Value 值
* @author WHD
*
*/
public class Test1 {
public static void main(String[] args) {
A<String> a = new A<String>();
a.m1("abc");
a.m2();
A<Integer> a1 = new A<Integer>();
a1.m1(20);
a1.m2();
A<Boolean> a2 = new A<Boolean>();
a2.m1(false);
a2.m2();
B1 b1 = new B1();
b1.m1("a");
B2 b2 = new B2();
b2.m1(3.14F);
}
}
class Pet{}
class Dog extends Pet{}
class Penguin extends Pet{}
class TestPet{
public static void m1(List<? extends Pet> list) {
}
public static void m2(Set<? super Dog> set) {
}
public static void main(String[] args) {
ArrayList<Dog> list1 = new ArrayList<Dog>();
ArrayList<Penguin> list2 = new ArrayList<Penguin>();
LinkedList<Pet> list3 = new LinkedList<Pet>();
m1(list1);
m1(list2);
m1(list3);
Set<Dog> set1 = new HashSet<Dog>();
Set<Pet> set2 = new HashSet<Pet>();
m2(set1);
m2(set2);
}
}
interface C<P,R>{
R m1(P p);
}
class C1 implements C<String,Integer>{
@Override
public Integer m1(String p) {
return null;
}
}
class C2 implements C<Double,Character>{
@Override
public Character m1(Double p) {
return null;
}
}
class A<T>{
void m1(T t) {
System.out.println(t);
}
T m2() {
return null;
}
public static <T> void m3(T t) {
List<T> list = new ArrayList<T>();
}
}
interface B<E>{
E m1(E e);
}
class B1 implements B<String>{
@Override
public String m1(String e) {
return null;
}
}
class B2 implements B<Float>{
@Override
public Float m1(Float e) {
return null;
}
}
5. Set
5.1 HashSet 重点
无序 元素唯一
常用方法: add
remove
循环遍历
public class App {
public static void main(String[] args) {
// TODO Auto-generated method stub
HashSet<String> hashSet = new HashSet<String>();
hashSet.add("nvwangjie");
hashSet.add("xiannvjie");
hashSet.add("xiannvjie");
hashSet.add("nvshenjie");
hashSet.add("laodongjie");
hashSet.add("chunjie");
// 增加的for循环
for(String s : hashSet) {
System.out.println(s);
}
// 迭代器
Iterator<String> iterator = hashSet.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
向set中添加数据时,如何判断两个对象是否相同(笔试、面试中)
- 先判断hashCode(), 如果hashCode()返回的值一样,再判断equals()
public class App2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
HashSet<Student> stuSet = new HashSet<Student>();
Student s1 = new Student(1, "gousheng", 20);
Student s2 = new Student(2, "wangcai", 10);
Student s4 = new Student(2, "wangcai", 10);
Student s3 = new Student(3, "fugui", 20);
stuSet.add(s1);
stuSet.add(s2);
stuSet.add(s3);
stuSet.add(s4);
for(Student s : stuSet) {
System.out.println(s.getName() + "-" + s.getAge());
}
}
}
public class Student {
private int id;
private String name;
private int age;
public Student() {
}
public Student(int id, String name, int age) {
super();
this.id = id;
this.name = name;
this.age = age;
}
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 getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int hashCode() {
// TODO Auto-generated method stub
return this.name.hashCode();
}
@Override
public boolean equals(Object obj) {
// TODO Auto-generated method stub
Student s = (Student)obj;
return this.name.equals(s.getName());
}
}
5.2 TreeSet 知道
内部进行排序、 元素唯一
红黑树
public class App3 {
public static void main(String[] args) {
// TODO Auto-generated method stub
TreeSet<Integer> treeSet = new TreeSet<Integer>();
treeSet.add(10);
treeSet.add(20);
treeSet.add(5);
treeSet.add(12);
treeSet.add(8);
for(Integer i : treeSet) {
System.out.println(i);
}
}
}
内部类
针对接口、抽象类,不需要实现类
语法格式:new 接口名/抽象类名(){ 重写的方法 }
使用参考排序的代码