一.集合概念
1.1
案例:写一个学生数组,提出需求,根据需求分析数组和集合的区别
需求:存储5个学生对象,并输出学生对象的数据信息。
分析:
A:定义学生类(name,age)
B:定义学生数组,用于存储学生对象
C:创建学生对象,给学生对象的成员变量赋值
D:把创建好的学生对象添加到数组中
E:遍历数组。
package com.edu_01;
public class Student {
private String name;
private int age;
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Student() {
super();
// TODO Auto-generated constructor stub
}
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;
}
}
package com.edu_01;
public class StudentDemo {
public static void main(String[] args) {
/**
* 需求:德云社又添加了几个新徒弟
* 如果还想给德云社的数组中添加新徒弟的话,因为数组长度不可变,所以我们必须创建新的数组重新添加
*/
//2.创建学生对象
Student s1 = new Student("岳云鹏", 33);
Student s2 = new Student("孙越", 35);
Student s3 = new Student("郭老师", 45);
Student s4 = new Student("谦哥", 50);
//创建一个新徒弟
Student s5 = new Student("陈洁", 23);
//3.创建学生数组
Student[] ts = new Student[4];
//4.将创建的学生对象存储到数组中
ts[0] = s1;
ts[1] = s2;
ts[2] = s3;
ts[3] = s4;
//遍历学生数组
for (int i = 0; i < ts.length; i++) {
System.out.println(ts[i].getName()+" "+ts[i].getAge());
}
}
}
集合和数组的区别:数组不适应变化的需求,所有Java就提供了集合类供我们使用
数组:
1.长度固定
2.可以存储基本类型,也可以存储引用类型
3.存储元素类型一致
集合:
1.长度可变
2.只可以存储引用类型
3.可以存储多种类型
1.2
为什么出现集合类?
面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,我们就需要对这多个对象进行存储。而目前为止我们学习过的可以存储多个元素的东西是数组,但是呢,数组长度固定,不能适应变化的需求,所以,Java就提供了集合类供我们使用。
二.
2.1
Java提供了集合类供我们使用,而我们的需求可能是这样的:
* 我要求我的元素是有序的,
* 我要求我的元素是无序的,
* 我要求我的元素是唯一的,
* 我要求我的元素是可以重复的。
为了满足不同的需求,Java就提供了不同的集合类。
而这些集合类由于数据结构不同,才可以满足这些条件的。
数据结构:存储元素的方式。
而无论这些集合的结构是什么样子的,都是要装水的,所以,他们应该有共性的内容。
通过不断的向上提取,最终会形成一个集合的继承体系图。
2.2
java API 集合类图介绍(主要看继承关系,画图讲解)
Collction体系结构图
Collection
List
ArrayList
Vector
LinkedList
Set
HashSet
TreeSet
三.开发中常类介绍
String,Math,Scanner,List,ArrayList,等等
集合部分:
1.Collection
1.1
简单介绍这个接口
是集合的顶层结构,定义了集合的共性功能。
可以存储对象,这些对象也被称为元素。
1.2(学习方法)
成员方法:(看到E我们先把它理解为Object即可)
A:添加功能
boolean add(Object obj):往集合中添加一个元素
boolean addAll(Collection c):往集合中添加多个元素
B:删除功能
void clear():清空所有元素
boolean remove(Object o):从集合中删除一个元素
boolean removeAll(Collection c):从集合中删除另一个集合的元素
C:判断功能
boolean contains(Object o):判断集合中是否包含指定的元素
boolean containsAll(Collection c):判断集合中是否包含另一个集合的元素
boolean isEmpty():判断集合是否为空。
D:交集功能
boolean retainAll(Collection c)
E:迭代器(集合特有的遍历方式)
Iterator iterator()
重点:Iterator的使用
A:使用步骤
B:迭代器原理
F:长度功能
int size():返回集合中元素的个数
面试题:
数组有length()吗?字符串有length()吗?集合有length()吗?
G:集合转数组
Object[]toArray():把集合转成数组,然后遍历数组,其实就相当于遍历了集合。(这个代码我们练习一次,就可以忘)
package day10.edu_2;
import java.util.ArrayList;
import java.util.Collection;
public class CollectionDemo {
public static void main(String[] args) {
//创建集合
//Collection c = new Collection();(会报错)
ArrayList<Object> a = new ArrayList<>();
//boolean add(Object obj):往集合中添加一个元素
a.add("java");
a.add(123);//集合中只能添加引用类型的数据,但是在这里为什么可以添加int类型的数据100呢?在这里进行了自动装箱
//boolean addAll(Collection c):往集合中添加多个元素
ArrayList<Object> a2 = new ArrayList<>();
a2.add("汇演");
a2.add("521");
a.addAll(a2);
//void clear():清空所有元素
//a.clear();
//boolean remove(Object o):从集合中删除一个元素
boolean remove = a.remove("521");
System.out.println(remove);
//boolean removeAll(Collection c):从集合中删除另一个集合的元素,只要删除一个元素就代表删除成功
boolean removeAll = a.removeAll(a2);
System.out.println(removeAll);
//boolean contains(Object o):判断集合中是否包含指定的元素
boolean contains = a.contains("521");
System.out.println(contains);
//boolean containsAll(Collection c):判断集合中是否包含另一个集合的元素,包含的所有元素才叫全部包含
boolean containsAll = a.containsAll(a2);
System.out.println(containsAll);
//boolean isEmpty():判断集合是否为空。
boolean empty = a.isEmpty();
System.out.println(empty);
//boolean retainAll(Collection c):求出交集元素,并且将没有交集的元素删除
boolean retainAll = a.retainAll(a2);
System.out.println(retainAll);
//int size():返回集合中元素的个数
int size = a.size();
System.out.println(size);
System.out.println("---------------------------");
//怎么遍历集合呢?
//先将集合转成数组
Object[] array = a.toArray();
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
}
练习:
1.3
需求:往集合中添加三个字符串,并遍历。
分析:
A:创建集合对象
B:创建字符串对象
C:把字符串对象添加到集合对象中
D:遍历集合
Object[] toArray():把集合转成数组,然后遍历数组,其实就相当于遍历了集合。
练习:
在集合中存储3个学生对象,并遍历,拿出每一个学生对象的属性。
package day10.edu_3;
import java.util.ArrayList;
public class CollectionDemo {
public static void main(String[] args) {
//1.创建学生对象
Student s1 = new Student("小白", 12);
Student s2 = new Student("小灰", 16);
Student s3 = new Student("小黑", 13);
//2.创建集合
ArrayList<Object> a = new ArrayList<>();
//3.将学生对象添加到集合中
a.add(s1);
a.add(s2);
a.add(s3);
//4.遍历集合
Object[] array = a.toArray();
for (int i = 0; i < array.length; i++) {
Student s = (Student)array[i];
System.out.println(s.getAge()+" "+s.getName());
}
}
}
package day10.edu_3;
public class Student {
private String name;
private int age;
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;
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Student() {
super();
// TODO Auto-generated constructor stub
}
}
1.4
迭代器:(分别创建String对象,Student对象添加集合遍历练习)
Iterator iterator()
Object next():返回迭代的下一个元素,并移动指向的位置
boolean hasNext():判断是否有元素
NoSuchElementException:没有这样的元素异常。
原因是:你已经获取到元素的末尾了,你还要继续获取元素,已经没有了,所以就报错了。
解决方案:你不要再拿了。我哪知道什么就不拿了啊?怎么办呢?就应该在拿之前判断一下是否有元素。
迭代器遍历集合:
迭代器是依赖于集合而存在的。所以,要想得到迭代器对象,必须先有集合对象。
迭代步骤:
A:通过集合对象获取到迭代器对象
B:通过迭代器对象的hasNext()方法判断是否有元素
C:通过迭代器对象的next()方法获取元素
package com.edu_04;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class CollectionDemo {
public static void main(String[] args) {
//学习的是集合的迭代器的遍历方式
//创建一个集合
Collection c = new ArrayList();
//给集合中添加元素
c.add("hello");
c.add("world");
c.add("java");
//将集合转换成迭代器对象之后进行遍历
Iterator it = c.iterator();
//从迭代器中取出元素,调用next()方法
// System.out.println(it.next());
// System.out.println(it.next());
// System.out.println(it.next());
//System.out.println(it.next());//java.util.NoSuchElementException,没有元素了
//为了避免上面的异常发生,我们可以首先调用他的hasNext()这个方法,判断线面是否有可以继续往下进行迭代的元素
// if (it.hasNext()) {
// System.out.println(it.next());
// }
//
// if (it.hasNext()) {
// System.out.println(it.next());
// }
//
// if (it.hasNext()) {
// System.out.println(it.next());
// }
//
// if (it.hasNext()) {
// System.out.println(it.next());
// }
//使用while循环改进上述代码
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
1.5
练习:创建狗对象(带参数),存储到集合,用迭代器进行遍历并打印对象的属性数据
package com.edu_05;
public class Dog {
private String name;
private int age;
private String type;
public Dog(String name, int age, String type) {
super();
this.name = name;
this.age = age;
this.type = type;
}
public Dog() {
super();
// TODO Auto-generated constructor stub
}
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;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
package com.edu_05;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class DogTest {
public static void main(String[] args) {
/**
* 1.创建dog对象
* 2.创建集合
* 3.将dog对象添加到集合
* 4.获取迭代器对象
* 5.调用方法进行遍历
*/
//1.创建dog对象
Dog d1 = new Dog("小黑", 1, "藏獒");
Dog d2 = new Dog("小黄", 1, "金毛");
Dog d3 = new Dog("小白", 2, "萨摩耶");
//2.创建集合
Collection c = new ArrayList();
//3.将dog对象添加到集合
c.add(d1);
c.add(d2);
c.add(d3);
//4.获取迭代器对象,该集合对应的迭代器对象
Iterator it = c.iterator();
// 5.调用方法进行遍历
while (it.hasNext()) {
Dog d = (Dog) it.next();
System.out.println(d.getName()+" "+d.getAge()+" "+d.getType());
}
}
}
2.List
(1)List集合的元素有序(存储和取出顺序一致),元素可重复
(2)List的特有功能:
A:添加功能
void add(int index,Object obj):在指定的位置添加元素
B:删除功能
Object remove(int index):通过指定的索引删除元素,并把删除的元素返回
C:获取功能
get(int index) 返回列表中指定位置的元素。
D:替换功能
Object set(int index,Object obj)
package com.edu_06;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
public class ListDemo {
public static void main(String[] args) {
//创建List集合,List集合特点:元素的存入和取出的顺序一致
List<String> list = new ArrayList<String>();
list.add("hello");
list.add("world");
list.add("java");
//void add(int index,Object obj):在指定的位置添加元素
//list.add(1, "php");
//Object remove(int index):通过指定的索引删除元素,并把删除的元素返回
//Object remove = list.remove(1);
//System.out.println(remove);
//get(int index) 返回列表中指定位置的元素。
// Object object = list.get(0);
// System.out.println(object);
// Object object2 = list.get(1);
// System.out.println(object2);
// Object object3 = list.get(2);
// System.out.println(object3);
//list集合的特有的便利方式,通过get(int index),和size()方法,可以通过普通for循环去遍历list集合
/*
for(int i=0;i<list.size();i++){
Object object = list.get(i);
String str = (String)object;
System.out.println(str);
}*/
//Object set(int index,Object obj),将指定的索引处的元素替换成指定元素,并且将原来的老的元素返回
String set = list.set(2, "c++");
System.out.println(set);
System.out.println("---------------");
//遍历集合
Iterator<String> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
(3)案例:
A:List存储字符串并遍历(迭代器,普通for)
B:List存储自定义对象并遍历(迭代器,普通for)
package com.edu_07;
public class Student {
private String name;
private int age;
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Student() {
super();
// TODO Auto-generated constructor stub
}
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;
}
}
package com.edu_07;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ListDemo {
public static void main(String[] args) {
//创建学生对象
Student s1 = new Student("刘德华", 50);
Student s2 = new Student("张学友", 55);
Student s3 = new Student("黎明", 56);
Student s4 = new Student("郭富城", 60);
//创建List集合
List list = new ArrayList();
//给集合中添加元素
list.add(s1);
list.add(s2);
list.add(s3);
list.add(s4);
//普通for循环进行遍历
for(int i=0;i<list.size();i++){
Object object = list.get(i);
Student s = (Student)object;
System.out.println(s.getAge()+" "+s.getName());
}
System.out.println("-----------");
//获取迭代器对象
Iterator it = list.iterator();
while (it.hasNext()) {
Object obj = it.next();
Student s = (Student)obj;
System.out.println(s.getAge()+" "+s.getName());
}
System.out.println("------------");
//使用增强for循环遍历集合
for(Object obj:list){
Student s= (Student)obj;
System.out.println(s.getAge()+" "+s.getName());
}
}
}
package com.edu_07;
import java.util.ArrayList;
import java.util.List;
public class ForDemo {
public static void main(String[] args) {
/**
* 使用增强for循环遍历集合
* for(集合中的元素类型 变量名:集合名){
* 取出集合中的每一个元素
* }
*
*/
//创建一个List集合
List list = new ArrayList();
//给集合中添加元素
list.add("java");
list.add("hello");
list.add("world");
//使用增强for循环遍历集合
for(Object str:list){
System.out.println(str);
}
}
}
(4).List的倒序与洗牌
List中元素顺序可以被洗牌Collections.shuffle(list)
List中元素顺序可以被倒序Collections.reverse(list)
Collections.sort(list)对List元素排序(字母数字分别进行测试)
package com.edu_08;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class CollectionsDemo {
public static void main(String[] args) {
//创建List集合
List list = new ArrayList();
//给集合中添加元素
list.add(2);
list.add(8);
list.add(1);
list.add(3);
//List中元素顺序可以被洗牌Collections.shuffle(list)
//Collections.shuffle(list);
//List中元素顺序可以被倒序Collections.reverse(list)
//Collections.reverse(list);
//Collections.sort(list)对List元素排序(字母数字分别进行测试)
//如果是按字母是按照a-z的顺序进行排序
//Collections.sort(list);
//如果是按照数字进行排序,按照从小到大的顺序进行排列
Collections.sort(list);
//遍历集合
for (Object object : list) {
System.out.println(object);
}
}
}
案例练习:
需求:用List集合存储3个汽车对象,然后遍历。
汽车:Car
成员变量:String brand,int price,String color
构造方法:无参,带参
成员方法:getXxx()/setXxx()
package com.edu_09;
public class Car {
private String brand;
private int price;
private String color;
public Car(String brand, int price, String color) {
super();
this.brand = brand;
this.price = price;
this.color = color;
}
public Car() {
super();
// TODO Auto-generated constructor stub
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}
package com.edu_09;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class CarDemo {
public static void main(String[] args) {
//创建汽车对象
Car c1 = new Car("兰博基尼", 4000000, "黑色");
Car c2 = new Car("玛莎拉蒂", 1000000, "黑色");
Car c3 = new Car("特斯拉", 1000000, "黑色");
//创建集合
List list = new ArrayList();
//给集合中添加元素
list.add(c1);
list.add(c2);
list.add(c3);
//迭代器遍历
Iterator it = list.iterator();
while (it.hasNext()) {
Object obj = it.next();
Car c = (Car)obj;
System.out.println(c.getBrand()+" "+c.getColor()+" "+c.getPrice());
}
System.out.println("----------------");
//普通for循环
for (int i = 0; i < list.size(); i++) {
Car car = (Car)list.get(i);
System.out.println(car.getBrand()+" "+car.getColor()+" "+car.getPrice());
}
System.out.println("----------------");
//增强for循环
for(Object obj:list){
Car car2 = (Car)obj;
System.out.println(car2.getBrand()+" "+car2.getColor()+" "+car2.getPrice());
}
}
}
注意事项:
A:忘写main方法。
B:导入包的问题,集合操作的时候,导入包基本上都是在java.util下
C:大家针对我们的命名规范有些忘记了,需要回来再看一下
类,接口等名称是首字母大写
变量或者方法名首字母小写
3.ArrayList
案例1:存储字符串并遍历
案例2:存储自定义对象并遍历
4.LinkedList
案例1:存储字符串并遍历
案例2:存储自定义对象并遍历
* LinkedList特有功能:
* public void addFirst(E e)
* public void addLast(E e)
*
* public E getFirst()
* public E getLast()
*
* public E removeFirst()
* public E removeLast()
package com.edu_10;
import java.util.LinkedList;
import java.util.List;
public class LinkedListDemo {
public static void main(String[] args) {
//创建一个LinkedList的集合
LinkedList list = new LinkedList();
list.add("hello");
list.add("world");
list.add("java");
// * public void addFirst(E e)
// * public void addLast(E e)
//需求:在hello前面加上一个元素“c++”
list.addFirst("c++");
list.addLast("js");
// * public E getFirst()
// * public E getLast()
// Object first = list.getFirst();
// Object last = list.getLast();
// System.out.println(first);
// System.out.println(last);
// * public E removeFirst()
// * public E removeLast()
Object removeFirst = list.removeFirst();
Object removeLast = list.removeLast();
System.out.println(removeFirst);
System.out.println(removeLast);
System.out.println("---------------");
//遍历集合
for(Object obj:list){
System.out.println(obj);
}
}
}
8.ArrayList与LinkedList的相同点与不同点 (面试题**)
相同点:有顺序的,元素可以重复
(1)ArrayList特点:
底层数据结构是数组,查询快,增删慢
线程不安全,效率高
(2)LinkedList特点:
底层数据结构是链表,查询慢,增删快
线程不安全,效率高
package com.edu_11;
import java.util.ArrayList;
import java.util.List;
public class ListDemo {
public static void main(String[] args) {
//创建一个集合
//list集合两个特点:1.元素存入和取出的顺序一致 2.元素可以重复
List list = new ArrayList();
//给集合中添加元素
list.add("hello");
list.add("world");
list.add("hello");
for (Object object : list) {
System.out.println(object);
}
}
}
9.List的遍历(掌握)
1.for(普通for)
2.Iterator(迭代器)
3.foreach(增强for)
10.泛型入门
引入:
案例:创建集合存储字符串,存储integer类型数据,遍历的时候强制转换
与String数组进行对比,引入泛型
package com.edu_12;
import java.util.ArrayList;
/**
* 根据下面的代码演示得出结论:我们目前使用集合的这种方式是很不安全的
*
* 什么是泛型:泛型是一种可以将明确数据类型的工作推迟到创建对象或者调用方法的时候才去明确数据类型的特殊的数据类型
*
* 泛型的格式:<泛型>
*
* 加入泛型的好处:
* 1.将我们之前的运行时期的异常提前到编译时期
* 2.解决了黄色警告线的问题
* 3.避免了强制类型转换的麻烦
*/
public class GenericDemo {
public static void main(String[] args) {
//创建一个集合
// ArrayList al = new ArrayList();
// al.add("hello");
// al.add("world");
// al.add("java");
// al.add(100);
//创建ArrayList集合的时候就给集合加上泛型,明确一下这个的类型
//在这里已经明确了数据类型,说明目前只能给al集合中添加String类型的元素
ArrayList<String> al = new ArrayList<String>();
al.add("java");
al.add("hello");
al.add("woreld");
//al.add(100);
//遍历一下
// for(Object obj:al){
// String s = (String)obj;
// System.out.println(s);
// //java.lang.ClassCastException:类型转换异常,
// //在这里当我们将Integer类型的100强制转换成String类型的100的时候就会抛出这个类型转换的异常
// }
//加入泛型之后再去遍历al集合
for (int i = 0; i < al.size(); i++) {
String str = al.get(i);
System.out.println(str);
}
//创建一个数组
String[] strs = new String[3];
strs[0] = "java";
strs[1] = "world";
//strs[2] = 100;
//,当我们给String类型的数组赋int类型的值的时候就出现了报错的情况,
//因为我们在创建这个数组之处就已经规定了存入这个数组元素的类型
//直接在编译之处代码就会直接抛异常
}
}
泛型(掌握)
(1)是一种把明确数据类型的工作推迟到创建对象或者调用方法的时候才去明确类型的特殊类型
(2)格式:
<数据类型>
默认情况下,是Object类型。
这里数据类型只能是引用类型。如果你看到写基本类型也行,其实这里使用了自动装箱。
(3)好处:
A:把运行时期问题提前到了编译时期
B:避免了强制类型转换
C:优化程序设计,解决了黄色警告线问题
(4)在哪里用?
一般来说就是在集合中用的多。
看API,如果类或者接口或者方法出现了<>说明这里就有泛型。
package com.edu_13;
public class Student {
private String name;
private int age;
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Student() {
super();
// TODO Auto-generated constructor stub
}
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;
}
}
package com.edu_13;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
//注意:以后所有人创建集合对象的时候全部必须加上泛型
public class GenericDemo {
public static void main(String[] args) {
//创建集合对象并加上泛型
//创建学生对象
Student s = new Student("刘德华", 50);
Student s1 = new Student("张学友", 55);
Student s2 = new Student("林志玲", 47);
//创建集合对象并加上泛型
List<Student> list = new ArrayList<Student>();
//集合中添加元素
list.add(s);
list.add(s1);
list.add(s2);
//使用迭代器进行遍历
Iterator<Student> it = list.iterator();
while (it.hasNext()) {
//取出迭代器中的元素
Student ss = it.next();
System.out.println(ss.getAge()+" "+ss.getName());
}
}
}
拓展(有时间的话可以讲一讲,听懂了解就可以):
(5)泛型的概述(了解)
A:泛型类(把泛型定义在类上)
package com.edu_14;
public class GenericDemo<E> {
//创建一个方法
public void show(E e){
System.out.println(e);
}
}
package com.edu_14;
public class Test {
public static void main(String[] args) {
GenericDemo<String> gd = new GenericDemo<String>();
gd.show("hello");
}
}
B:泛型方法(把泛型定义在方法上)
package com.edu_15;
public class GenericDemo<E> {
public void show(E e){
System.out.println(e);
}
//创建一个方法,将泛型加载方法上
public<BMW> void method(BMW bmw){
System.out.println(bmw);
}
}
package com.edu_15;
public class Test {
public static void main(String[] args) {
GenericDemo<String> gd = new GenericDemo<String>();
gd.show("hello");
gd.method("hello");
gd.method(100);
gd.method('a');
}
}
C:泛型接口(泛型定义在接口上)
package com.edu_16;
public interface Inter<E> {
}
package com.edu_16;
public class InterImpl<E> implements Inter<E> {
}
(6)泛型通配符(先不进行讲解,后面会根据实例一一进行讲解)