目录
一.集合概述
二.Collection集合体系的特点
package com.wjh.d1_collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
/*
目标:明确Collection集合体系的特点
*/
public class CollectionDemo1 {
public static void main(String[] args) {
//有序 可重复 有索引
ArrayList list = new ArrayList();
Collection list2 = new ArrayList(); //多态
list2.add("Java");
list2.add("Java");
list2.add("MyBatis");
list2.add(23);
list2.add(23);
list2.add(false);
list2.add(false);
System.out.println(list2);
//[Java, Java, MyBatis, 23, 23, false, false]
//无序 不重复 无索引
Collection list1 = new HashSet();
list1.add("Java");
list1.add("Java");
list1.add("MyBatis");
list1.add(23);
list1.add(23);
list1.add(false);
list1.add(false);
System.out.println(list1);
//[Java, false, 23, MyBatis]
}
}
[Java, Java, MyBatis, 23, 23, false, false]
[Java, false, 23, MyBatis]进程已结束,退出代码为 0
System.out.println("-----------------");
// 用泛型约束集合的类型,但是只能用引用类型
Collection<String> list3 = new ArrayList();
//JDK 7 开始之后后面的类型声明可以不写
list3.add("Java");
//list3.add(23);
list3.add("昨天");
//集合 泛型 不支持基本数据类型,只能用引用数据类型
System.out.println("-----------------");
// 用泛型约束集合的类型,但是只能用引用类型
Collection<String> list3 = new ArrayList();
//JDK 7 开始之后后面的类型声明可以不写
list3.add("Java");
//list3.add(23);
list3.add("昨天");
//集合 泛型 不支持基本数据类型,只能用引用数据类型
三.Collection集合常用API
package com.wjh.d2_collectionApi;
/*
-public Object[] toArray(); 把集合中的元素存储到数组中.
小结:
记住以上API
*/
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
public class CollectionApi {
public static void main(String[] args) {
//HashSet:添加的元素是无序 不重复 无索引
Collection<String> list =new ArrayList<>();
//1.添加元素 添加成功返回true
list.add("Java");
list.add("MySql");
list.add("HTML");
list.add("Java");
list.add("昨天");
System.out.println(list); //[Java, MySql, HTML, Java, 昨天]
//2.清空集合的元素
//list.clear(); // []
System.out.println(list);
//3.判断集合是否为空 是空返回true 反之亦然.
System.out.println(list.isEmpty());
//4.获取集合的大小
System.out.println(list.size());
//5.判断集合是否包含某个元素
list.contains("Java"); //true
list.contains("java"); //false : 精准匹配
list.contains("昨天"); //true
//6.删除某个元素:如果有多个元素默认删除前面的第一个元素
System.out.println(list.remove("java")); //false -> false原因:集合中没有 "java"元素
System.out.println(list);
System.out.println(list.remove("Java")); //true -> 只会删除第一个元素
System.out.println(list);
//7.把集合转换成数组[Java, 独孤求败, HTML, MyBatis]
Object[] arr = list.toArray(); //Object兼容一切数据
System.out.println("数组:" + Arrays.toString(arr));
System.out.println("------------拓展-----------------");
Collection<String> c1 =new ArrayList<>();
c1.add("Java1");
c1.add("Java2");
Collection<String> c2 =new ArrayList<>();
c2.add("公主");
c2.add("素素");
//addAll把c2集合的元素全部倒入到c1中去
c1.addAll(c2);
System.out.println(c1.addAll(c2)); //true
System.out.println(c1); //[Java1, Java2, 公主, 素素, 公主, 素素]
System.out.println(c2); //[公主, 素素]
}
}
[Java, MySql, HTML, Java, 昨天]
[Java, MySql, HTML, Java, 昨天]
false
5
false
[Java, MySql, HTML, Java, 昨天]
true
[MySql, HTML, Java, 昨天]
数组:[MySql, HTML, Java, 昨天]
------------拓展-----------------
true
[Java1, Java2, 公主, 素素, 公主, 素素]
[公主, 素素]进程已结束,退出代码为 0
四.Collection集合的遍历方式
1.方式一:迭代器
package com.wjh.d3_collection_traversal;
/*
2.定义一个while循环,问一次取一次
通过it.hasNext()询问是否有下一个元素,有就通过
it.Next()取出下一个元素.
小结:
记住代码.
*/
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class CollectionDemo1 {
public static void main(String[] args) {
Collection<String> list = new ArrayList<>();
list.add("小明");
list.add("小亮");
list.add("小红");
list.add("小嘉");
list.add("小帅");
System.out.println(list);
//1.得到当前集合的迭代器对象.
Iterator<String> it = list.iterator();
// String ele = it.next();
// System.out.println(ele); //小明
// System.out.println(it.next()); //小亮
// System.out.println(it.next()); //小红
// System.out.println(it.next()); //小嘉
// System.out.println(it.next()); //小帅
//
// //System.out.println(it.next()); //越界
//2.定义while循环
while(it.hasNext()){
String ele = it.next();
System.out.println(ele);
}
System.out.println("----------------------");
}
}
[小明, 小亮, 小红, 小嘉, 小帅]
小明
小亮
小红
小嘉
小帅
----------------------进程已结束,退出代码为 0
2.方式二:foreach/增强for循环
增强for循环
增强for循环:既可以遍历集合也可以遍历数组
他是JDK5出现之后,其内部原理是一个Iterator迭代器,遍历集合相当于是迭代器的简化写法.
实现Iterable接口的类才可以使用迭代器和增强for,Collection接口已经实现了Iterable接口.
格式:
for(元素数据类型 变量名 : 数组或者Collection集合){
//在此处使用变量即可,该变量就是元素.
}
package com.wjh.d3_collection_traversal;
import java.util.ArrayList;
import java.util.Collection;
public class CollectionDemo2 {
public static void main(String[] args) {
Collection<String> list = new ArrayList<>();
list.add("小明");
list.add("小红");
list.add("小嘉");
list.add("小航");
System.out.println(list);
//[小明, 小红, 小嘉, 小航]
//ele
for (String ele : list){
System.out.println(ele);
}
System.out.println("--------------------");
double[] scores = {100, 99.5, 88, 85.5, 59.5};
for (double score : scores) {
System.out.println(score);
}
}
}
[小明, 小红, 小嘉, 小航]
小明
小红
小嘉
小航
--------------------
100.0
99.5
88.0
85.5
59.5进程已结束,退出代码为 0
double[] scores = {100, 99.5, 88, 85.5, 59.5};
for (double score : scores) {
System.out.println(score);
if (score == 59.5){
score = 100; //修改无异议,不会影响数组和集合原本的值
}
}
System.out.println(Arrays.toString(scores)); //[100.0, 99.5, 88.0, 85.5, 59.5]
3.方式三:lambda表达式
package com.wjh.d3_collection_traversal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.function.Consumer;
public class CollectionDemo3 {
public static void main(String[] args) {
Collection<String> list = new ArrayList<>();
list.add("小明");
list.add("小红");
list.add("小嘉");
list.add("小航");
System.out.println(list);
//[小明, 小红, 小嘉, 小航]
//ele
System.out.println("---------------");
list.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
System.out.println("-------代码简化-----");
list.forEach(s -> {
System.out.println(s);
});
System.out.println("--------最终简化-------");
list.forEach(System.out::println);
}
}
[小明, 小红, 小嘉, 小航]
---------------
小明
小红
小嘉
小航
-------代码简化-----
小明
小红
小嘉
小航
--------最终简化-------
小明
小红
小嘉
小航进程已结束,退出代码为 0
五.Collection集合存储自定义类型的对象
package com.wjh.d4_collection_object;
import java.util.ArrayList;
import java.util.Collection;
public class TestDemo {
public static void main(String[] args) {
//定义一个电影类
//2.定义一个集合对象存储3部电影对象
Collection<Movie> movies = new ArrayList<>();
movies.add(new Movie("<<流浪地球>>", 9.6, "1,2,3"));
movies.add(new Movie("<<地球>>", 9.9, "4,6,7"));
movies.add(new Movie("<<流浪>>", 9.3, "8,5,9"));
//3.遍历集合容器中的每个电影独象
for (Movie movie2 : movies){
System.out.println("电影名:" + movie2.getName() + "评分:" + movie2.getScore() + "主演:" + movie2.getActor());
}
}
}
电影名:<<流浪地球>>评分:9.6主演:1,2,3
电影名:<<地球>>评分:9.9主演:4,6,7
电影名:<<流浪>>评分:9.3主演:8,5,9进程已结束,退出代码为 0
六.常见结构数据
1.数组结构概述, 栈, 队列
2.数组
数组是一种查询快,增删慢的模型.
3.链表
4.二叉树,二叉查找数
5.平衡二叉树
6.红黑树
七.List系列结合
1.List集合特点,特有API
package com.wjh.d5_collection_list;
import java.util.ArrayList;
import java.util.List;
public class ListDemo1 {
public static void main(String[] args) {
//1.创建一个ArrayList集合对象
//List:有序,可重读,有索引
List<String> list = new ArrayList<>(); //一条经典代码诞生了!
list.add("Java");
list.add("Java");
list.add("MySql");
list.add("MySql");
System.out.println(list); //[Java, Java, MySql, MySql]
//2.在某个索引位置上插入元素
list.add(2, "JavaScript");
System.out.println(list); //[Java, Java, MySql, MySql]
//3.根据索引删除元素,
//System.out.println(list.remove(2));// 返回被删除的元素 //MySql
list.remove(2);
System.out.println(list); //[Java, Java, JavaScript, MySql, MySql]
//4.根据索引获取元素:public E get(int index):返回集合中指定位置的元素
System.out.println(list.get(2));
System.out.println(list); //[Java, Java, MySql, MySql]
//5.修改索引位置处的元素:public E set(int index, E element)
//System.out.println(list.set(2, "Python")); //返回修改前的数据
list.set(2, "Python");
System.out.println(list); //[Java, Java, Python, MySql]
list.clear();
System.out.println(list); //[]
}
}
[Java, Java, MySql, MySql]
[Java, Java, JavaScript, MySql, MySql]
[Java, Java, MySql, MySql]
MySql
[Java, Java, MySql, MySql]
[Java, Java, Python, MySql]
[]进程已结束,退出代码为 0
2.List集合遍历方式小结
package com.wjh.d5_collection_list;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ListDemo2 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("Java1");
list.add("Java2");
list.add("Java3");
System.out.println("------------------");
//(1)for循环
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
System.out.println("------------------");
//(2)迭代器
Iterator<String> it = list.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
System.out.println("------------------");
//(3)forEach
for (String list2 : list){
System.out.println(list2);
}
System.out.println("------------------");
//(4)Lambda表达式(JDK1.8之后的)
list.forEach(s -> {
System.out.println(s);
});
System.out.println("------------------");
System.out.println(list);
}
}
------------------
Java1
Java2
Java3
------------------
Java1
Java2
Java3
------------------
Java1
Java2
Java3
------------------
Java1
Java2
Java3
------------------
[Java1, Java2, Java3]进程已结束,退出代码为 0
3.ArrayList集合的底层原理
4.LinkedList集合的底层原理
package com.wjh.d5_collection_list;
/*
如果查询多,增删少用ArrayList集合.(用的最多)
如果查询少,而增删首尾较多用LinkedList集合.
*/
import java.util.LinkedList;
public class ListDemo3 {
public static void main(String[] args) {
//LinkedList可以完成队列结构,和栈结构(双链表)
// 栈
LinkedList<String> list = new LinkedList<>(); //想用LinkedList的独有功能不要用多态
// 压栈 入栈
list.addFirst("1");
list.addFirst("2");
list.addFirst("3");
list.addFirst("4");
list.addFirst("5");
System.out.println(list); //[5, 4, 3, 2, 1]
//出栈 弹栈
System.out.println(list.getFirst()); //5 ;只是取出但是没有移除
System.out.println(list); //[5, 4, 3, 2, 1]
System.out.println(list.remove()); //5 ;返回取出结果,并且将getFirst移除
System.out.println(list.remove()); //4 ;返回取出结果,并且将getFirst移除
System.out.println(list.remove()); //3 ;返回取出结果,并且将getFirst移除
System.out.println(list); //上面执行三次移除首位元素 最终结果:[2, 1]
System.out.println("-------------------");
// 队列
LinkedList<String> queue = new LinkedList<>();
//入队
queue.addLast("1");
queue.addLast("2");
queue.addLast("3");
queue.addLast("4");
queue.addLast("5");
System.out.println(queue); //[1, 2, 3, 4, 5]
//出队
System.out.println(queue.getLast()); //5;只是取出但是没有移除
System.out.println(queue); //[1, 2, 3, 4, 5]
System.out.println(queue.removeFirst()); //1 ;返回取出结果,并且将getFirst移除
System.out.println(queue.removeFirst()); //2 ;返回取出结果,并且将getFirst移除
System.out.println(queue.removeFirst()); //3 ;返回取出结果,并且将getFirst移除
System.out.println(queue); //[4, 5]
//扩展
queue.push("s"); //压栈:与addFirst一样
System.out.println(queue); //[s, 4, 5]
System.out.println(queue.pop()); //弹栈:与removeFirst一样
System.out.println(queue); //[4, 5]
}
}
[5, 4, 3, 2, 1]
5
[5, 4, 3, 2, 1]
5
4
3
[2, 1]
-------------------
[1, 2, 3, 4, 5]
5
[1, 2, 3, 4, 5]
1
2
3
[4, 5]
[s, 4, 5]
s
[4, 5]进程已结束,退出代码为 0
八.补充知识:集合的并发修改异常问题
package com.wjh.d6_collection_update_delete;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/*
目标:研究集合遍历并删除元素可能会出现的问题 -> 并发修改异常问题.
*/
public class Test {
public static void main(String[] args) {
//1.准备数据
List<String> list = new ArrayList<>();
list.add("唱");
list.add("唱");
list.add("跳");
list.add("rap");
list.add("rap");
list.add("篮球");
list.add("music");
list.add("music");
System.out.println(list); //[唱, 跳, rap, rap, 篮球, music]
//[唱, 跳, rap, rap, 篮球, music]
//ik
//需求:删除全部的rap信息
//a.迭代器遍历删除
Iterator<String> it = list.iterator();
//输入list.iterator 按下ctrl+alt+V 自动补全代码
while(it.hasNext()){
String ele = it.next();
if(ele.equals("rap")){
//list.remove("rap"); 报错;删除后跳位也同时执行导致删除异常
it.remove(); //删除当前所在元素,并且不会跳位(后移)
//使用迭代器删除当前位置的元素,保证不后移,能够成功遍历到全部元素!
}
}
System.out.println(list);
//b.forEach遍历删除(会出现bug)
// for(String s : list){
// if(s.equals("music")){
// //list.remove(s); //报错!并发修改异常:同时遍历同时删除
// }
// }
//c.lambda表达式(会出现bug)
// list.forEach(s -> {
// if(s.equals("music")){
// //list.remove(s); //报错! :并发修改异常:同时遍历同时删除
// }
// });
// System.out.println(list);
//d.for循环(不出异常,但是数据有误,会漏删)
// for (int i = 0; i < list.size(); i++) {
// String ele = list.get(i);
// if (ele.equals("music")){
// list.remove(ele);
// }
// }
// System.out.println(list);
//解决方案: 倒着删!
//[唱, 跳, rap, rap, 篮球, music, music]
// i
for (int i = list.size() - 1; i >= 0; i--) {
String ele = list.get(i);
if (ele.equals("music")){
list.remove("music");
}
}
System.out.println(list);
//解决方案2: 增加退格操作
for (int i = 0; i < list.size(); i++) {
String ele = list.get(i);
if (ele.equals("唱")){
list.remove(ele);
i--;
}
}
System.out.println(list);
}
}
[唱, 唱, 跳, rap, rap, 篮球, music, music]
[唱, 唱, 跳, 篮球, music, music]
[唱, 唱, 跳, 篮球]
[跳, 篮球]进程已结束,退出代码为 0
九.补充知识:泛型输入
1.泛型的概述和优势
package com.wjh.d7_genericity;
/*
目标:泛型的概述
什么是泛型?
泛型是一个标签:<数据类型>
泛型在编译阶段只能操作某种数据类型.
注意:
JDK1.7开始后后面的泛型声明可以省略不写
小结:
泛型是一个标签.
泛型在编译阶段只能操作某种数据类型.
泛型只支持引用数据类型,不支持基本数据类型
Object -> 所有数据类型
*/
import java.util.ArrayList;
import java.util.List;
public class GenericityDemo {
public static void main(String[] args) {
//后面需要强转数据类型,太麻烦,所以可以用泛型先约束
// List list1 = new ArrayList<>();
// list1.add("Java1");
// list1.add(88);
// list1.add(true);
// list1.add(99.5);
//
// for (Object o : list1) {
// String ele = o + "";
// System.out.println(ele);
// }
List<String> list = new ArrayList<>();
list.add("Java1");
list.add("Java2");
list.add("Java3");
//list.add(23);
System.out.println(list);
System.out.println("-------Object-------");
//存输任意元素
List<Object> list2 = new ArrayList<>();
list2.add("Java");
list2.add(23);
list2.add(98.5);
list2.add(false);
System.out.println(list2);
}
}
[Java1, Java2, Java3]
-------Object-------
[Java, 23, 98.5, false]进程已结束,退出代码为 0
2.自定义泛型类
MyArrayList类:
package com.wjh.d8_genericity_class;
import java.util.ArrayList;
public class MyArrayList<E> {
private ArrayList lists = new ArrayList();
//包装类(换壳)
public void add(E e){
lists.add(e);
}
public void remove(E e){
lists.remove(e);
}
@Override
public String toString() {
return lists.toString();
}
}
测试类:
package com.wjh.d8_genericity_class;
public class Test {
public static void main(String[] args) {
//需求:模拟ArrayList定义一个MyArrayList,关注泛型设计
MyArrayList<String> list = new MyArrayList<String>();
list.add("Java");
list.add("C++");
list.add("Java");
list.remove("C++");
System.out.println(list);
MyArrayList<Integer> list1 = new MyArrayList<Integer>();
list1.add(23);
list1.add(59);
list1.add(98);
list1.add(100);
list1.remove(59);
System.out.println(list1);
}
}
[Java, Java]
[23, 98, 100]进程已结束,退出代码为 0
3.自定义泛型方法
package com.wjh.d9_genericity_method;
/*
定义了泛型的方法就是泛型方法
泛型方法的定义格式:
修饰符 <泛型变量> 返回值类型 方法名称(形参列表){
}
注意:方法中定义了什么泛型变量,后面就只能用什么泛型变量
泛型类的核心思想:是把泛型变量的地方全部替换成传输的真实数据类型.
需求:给你一个任何数据类型,都能返回他的内容. Array.toString(数组)的功能!
小结:
泛型放大可以更灵活地接受数据,可以做通用技术!
*/
public class GenericDemo {
public static void main(String[] args) {
String[] names = {"唱", "跳", "rap", "篮球"};
printArray(names);
Integer[] ages = {23, 18, 30};
printArray(ages);
}
/**
*
* @param arr 数组变量
* @param <T> 自定义泛型类型T
*/
public static <T> void printArray(T[] arr){
if (arr != null){
StringBuilder sb = new StringBuilder("[");
for (int i = 0 ; i < arr.length ;i++) {
sb.append(arr[i]).append(i == arr.length - 1 ? "" : ",");
}
sb.append("]");
System.out.println(sb);
}else{
System.out.println(arr);
}
}
}
[唱,跳,rap,篮球]
[23,18,30]进程已结束,退出代码为 0
4.自定义泛型接口
Date接口:
package com.wjh.d10_enericity_interface;
public interface Date<T> {
void add(T t);
void delete(int id);
void update(T t);
void queryById(int id);
}
测试类:
package com.wjh.d10_enericity_interface;
public class GenericInterfaceDemo {
public static void main(String[] args) {
}
}
Student类:
package com.wjh.d10_enericity_interface;
public class Student {
}
StudentDate类: 重写Date接口方法
package com.wjh.d10_enericity_interface;
public class StudentDate implements Date<Student>{
@Override
public void add(Student student) {
}
@Override
public void delete(int id) {
}
@Override
public void update(Student student) {
}
@Override
public void queryById(int id) {
}
}
Teacher类:
package com.wjh.d10_enericity_interface;
public class Teacher {
}
TeacherDate类: 重写Date接口方法
ackage com.wjh.d10_enericity_interface;
public class TeacherDate implements Date<Teacher>{
@Override
public void add(Teacher teacher) {
}
@Override
public void delete(int id) {
}
@Override
public void update(Teacher teacher) {
}
@Override
public void queryById(int id) {
}
}
5.泛型通配符,上下限
package com.wjh.d11_genericity_car;
/*
小结:
通配符: ?
? 可以在"使用泛型"的时候代表一切类型.
*/
import java.util.ArrayList;
public class GenericDemo {
public static void main(String[] args) {
ArrayList<Car> cars = new ArrayList<>();
cars.add(new BENZ());
cars.add(new BMW());
go(cars);
// ArrayList<Dog> dogs = new ArrayList<>();
// dogs.add(new Dog());
// dogs.add(new Dog());
// dogs.add(new Dog());
// go(dogs);
}
/*
所有类型都能进来比赛
*/
//public static void go(ArrayList<?> cars){ } // ? -> 代表一切类型
/**
* 所有车进来比赛(<? extends Car>只有继承了Car的子类才能进来比赛)
* @param cars
*/
public static void go(ArrayList<? extends Car> cars){ // ? -> 代表一切类型
}
}
class BENZ extends Car{
}
class BMW extends Car{
}
//其他类
class Dog{
}
//Car父类
class Car {
}