荐 Collection集合,Iterator迭代器,<>泛型
Collection
集合概述:
集合作为容器用来存储,管理大量的对象(引用),这些集合内部cc爱用了不同的数据结构来存储元素,这些数据结构的不同导致了每种集合的增删改查效率不同。
数据结构会另开一篇。
Java常用集合体系:
Collection接口的常用方法
由于Collection是一个接口,所以该类中全部都是抽象方法,调用时会使用多态(父类型引用指向子类型对象)。主要了解这些方法的作用。
增:
public boolean add(E e);//把给定的对象添加到集合中
删:
- public void clear();//清空集合中所有元素。
- public boolean remove(E e);//把给定的对象在集合中删除
改:【无】
查:
- public boolean contains(Object obj);//判断当前集合是否包含给定元素
- public boolean isEmpty();//判断集合是否为空
- public int size();//返回当前集合元素的个数。
- public Object[] toArray();//把集合中的元素储存在数组中。
- public Iterator iterator();//获取一个迭代器,用于遍历集合元素
代码演示:
package Collection集合的增删改查Test;
import java.util.ArrayList;
import java.util.Collection;
public class Demo01 {
public static void main(String[] args) {
//多态,父类型引用指向子类型对象
Collection<String> list = new ArrayList<String>();
//增:
//调用子类ArrayList重写的add方法:向集合中添加元素
list.add("张三");
list.add("李四");
list.add("王五");
list.add("赵六");
list.add("冯七");
for (String s:list) {
System.out.println(s);
}
//删:
//clear()删除集合中所有元素:
//list.clear();
System.out.println(list.size());
//remove(E e):将给定的元素在集合中删除。返回boolean值
list.remove("张三");
System.out.println("移除后元素有:");
for(String s:list){
System.out.println(s);
}
//改【无】
//查:
//contains(Object obj):查询给定元素是否存在集合中,返回boolean
boolean boo = list.contains("李四");
System.out.println(boo);
//isEmpty():判断集合是否为空,返回boolean;
boo = list.isEmpty();
System.out.println(boo);
//size()返回集合中元素的个数:
int sum = list.size();
System.out.println(sum);
//toArray():把集合元素储存在数组中;返回一个Object[]数组
Object[] obj = list.toArray();
for (int i = 0; i <obj.length ; i++) {
System.out.println(obj[i]);
}
}
}
迭代器Iterator
Collection中定义了一个遍历元素的方法:
public Iterator iterator();此方法可以获取一个迭代器,用于遍历集合元素。
代码演示
package iterator迭代器;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Demo01 {
public static void main(String[] args) {
Collection<String> list = new ArrayList<String>();
//增:
//调用子类ArrayList重写的add方法:向集合中添加元素
list.add("郭德纲");
list.add("柳岩");
list.add("成龙");
list.add("洪金宝");
//调用集合的iterator方法获取迭代器。
Iterator<String> it = list.iterator();
//调用迭代器Iterator<>中的hasNext判断集合中是否还存在元素。返回boolean值
while(it.hasNext()){
//调用next方法遍历集合中的元素。
System.out.println("获取一个元素"+it.next());
}
}
}
图解代码:
注意!!!
这个“迭代器”是“单向”的,只能从上到下。而且是“一次性”的。
如果想再次使用迭代器,就需要再次调用集合的iterator()方法,获取一个新的迭代器。
迭代器常见问题
一次hasNext(),然后多次next()----错误
代码演示:
package iterator迭代器;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Demo01 {
public static void main(String[] args) {
Collection<String> list = new ArrayList<String>();
//增:
//调用子类ArrayList重写的add方法:向集合中添加元素
list.add("郭德纲");
list.add("柳岩");
list.add("成龙");
list.add("洪金宝");
//调用集合的iterator方法获取迭代器。
Iterator<String> it = list.iterator();
//调用迭代器Iterator<>中的hasNext判断集合中是否还存在元素。返回boolean值
while(it.hasNext()){
//调用next方法遍历集合中的元素。
String str = it.next();
//不要再次使用next(),这样会导致输出结果不完整。
System.out.println("获取一个元素"+it.next());
}
/*
运行结果:
获取一个元素柳岩
获取一个元素洪金宝
*/
}
}
并发修改异常:
代码演示:
public class Demo03 {
public static void main(String[] args) {
//1.创建一个集合对象
Collection<String> list = new ArrayList<>();
list.add("郭德纲");//modCount++
list.add("柳岩");//modCount++
list.add("成龙");//modCount++
//2.获取迭代器
Iterator<String> it = list.iterator();
//3.遍历迭代器
while (it.hasNext()) {//cursor != size
String s = it.next();//next()-->调用:checkForComodification(){ modCount != expectedModCount}
// System.out.println(it.next());//不要再次调用it.next()
System.out.println(s);
if (s.equals("成龙")) {
//删除这个元素
//list.remove(s);//modCount++当通过迭代器 遍历时,使用"集合对象"删除元素,会引发:并发修改异常。
//可以通过"迭代器"对象去删除
it.remove();//OK的
}
}
System.out.println(list);//[郭德纲, 柳岩]
//作业:当删除倒数第二个元素时,不会抛异常,请问为什么??????
}
}
增强for循环
-
增强for是一个新语法(JDK1.5开始),用于代替某种情况下的普通for循环,语法更加简洁。
可以遍历:数组、集合语法格式:
for(数据类型 变量名 : 数组名/集合名){
//直接使用“变量名”
}
遍历数组:
//1.遍历数组
int[] arr = {1,3,242,43,5};
for (int a : arr) {//编译后:就是普通for循环,仅仅是写法上简单一些,没有提高效率
System.out.println(a);
}
3).遍历集合:
ArrayList<String> list = new ArrayList<>();
list.add("熊杰");
list.add("李天阳");
list.add("郭涛");
list.add("陈卫广");
for (String s : list) {//编译后:就是"迭代器"
System.out.println(s);
if (s.equals("陈卫广")) {
// list.remove(s);//仍然会引发"并发修改异常"。而且不能拿到"迭代器"对象,因为使用的是"增强for",此时还没有"迭代器"对象。
}
}
注意:
增强for的特点:没有"循环变量",所以如果循环过程中需要使用"循环变量",那就不能用增强for循环了
只有当:从第一个元素遍历到最后一个元素时,才需要使用增强for,仅仅是写法简单而已。
泛型
泛型概述及作用
- 在我们之前定义集合对象时,使用了“泛型”:
ArrayList list = new ArrayList<>(); - 泛型的作用:限制这个集合只能存储“某种类型”的引用,可以保证集合的安全。
在创建对象时,可以不用“泛型”:
public class Demo05 {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add("字符串");
list.add(10);//Integer对象
list.add(new Random());
//可以存储任何类型,存储的时候很强大,但取出的时候就会有麻烦
//如果取出时需要访问子类特有成员,就需要向下转型,就有风险
for (Object o : list) {//取出时只能是Object类型接收
//如果向下转型,就非常麻烦,而且有安全隐患
}
//所以,在使用集合时,通常我们只希望集合只存储一种元素
//泛型:就可以限制这个集合只存储某种类型的引用
ArrayList<String> strList = new ArrayList<>();
strList.add("只能存字符串");
ArrayList<Integer> intList = new ArrayList<>();
intList.add(10);//只能存Integer对象
for (Integer integer : intList) {//直接用Integer类型接收,安全的。
}
}
}
泛型的类
代码图解:
关于public class MyArrayList中的,这就是此类定义的“泛型”,只有这里定义了泛型,在创建对象时才可以指定“泛型类型”。
MyArrayList myArrayList = new MyArrayList<>();
的命名:
1).E:用什么字母都可以,可以大写、也可以小写;也可以是多个字母表示一个泛型名。
2).可以同时定义多个“泛型名”:<A,B,C>
泛型方法
在一个“方法”上也可以单独定义“泛型”
代码演示:
public class Demo07 {
public static void main(String[] args) {
//1.调用fun()方法时,可以不指定泛型,这样泛型没有起到作用
Demo07.fun("abc", 10, 3.14, true, '你');
//2.调用fun()方法时,使用泛型
Demo07.<String>fun("abc", "10", "3.14", "true", "你");
Demo07.<Integer>fun(10, 20, 30, 40, 50);
}
//定义一个方法,要求可以接收5参数,这5个参数可以是任何的引用类型,但5个参数必须是相同的类型
public static <T> void fun(T a1, T a2, T a3, T a4, T a5) {
}
}
泛型接口
在定义接口时,也可以指定“泛型”,语法跟“类”一样
代码演示:
//定义一个有"泛型"的接口
interface Animal<E>{
public void eat(E e);
}
//当子类实现有泛型的接口,或者继承有泛型的父类时
//1.子类可以:丢弃泛型【必须记住】
class Cat1 implements Animal{
@Override
public void eat(Object o) {
}
}
//2.子类可以:指定为某种固定类型【必须记住】
class Cat2 implements Animal<String>{
@Override
public void eat(String s) {
}
}
//3.子类可以:继承泛型,继续使用泛型【必须记住】
class Cat3<E> implements Animal<E>{
@Override
public void eat(E e) {
}
}
public class Demo08 {
public static void main(String[] args) {
//1.创建Cat1对象,不能指定类型
// Cat1<String> cat1 = new Cat1();//编译错误
//2.创建Cat2对象,也不能指定类型
// Cat2<String> cat2 = new Cat2();//编译错误
//3.创建Cat3对象,可以指定类型
Cat3<String> cat3 = new Cat3<>();//OK的
}
}
泛型通配符
假如有以下几个类定义:
class Person{}
class Student extends Person{}
class Teacher extends Person{}
class JavaStudent extends Student{}
1).<? extends E>:表示可以是:E及其E的任何子类类型。
2).<? super E>:表示可以是:E及其E的任何父类类型。
3).<?>:表示:可以接收任何类型。
代码演示:
public class Demo09 {
public static void main(String[] args) {
ArrayList<Person> list1 = new ArrayList<>();
ArrayList<Student> list2 = new ArrayList<>();
ArrayList<Teacher> list3 = new ArrayList<>();
ArrayList<JavaStudent> list4 = new ArrayList<>();
ArrayList<String> list5 = new ArrayList<>();
fun1(list1);//OK的
fun1(list2);//OK的
fun1(list3);//OK的
fun1(list4);//OK的
// fun1(list5);//不可以
fun2(list1);//OK的
fun2(list2);//OK的
// fun2(list3);//不可以
// fun2(list4);//不可以
// fun2(list5);//不可以
fun3(list1);//OK的
fun3(list2);//OK的
fun3(list3);//OK的
fun3(list4);//OK的
fun3(list5);//OK的
}
//1.要求定义一个方法,可以接收ArrayList集合,
// 集合里面可以是:Person及其他的任何子类类型,其他类型不可以
public static void fun1(ArrayList<? extends Person> list){//设置泛型的:上限
}
//2.要求定义一个方法,可以接收ArrayList集合,
//集合里面可以是:Student及其父类类型,其他类型不可以
public static void fun2(ArrayList<? super Student> list) {//设置泛型的:下限
}
//3.要求定义一个方法,可以接收ArrayList集合,
//集合里面可以是:任何引用类型。
public static void fun3(ArrayList<?> list) {
}
}
本文地址:https://blog.csdn.net/weixin_45144691/article/details/107343478
上一篇: 迭代器和foreach,底层工作原理和实现是怎么样的?
下一篇: 自媒体运营误区多 品牌营销仍是王道
推荐阅读
-
荐 Collection集合,Iterator迭代器,<>泛型
-
java基础(18):集合、Iterator迭代器、增强for循环、泛型
-
java基础第十二篇之集合、增强for循环、迭代器和泛型
-
JAVA基础之集合、Iterator迭代器、泛型及增强for循环
-
20200729集合框架与泛型(Iterator接口,Map接口,Collection类和泛型)
-
java基础(18):集合、Iterator迭代器、增强for循环、泛型
-
【 Collection集合、Iterator迭代器、泛型、泛型通配符 】
-
荐 Collection集合,Iterator迭代器,<>泛型
-
java基础第十二篇之集合、增强for循环、迭代器和泛型
-
迭代器、增强for、泛型用法集合