文章目录
- 6、集合
- 6.1 介绍
- 6.2 常用接口和类
- 6.3 ArrayList
- 6.3.1 介绍
- 6.3.2 基本操作
- 6.3.3 常用方法
- 6.4 LinkedList
- 6.4.1 基本操作
- 6.4.2 常用方法
- 6.5 泛型
- 6.5.1 介绍
- 6.5.2 基本使用
- 6.6 比较器
- 6.7 ArrayList和LinkedList的比较
- 6.8 HashSet
- 6.8.1 介绍
- 6.8.2 常用方法
- 6.8.3 重复数据
- 6.9 Queue
- 6.10 HashMap
- 6.10.1 介绍
- 6.10.2 常用方法
- 6.11 Hashtable
- 6.12 迭代器
- 6.13 工具类
- 6.14问题汇总
Java零基础极速入门-讲师:海波
失败,是正因你在距成功一步之遥的时候停住了脚步。
6、集合
6.1 介绍
public class Demo {
public static void main(String[] args) {
//集合
// 生活中集合,是一个动词
// Java中集合是一个名词,数据的一种容器,用于容纳数据
// Java提供了完整的集合框架
// 问题1:什么时候需要一个容纳数据的容器,也就是集合对象。
// 当容纳数据个数不确定,Java集合框架就包含了对不确定个数的数据处理的集合类
// 问题2:如果只是为了容纳数据,可以是直接使用数组,为什么要学习集合。
// 数组使用起来不方便,在数据不确定的场合,数组使用起来很不方便
// 总结:不确定有关系的数据,进行相同的逻辑处理的场合,使用集合是一个不错的选择
// 根据数据的不同,Java的集合分为两大体系
// 1.单一数据体系 :Collection接口定义了相关规则
// 2.成对出现的数据体系:Map接口定义了相关规则
// 承兑的数据:两个数据有关系,可以根据第一个数据关联第二个数据(键值对数据)
}
6.2 常用接口和类
public class Demo {
public static void main(String[] args) {
//集合
// 1.Collection接口
// 常用子接口
// List:按照插入顺序保存数据
// 具体实现类:ArrayList、LinkedList
// Set:集,无需保存,数据不能重复
// 具体实现类:HashSet
// Queue:队列(有头有尾)
// 具体实现类:ArrayBlockingQueue
// 2.Map接口
// 常用子接口
// HashMap:
//Hashtable:
}
}
6.3 ArrayList
6.3.1 介绍
//集合
// 1.Collection接口-List
// ArrayList:Array + List(使用数组实现存储的容器对象)
// List:列表、清单(按照插入顺序存储)
// Array:数组、阵列
6.3.2 基本操作
public class Demo {
public static void main(String[] args) {
// 创建集合对象:ArrayList
ArrayList list = new ArrayList();
// 1.不需要传递构造参数,直接new就可以(默认底层数组为空数组)
// 2.构造参数需要传递一个int类型的值,用于设定底层数组的长度
// 3.构造参数需要传递一个Collection集合类型的值,用于将其他集合中的数据放置在当前集合中
// 增加数据:添加数据时,如果集合中没有数据,默认创建长度为10的数组
list.add("张三");
// 增加数据:增加第二条数据不会再增加数组长度
list.add("李四");
// 扩容:当添加数据长度超过10,会创建一个新数组,比旧数组容量大,将旧数组数据复制到新数组,旧数组不再使用
// 访问数据
// 获取集合中数据数量
System.out.println(list.size());
// 获取指定位置数据
System.out.println(list.get(0));
// 遍历集合中的数据
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
// foreach(快捷键:list.iter)
for (Object o : list) {
System.out.println(o);
}
// 修改数据:将指定位置的数据修改
// 参数1:修改的位置
// 参数2:修改的值
// 方法会返回结果,结果就是更新前的值
Object old = list.set(1, "王五");
System.out.println(old);
// 删除数据:将指定位置的数据删除
// 参数1:删除的位置
// 方法会返回结果,结果就是删除的值
Object remove = list.remove(1);
System.out.println(remove);
// 打印集合对象
System.out.println(list);
}
}
6.3.3 常用方法
public class Demo {
public static void main(String[] args) {
// ArrayList的常用方法
// 创建集合对象:ArrayList
ArrayList list = new ArrayList();
list.add("张三");
list.add("李四");
list.add("王五");
// add():新增加的数据插入到数组指定位置,后面的数据全部后移一位,如果数组空间不足,需要创建新数组
// 参数1:增加位置的索引
// 参数2:数据
list.add(1,"赵六");
// addAll():追加其他集合中的数据
ArrayList list1 = new ArrayList();
list1.add(1);
list1.add(2);
list1.add(3);
list.addAll(list1);
// size():集合中数据的数量
System.out.println(list.size());
// clear():清空集合中数据
list.clear();
// removeAll():删除指定集合中数据
// 参数1:集合对象
list.removeAll(list1);
// contains():判断集合中是否包含某条数据,返回布尔类型值
list.contains("张三");
// indexOf():获取数据在索引中第一次出现位置(获取不存在数据返回-1,当两个相同数据,返回数据第一个位置索引)
// 参数1:需要查询字符串
list.indexOf("张三");
// lastIndexOf():获取数据在索引中位置最后出现的位置
list.lastIndexOf("张三");
// isEmpty():集合中数据是否为空
System.out.println(list.isEmpty());
// 将集合转换成数组
list.toArray();
// 克隆集合对象
ArrayList list2 = (ArrayList)list.clone();
// 打印结果
System.out.println(list);
}
}
6.4 LinkedList
6.4.1 基本操作
public class Demo {
public static void main(String[] args) {
// LinkedList:Linked(连接)+ List(集合)
// 构建集合对象
LinkedList list = new LinkedList();
// 增加一个数据
list.add("zhangsan");
// 增加数据到首位
list.addFirst("list");
// 增加数据到指定位置
list.add(1,"wangwu");
// 获取首位数据
System.out.println(list.getFirst());
// 获取末位数据
System.out.println(list.getLast());
// 获取全部数据
System.out.println(list);
// 根据索引获取数据
System.out.println(list.get(1));
// 遍历数据
for (Object o : list) {
System.out.println(o);
}
// 修改数据
list.set(1,"zhaoliu");
// 获取全部数据
System.out.println(list);
// 删除
System.out.println(list.remove("zhangsan"));
// 获取全部数据
System.out.println(list);
}
}
6.4.2 常用方法
public class Demo {
public static void main(String[] args) {
// LinkedList:Linked(连接)+ List(集合)
// 构建集合对象
LinkedList list = new LinkedList();
list.add("zhangsan");
list.add("lisi");
list.add("wangwu");
// 常用方法
//list.add(1,"lisi"); 指定位置增加
//list.addFirst("lisi"); 开头增加
//list.addLast("lisi"); 结尾增加
//list.addAll(); 拷贝其他集合中的数据
//list.remove("lisi"); 删除指定数据
//list.remove(); 删除第一个
// list.removeFirst(); 删除第一个
// list.removeLast(); 删除最后一个
// list.remove(1); 删除指定下标
// list.size(); 集合长度
// list.isEmpty(); 是否为空
// list.clear(); 清空数据
// list.contains("list"); 是否包含
// list.element(); //获取第一个数据
// list.indexOf("lisi"); 获取数据所在位置
// list.lastIndexOf("lisi"); 返回元素最后一次出现的位置
// list.push("aa");// 添加数据到首位
// list.pop();// 弹出数据,弹出后数据在集合中就消失了
System.out.println(list);
}
}
6.5 泛型
6.5.1 介绍
public class Demo {
public static void main(String[] args) {
// 集合 Collection
// 泛型语法:在集合处理时,简化数据类型的判断,以及进行类型的转换
ArrayList<User> list = new ArrayList<>();
// 指定集合中只可以储存User对象,不可以存别的对象
list.add(new User());
// 从集合中获取只能是User
User user = list.get(0);
}
}
class User{
}
6.5.2 基本使用
public class Demo {
public static void main(String[] args) {
// 泛型语法
// 有时,泛型也称之为参数类型
MyContainer<User> myContainer = new MyContainer<>();
test(myContainer);
// 1.类型存在多态的使用
// 2.泛型没有多态
}
public static void test(MyContainer<User> myContainer) {
System.out.println(myContainer);
}
}
// 容器类
class MyContainer<C> {
public C data;
}
class User {
}
6.6 比较器
public class Demo {
public static void main(String[] args) {
// 比较器
// Sort 排序
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(3);
list.add(4);
list.add(2);
// 排序需要传递一个实现了比较器接口的对象
list.sort(new NumberComparater());
System.out.println(list);
}
}
//实现了比较器接口的对象
class NumberComparater implements Comparator<Integer>{
@Override
public int compare(Integer o1, Integer o2) {
// o1 > o2 返回正数,升序
//return o1 - o2;
// o1 < o2 返回负数,降序
return o2 - o1;
// o1 = o2 返回0,顺序不发生改变
//return 0;
}
}
6.7 ArrayList和LinkedList的比较
public class Demo {
public static void main(String[] args) {
// 集合数据容量没有达到数组阈值场景,追加数据ArrayList快
// 向集合的指定位置插入数据,或集合数据容量不够的场景,LinkedList快
// 根据索引查询数据,ArrayList快
// 线性查询数据,两个集合没有本质区别
// 线性查询:一个一个查询
}
}
6.8 HashSet
6.8.1 介绍
数据A存储到HashSet,首先通过HASH算法,得到存储位置,将数据放入,取数据通过数组下表顺序取出。
HashSet的数据是无序排列。
可以向HashSet中放入重复数据,但是重复数据存储位置相同,导致存储数据不会重复。
public class Demo {
public static void main(String[] args) {
// HashSet: Hash + Set
// Hash:哈希算法,散列算法
// 基本操作
HashSet<String> set = new HashSet<>();
// 增加数据
set.add("zhangsan");
set.add("zhangsan");
set.add("lisi");
set.add("wangwu");
// 打印
System.out.println(set);
// HashSet没有修改方法,想修改只能先删除,在添加
// 删除
set.remove("wangwu");
System.out.println(set);
// 查询数据
for (String s : set) {
System.out.println(s);
}
}
}
6.8.2 常用方法
public class Demo {
public static void main(String[] args) {
// 常用方法
HashSet<String> set = new HashSet<>();
// ArrayList数据
ArrayList<String> list = new ArrayList<>();
list.add("zhangsan");
list.add("lisi");
list.add("wangwu");
// 导入其他集合数据
set.addAll(list);
// 将HashSet变成数组
Object[] toArray = set.toArray();
// 是否为空
set.isEmpty();
// 集合清空
set.clear();
// 是否包含某个数据
set.contains("zhangsan");
// 获取集合长度
set.size();
// 复制一个新的集合随想
set.clone();
}
}
6.8.3 重复数据
HashSet判断对象数据重复,先获取对象HashCode值,通过HASH算法,算出存放位置,如果两个对象存放位置相同,但内容不同,两个对象存放在同一个位置,使用链表链接。
public class Demo {
public static void main(String[] args) {
// 重复判断
HashSet<User> set = new HashSet<>();
User user1 = new User();
user1.id = 1;
user1.name = "zhangsan";
User user2 = new User();
user2.id = 1;
user2.name = "lisi";
User user3 = new User();
user3.id = 3;
user3.name = "wangwu";
set.add(user1);
set.add(user2);
set.add(user3);
System.out.println(set);
}
}
class User {
public int id;
public String name;
// 从写hashCode,按照用户自定义的标志位做对象区分
@Override
public int hashCode() {
return id;
}
// 重写equeals,按照用户自定义规则比较对象内容
@Override
public boolean equals(Object obj) {
if (obj instanceof User) {
User user = (User) obj;
if (user.id == this.id) {
if (user.name == this.name) {
return true;
}
}
return false;
} else {
return false;
}
}
// 重写toString方便打印对象内容
@Override
public String toString() {
return "User[" + id + "," + name + "]";
}
}
6.9 Queue
public class Demo {
public static void main(String[] args) throws InterruptedException {
// Queue:排队
// ArrayBlockingQueue Array:数组 Blocking:阻塞,堵住 Queue
ArrayBlockingQueue queue = new ArrayBlockingQueue(3);
// 添加-add():当数据增加超过数组设定容量,会直接报错Queue full
//queue.add("zhangsan");
//queue.add("lisi");
//queue.add("wangwu");
//queue.add("zhaoliu");
// 添加-put():当数据增加超过数组设定容量,程序会阻塞
//queue.put("zhangsan");
//queue.put("lisi");
//queue.put("wangwu");
//queue.put("zhaoliu");
// 添加-put():数据添加成功,返回true,当数据增加超过数组设定容量,添加失败,返回false
boolean zhangsan = queue.offer("zhangsan");
System.out.println(zhangsan);
boolean lisi = queue.offer("lisi");
System.out.println(lisi);
boolean wangwu = queue.offer("wangwu");
System.out.println(wangwu);
boolean zhaoliu = queue.offer("zhaoliu");
System.out.println(zhaoliu);
// 取数据,当集合中没有数据,返回null
//System.out.println(queue.poll());
//System.out.println(queue.poll());
//System.out.println(queue.poll());
//System.out.println(queue.poll());
// 取数据,当集合中没有数据,阻塞等待添加数据
System.out.println(queue.take());
System.out.println(queue.take());
System.out.println(queue.take());
System.out.println(queue.take());
}
}
6.10 HashMap
6.10.1 介绍
HashMap存储数据,首先通过HASH算法,计算key(A)的存放位置,将(key,value)储存,有可能不相同的key存放相同位置,同位置使用单向链表链接,Java为了增强HashMap的查询速度,单向链表使用红黑树优化。
public class Demo {
public static void main(String[] args) throws InterruptedException {
// HashMap:Hash + Map
// 数据存储无序,且key不能重复
// 数据格式(key,value)
HashMap<Integer,String> map = new HashMap<>();
// 添加数据:put
map.put(1,"zhangsan");
// 修改数据,put方法也可以,返回值就是被修改的数据
System.out.println(map.put(1, "zhaoliu"));
map.put(2,"lisi");
map.put(3,"wangwu");
// 查询数据
System.out.println(map.get(1));
// 删除数据
map.remove(1);
// 打印所有数据
System.out.println(map);
}
}
6.10.2 常用方法
public class Demo {
public static void main(String[] args) throws InterruptedException {
// HashMap:Hash + Map
// 数据存储无序
HashMap<Integer,String> map = new HashMap<>();
// 添加数据:put
map.put(1,"zhangsan");
map.put(2,"lisi");
map.put(3,"wangwu");
// key不存在就添加,key存在,不添加
map.putIfAbsent(1,"Tom");
//修改数据,返回修改前的数据
System.out.println(map.replace(1, "Tom"));
// 清空clear
// map.clear();
// 获取map集合中所有的key
Set<Integer> set = map.keySet();
// 通过获取全部key遍历value,有true无false
for (Integer integer : set) {
System.out.println(map.get(integer));
}
// 判断当前map集合中有没有指定的key
System.out.println(map.containsKey(1));
// 获取全部value
Collection<String> values = map.values();
for (String value : values) {
System.out.println(value);
}
// 判断当前map集合中有没有指定的value
System.out.println(map.containsValue("Tom"));
// 打印map
System.out.println(map);
// 获取键值对对象
Set<Map.Entry<Integer, String>> entries = map.entrySet();
for (Map.Entry<Integer, String> entry : entries) {
System.out.println(entry.getKey() + ":" + entry.getValue());
}
// 删除一个键值对
map.remove(1);
System.out.println(map);
// 删除一个特定的键值对(只有键值对都相等才能删除)
map.remove(2,"lisi");
System.out.println(map);
}
}
6.11 Hashtable
public class Demo {
public static void main(String[] args) throws InterruptedException {
// Hashtable:Hash + table
Hashtable table = new Hashtable();
table.put(null,null);
HashMap map = new HashMap();
map.put(null,null);
// HashMap与Hashtable区别
// 1.实现方式不一样:继承父类不一样
// 2.底层结构容量不同:HashMap(16),Hashtable(11)
// 3.HashMap的K,V都可以为null,HashMap的K,V都不可以为null
// 4.HashMap的数据定位采用的是Hash算法,但是Hashtable采用的是hashcode
// 5.HashMap的性能较高(不支持多线程),Hashtable(支持多线程)的性能较低
}
}
6.12 迭代器
public class Demo {
public static void main(String[] args) throws InterruptedException {
// 当使用循环遍历时,对HashMap进行修改会报错。
// HashMap 创建 复制
HashMap<Integer, String> map = new HashMap<>();
map.put(1,"a");
map.put(2,"b");
map.put(3,"c");
// 获取所有key
Set<Integer> set = map.keySet();
// 迭代器
Iterator<Integer> iterator = set.iterator();
// hasNext():用来判断是否存在下一跳数据
while(iterator.hasNext()){
// 获取下一条数据
Integer next = iterator.next();
// 在取值的过程中删除数据,使用迭代器删除,这样就不报错了
if(2 == next){
//remove()方法只能删除当前数据,不能删除其他数据
iterator.remove();
}
System.out.println(map.get(next));
}
}
}
6.13 工具类
public class Demo {
public static void main(String[] args) throws InterruptedException {
// Arrays 集合工具类
int[] is = {2, 3, 1, 5, 4};
int[] is1 = {1, 2, 3, 4, 5};
// 将数组变成字符串
System.out.println(Arrays.toString(is));
// 将数组变成字符串
System.out.println(is);
// 获取list集合并赋值
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6);
// 排序(默认升序)
Arrays.sort(is);
System.out.println(Arrays.toString(is));
// 二分查找法(查询排序后的顺序的位置)
System.out.println(Arrays.binarySearch(is, 5));
// 数组的比较,比较数组内容是否相等(包括数组内顺序)
System.out.println(Arrays.equals(is, is1));
// 数组的比较,指定范围,比较数组内容是否相等(包括数组内顺序)
System.out.println(Arrays.equals(0,5, is,0,5is1));
}
}
6.14问题汇总
public class Demo {
public static void main(String[] args) throws Exception {
// 集合Exception
// 容量:当前的容量不能小于0
ArrayList list = new ArrayList(10);
list.add("a");
list.add("b");
list.add("c");
// 如果访问的集合是数组,那么索引范围就是0,到数组长度-1
// 如果访问的集合是List,那么索引范围就是0,到数据长度-1
System.out.println(list.get(2));
// NoSuchElementException
LinkedList linkedList = new LinkedList();
//System.out.println(linkedList.getFirst());
// 在遍历的过程中集合数据数量发生改变,就会发生错误,所以在循环的时候处理集合,一定要使用迭代器
HashMap map = new HashMap();
map.put("a", "1");
map.put("b", "2");
map.put("c", "3");
for (Object o : map.keySet()) {
if( "b".equals(o)){
map.remove(o);
}
System.out.println(map.get(o));
}
}
}