集合
通过一个例子引入集合概念
练习1 Student类
package org.westos.collection_02;
public class Student {
private String name;
private int age;
public Student() {
super();
}
public Student(String name, int age) {
super();
this.name = name;
this.age = 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;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
测试类
package org.westos.objectarray;
/**
* 对象数组:可以存储对象的数组
*
* 需求:有5个学生,每一个学生有自己的信息(姓名,年龄等等),将5个学生的信息遍历出来!
*
* 分析:A:定义一个学生类:
* 提供两个成员 变量
* String name,int age
* 提供无参/有参的构造方法
* 提供set/get()方法
* B:定义一个学生数组(对象数组)
* C:创建5个学生对象
* D:赋值,将5个学生对象放到学生数组中
* E:遍历数组
* F:输出
*
* @author Orange
*/
public class ObjectArrayDemo {
public static void main(String[] args) {
//学生类创建完毕
//定义一个学生数组:定义数组的格式:数据类型[] 数组名称 = new 数据类型[数组长度] ;
//定义一个学生数组
Student[] students = new Student[5] ;//数组的类型可以是自定义的
//创建5个学生对象
Student s1 = new Student("高圆圆", 27) ;
Student s2 = new Student("黄晓明", 28) ;
Student s3 = new Student("邓超" ,30) ;
Student s4 = new Student("孙俪" ,28) ;
Student s5 = new Student("王昭君" ,25) ;
//赋值
students[0] = s1 ;
students[1] = s2 ;
students[2] = s3 ;
students[3] = s4 ;
students[4] = s5 ;
//遍历学生数组
for(int x = 0 ; x <students.length ; x ++){
//System.out.println(students[x]);
//通过底层原码重写toString()得到的每个对象的成员变量的信息(不重写的话是地址)
//多态:编译在左,运行在右---此时右也是继承Object的toString()
Student s = students[x] ;
System.out.println(s.getName()+"----"+s.getAge());
}
}
}
集合的由来
我们学习的java的语言是一种面向对象语言,面向对象语言对事物的描述是通过对象体现出来的,那么存储很多个学生,就需要使用容器变量进行存储,那么目前我们学习过哪些容器变量呢?
数组、StringBuffer、StringBuilder,对于数组来说,数组的长度是固定的,不符合实际需求(长度不可变);对于StringBuffer来说始终在内存中返回的是字符串类型,也不满足元素类型变化的要求;所以java就提供了一个技术-----集合!
集合:是可以存储多种类型的引用元素;针对集合来说,Java提供了很多集合类,每一种集合类的数据结构不一样,所以将他们之间的共性内容抽取出来就行了
面试题1:
集合和数组的区别?
1)长度的区别:
数组:长度是固定的;
集合:长度是可变的;
2)存储数据类型的区别:
数组:可以存储引用类型,可以存储基本数据类型
集合:只能存储引用类型
3)存储元素的区别
数组:在同一个数组中,只能存储同一种数据类型的元素
集合:可以存储多种数据类型的元素
一个集合的继承体系图!(回头补图)
数据结构:存储数据的方式
Collection:表示一组对象,这些对象也称为 collection 的元素;一些 collection 允许有重复的元素,而另一些则不允许;
一些 collection 是有序的,而另一些则是无序的;JDK 不提供此接口的任何直接
实现方式:它提供更具体的子接口(如 Set 和 List)实现
Collection的一些常用成员方法
添加功能:
1---boolean add(Object e):给集合中添加指定的元素
问题1:为什么add(Object object)?
我们知道集合的容器是可以添加任意类型的对象,那么add方法的参数类型是Object,以便于接受任何类型的对象,集合中存储的都是对象的引用,通过接口多态实现。
2---boolean addAll(Collection c):添加一个集合中的所有元素
删除功能:
3---void clear():删除一个集合中的所有元素,暴力删除,(不建议使用)
4---boolean remove(Object o):删除一个集合中的指定元素
5---boolean removeAll(Collection c):删除一个集合中的所有元素(有一个就算)
判断功能:
6---boolean contains(Object o):判断一个集合中是否包含指定的单个元素
7---boolean containsAll(Collection c):判断一个集合中是否另一个集合---是包含所有.
8---boolean isEmpty():判断集合是否为空,如果为空,则返回true
交集功能:
9---boolean retainAll(Collection c):思考:A集合给B集合做交集,交集的元素去哪里?返回值boolean表达什么意思?
获取功能:
10--int size():获取集合中的元素数
11--Iterator<E> iterator()---迭代器
转换功能:
13--Object[] toArray():将集合转换成数组
面试题2
数组中有没有length(),String类中有没有length(),集合中有没有length()?
答:数组--length属性;String--length();集合中--size()
实例1 (非All的功能)
package org.westos.collection;
import java.util.ArrayList;
import java.util.Collection;
public class CollectionDemo {
public static void main(String[] args) {
//创建一个Collection集合对象
Collection c = new ArrayList() ;//JDK不提供此接口的任何直接 实现:它提供更具体的子接口(如Set和List)实现
System.out.println(c);//输出的是"[]",底层重写了toString()---ArrayList的方法,所以不是地址
/* 1--添加功能:
* public boolean add(E e)---可选操作
* E表示泛型,这里先理解为(Object object)
* 功能:给集合中添加指定的元素;
* 返回值类型说明:只要给集合中添加元素,永远返回true
*
*/
c.add("hello") ;
c.add("world") ;
c.add("Java") ;
System.out.println("添加元素add():"+c);
/* 2---删除(所有)
* void clear()---可选操作
* 功能:删除一个集合中的所有元素(可选操作)---暴力删除---不建议使用
*
* */
c.clear() ;
System.out.println("删除元素clear():"+c);
System.out.println("------------------");
//删除后再添加
c.add("hello") ;
c.add("world") ;
c.add("Java") ;
/*
* 3---删除指定元素
* boolean remove(Object o)---可选操作
* 功能:删除一个集合中的指定元素
* 返回值类型:boolean,true(删除成功),false(集合无此元素)
*
* */
boolean isRemove=c.remove("hello");
System.out.println(isRemove) ;
System.out.println("删除元素remove():"+c);
boolean isRemove1=c.remove("haha");
System.out.println(isRemove1) ;
/* 4---判断
* boolean contains(Object o)
* 功能:判断一个集合中是否包含指定的单个元素
* 返回值类型:boolean--如果此 集合包含指定的元素,则返回 true
*
* */
boolean isContains=c.contains("world");
System.out.println(isContains);
boolean isContains1=c.contains("haha");
System.out.println(isContains1);
/* 5---判断
* boolean isEmpty()
* 功能:判断集合是否为空,如果为空(即:不包含任何元素)则返回true
*
* */
boolean isEmpty1=c.isEmpty();
System.out.println("isEmpty:"+c.isEmpty());
/* 6---获取功能
* int size()
* 功能:获取集合中的元素数
*
* */
System.out.println("size:"+c.size());
//经过几步操作最后的结果
System.out.println("c:"+c);
}
}
对于类中
可选操作解释:
链接1:点击打开链接
链接2:点击打开链接
链接3:点击打开链接
链接4:点击打开链接
通俗易懂解释:可选操作”:简单说就是抽象类的的某些派生类实现里,或者接口的某个实现类里面,某个方法可能是无意义的,调用该方法会抛出一个异常。例如在collection的某些实现类里,里面的元素可能都是只读的,那么add这个接口是无意义的,调用会抛出UnspportedOperationException异常。 从设计的角度说,如果一个接口的方法设计为optional,表示这个方法不是为所有的实现而设定的,而只是为某一类的实现而设定的。
实例2 集合高级功能(All)
package org.westos.collection;
import java.util.ArrayList;
import java.util.Collection;
/**
* 特点:
* 带All的方法的形参:都是Collection c
*/
public class CollectionDemo2 {
public static void main(String[] args) {
//创建两个Collection集合对象
Collection c1 = new ArrayList() ;
Collection c2 = new ArrayList() ;
//说明:ArrayList类允许有重复的对象
//分别给c1,c2集合添加元素
c1.add("1") ;
c1.add("2") ;
c1.add("3") ;
c1.add("4") ;
c1.add("8") ;
System.out.println(c1);
c2.add("1") ;
c2.add("2") ;
c2.add("3") ;
c2.add("4") ;
c2.add("5") ;
c2.add("6") ;
c2.add("7") ;
System.out.println(c2);
/* 1--添加(All)
* boolean addAll(Collection c)----可选操作
* 功能:添加一个集合中的所有元素
* 谁调用在谁的集合中进行操作,所以在c1末尾添加
* */
boolean isAddAll=c1.addAll(c2);
System.out.println("addAll:"+isAddAll);
System.out.println(c1);//ArrayList类允许有重复的对象
System.out.println(c2);
System.out.println("-------------------------");
/* 2-删除(All)
* boolean removeAll(Collection c)---可选操作
* 功能:删除一个集合中的所有元素(共有的)
* 返回值类型:boolean
* 理解:其实是删除两个集合交集(共有的)的元素,因此删除一个算是删除,返回的是true
* 说明:此调用返回后, collection(c1)中将不包含任何与指定 collection(c2)相同的元素
* */
boolean isRemovel=c1.removeAll(c2);
System.out.println("removeAll:"+isRemovel);
System.out.println(c1);
System.out.println(c2);
System.out.println("-----------------------------");
//再给c1补充点货源
c1.add("1") ;
c1.add("2") ;
c1.add("3") ;
c1.add("4") ;
c1.remove("8");
System.out.println("补充货源后的c1:"+c1);
System.out.println("始终雷打不动c2:"+c2);
/* 3---包含
* boolean containsAll(Collection c)
* 功能:判断一个集合中(调用)是否包含另一个集合(被调用);
* 返回值类型:boolean
* 说明:如果此 collection包含指定 collection中的所有元素,则返回 true
*
* */
boolean isContainAll=c1.containsAll(c2);
//解释:c1(小)是否包含于c2(大)
System.out.println("containsAll:"+isContainAll);
boolean isContainAll1=c2.containsAll(c1);
//解释:c2(大)是否包含c1(小)
System.out.println("containsAll:"+isContainAll1);
/* 4---交集
* boolean retainAll(Collection c)---可选操作
* 返回值类型:boolean
* 返回值boolean表达什么意思?
* 说明--A集合对B集合取交集,那么交集的元素去A集合里面了,A集合中的元素是否发生变化,如果发生变化,就返回true;否则就false
* 说明:仅保留此 collection中那些也包含在指定 collection的元素(可选操作)。换句话说,移除此 collection 中未包含在指定 collection 中的所有元素。
* 思考:A集合给B集合做交集,交集的元素去哪里?
*
* */
boolean isretailAll=c1.retainAll(c2);
System.out.println("c1:"+isretailAll);
System.out.println("c1:"+c1);
System.out.println("c2:"+c2);
System.out.println("-----------------");
boolean isretailAll1=c2.retainAll(c1);
System.out.println("c2:"+isretailAll1);
//输出最终的结果
System.out.println("c1:"+c1);
System.out.println("c2:"+c2);
/**
* 面试题:
* A集合对B集合取交集,那么交集的元素去A集合里面了,并且返回值boolean表达的意思?
* 答:是A集合中的元素是否发生变化,如果发生变化,就返回true;否则,false
*/
}
}
Object[] toArray():将集合转换成数组
返回值类型:Object[]
返回:包含此 collection 中所有元素的数组
实例3
package org.westos.collection;
import java.util.ArrayList;
import java.util.Collection;
// 需求:给集合中添加String类型的元素,遍历集合
public class CollectionDemo3 {
public static void main(String[] args) {
//创建Collection集合对象
Collection c = new ArrayList() ;
//给集合中添加元素
c.add("高圆圆") ;
/* 说明1:
* c.add(Object obj)
* c.add("高圆圆")等价于
* ==>Object obj = new String("高圆圆"),从add()方法可以看出,此时Collection存储的此元素的是Object的对象
* ==>向上转型了(接口多态)
* */
c.add("邓超") ;
c.add("WE") ;
c.add("RNG") ;
//集合中有元素了,将集合转换数组
Object[] objs = c.toArray() ;
//遍历对象数组(需求:获取集合中元素的同时,获取集合中每一个元素的字符串长度)
for(int x = 0 ; x < objs.length ; x ++){
//System.out.println("objs[x]的引用是不是String的一个实例"+objs[x] instanceof String);
String s = (String) objs[x] ;//向下转型--父类的引用强制转换为子类的引用(必须有向上转型)
System.out.print(s+"----"+s.length()+";");//要获取字符串长度:需要使用length(),该方法属于String类的特有功能
}
System.out.println();
for(int i= 0;i<objs.length;i++){
//System.out.println(objs[x]+"---"+objs[x].length());//报错:没有为类型 Object 定义方法 length()
System.out.println(objs[i]+"---");
//疑问:objs[x].length()不能使用原因:此时是Object的引用,--多态--编译在左(没有length方法,编译不通过)
}
}
}
练习1
package org.westos.collection_01;
public class Student {
private String name;
private int age;
public Student() {
super();
}
public Student(String name, int age) {
super();
this.name = name;
this.age = 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;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
测试类
package org.westos.collection_01;
import java.util.ArrayList;
import java.util.Collection;
/**
* 需求:有5个学生,每一个学生有自己的信息(姓名,年龄...),将5个学生的信息遍历出来!
* 使用集合的转换功能去遍历学生信息
*
* 1)创建集合对象
* 2)创建5个学生对象
* 3)使用集合添加5个学生对象
* 4)将集合转换成数组:Object[] toArray() ;
* 5)遍历数组
* @author Orange
*/
public class CollectionTest {
public static void main(String[] args) {
//创建集合对象(集合中存储的是引用类型)
Collection c = new ArrayList() ;
//创建5个学生对象
Student s1 = new Student("貂蝉", 25) ;
Student s2 = new Student("王昭君", 22) ;
Student s3 = new Student("西施", 28) ;
Student s4 = new Student("杨贵妃", 29) ;
Student s5 = new Student("高圆圆", 38) ;
//给集合中添加元素
c.add(s1) ;//向下转型:Object obj = new Student("..") ;
c.add(s2) ;
c.add(s3) ;
c.add(s4) ;
c.add(s5) ;
//将集合转换成数组
Object[] objs = c.toArray() ;
for(int x = 0 ; x < objs.length ; x ++){
/* 1---
* System.out.println(objs[x]);
* 说明:
* 储存的是Object的引用类型;
* 如果不重写toString()就继承Object的此方法;
* 输出的是地址
*
*/
/* 2---
* 使用get()获取学生姓名和年龄
* Student类型接收
* */
Student s = (Student) objs[x] ;//使用子类特有的方法
System.out.println(s.getName()+"---"+s.getAge());
}
}
}
上面的遍历是不是挺麻烦的,引出→集合特有的遍历形式
集合的特有遍历方式:使用集合自己本身迭代功能遍历集合中的元素
Iterator iterator():迭代器
Iterator:迭代器接口
Iterator的成员方法:判断功能
Object next():返回迭代的下一个元素
boolean hasNext():判断一个集合中是否有下一个可以迭代的元素
实例4
package org.westos.collection_02;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
* Collection(集合)的专有遍历方式:使用集合自己本身迭代功能遍历集合中的元素
* Iterator iterator():迭代器
* 返回值类型:Iterator(迭代器接口)
* Iterator接口的成员方法(获取功能):
* 1--E(这里指:Object) next()
* 功能:返回迭代的下一个元素
* 返回值类型:Object
* 2--boolean hasNext()
* 功能:判断一个集合中是否有下一个可以迭代的元素
* 返回值类型:boolean
* 说明:如果迭代器仍有元素可迭代,则返回 true。
* 理解脉略:
* Collection-----→iteration()------→Iteration对象-----→判断:hasNext()-----→遍历:next
* 需求:使用集合存储字符串类型的元素并遍历
* @author Apple
*/
public class CollectionDemo {
public static void main(String[] args) {
//创建集合对象
Collection c = new ArrayList() ;//ArrayList是List集合的子实现类(存储和取出一致的)
//给集合中添加元素
c.add("hello") ;
c.add("world") ;
c.add("java") ;
c.add("java") ;
c.add("java") ;
c.add("java") ;
//获取迭代器对象
Iterator it = c.iterator() ;//底层使用ArrayList中的匿名内部类的形式:接口多态的形式(重点理解)
/* 由于当前集合中的元素获取完了,
* 如果没有元素,而还要去调用next()方法,那么就出现问题,
* 给当前加上一个判断就可以防止出现异常!
* 即hasNext()方法
* 由于集合中的元素不固定的,所有使用while循环
**/
//需求:获取字符串的同时,还要获取字符串长度
while(it.hasNext()){
//it.next()----获取集合的内容(对应类型的引用)
//Object obj = it.next()=new String("..")----向下转型
String s = (String)it.next() ;
System.out.println(s+"----"+s.length());
}
}
}
Iterator it = c.iterator() ;通过方法创建实例的说明-----类比Calendar类
随后会提到
实例5
package org.westos.collection_02;
//回忆快捷方式
public class Student {
private String name;
private int age;
public Student() {
super();
}
public Student(String name, int age) {
super();
this.name = name;
this.age = 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;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
测试类
package org.westos.collection_02;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
* 使用存储自定义对象并遍历
* 1)toArray():将集合转换成数组
* 2)集合专有遍历方式:迭代器遍历
* 注意:存储自定义对象使用迭代器遍历,it.next()不要使用多次(除非你想张冠李戴,3的倍数),否则会出现异常!!!(原因在代码下方)
* 使用迭代器遍历,使用的是while循环,可以是for循环吗?
* 答:可以,但是推荐使用while循环
* @author Orange
*/
public class CollectionTest {
public static void main(String[] args) {
//创建一个学生类
//创建集合对象
Collection c = new ArrayList() ;
//创建3个学生对象
Student s1 = new Student("张三", 26) ;
Student s2 = new Student("李四", 22) ;
Student s3 = new Student("王五", 28) ;
Student s4 = new Student("麻六", 28) ;
//给集合中添加元素
c.add(s1) ;
c.add(s2) ;
c.add(s3) ;
c.add(s4) ;
//获取迭代器对象
Iterator it = c.iterator() ;
//遍历(while常用)
while(it.hasNext()){
Student s = (Student)it.next() ;
System.out.println(s.getName()+"---"+s.getAge());//(1)
//System.out.println(((Student)it.next()).getName()+"----"+((Student)it.next()).getAge());//将(1)注释张冠李戴
/*
* 出错的原因:
* 当用hasNext()遍历到最后一个时,此时没有元素可以迭代,
* 出现NoSuchElementException异常---没有元素可以迭代
* */
}
System.out.println("----------------------------");
for(Iterator it2 = c.iterator();it2.hasNext();){
Student s = (Student) it2.next() ;
System.out.println(s.getName()+"---"+s.getAge());
}
}
}
Collection合集:
1---点击打开链接,2---点击打开链接,3---点击打开链接,4---点击打开链接
Iterator迭代器合集: