第三章:集合02
一:增强for循环
- JDK 5.0后退出了一个新特性:叫做增强for循环,或者叫做foreach
- for循环的一种,简化了数组和集合的遍历,可以用来替代迭代器
- 增强for的目标不能是null
public class ForEachTest01 {
public static void main(String[] args) {
//int类型数组
int[] arr = {432,4,65,46,54,76,54};
//遍历数组(普通for 循环)
for (int i = 0;i<arr.length;i++){
System.out.println(arr[i]);
}
System.out.println("----------------------------");
//增强for (foreach)
/*
for (元素类型 变量名:数组集合) {
System.out.println(变量名);}
缺点:没有下标。在需要下标的循环中不建议使用增强for循环
*/
for (int i:arr) {
System.out.println(i);
}
}
二:迭代器
Iterator
- 迭代器,可以对已知集合进行遍历操作。
- hasNext():必须实现,返回一个boolean表示是否有下一个值
- next():必须实现,从集合中返回下一个元素。
public class Test01 {
public static void main(String[] args) {
//迭代器是所有collection通用化的一种方式,在map集合中不能使用,是所有collection以及子类的使用
//创建集合对象
Collection c = new ArrayList();
//添加元素
c.add("abc");
c.add("def");
c.add(100);
c.add(new Object());
//对集合Collection进行遍历/迭代
//第一步:获取集合对象的迭代器对象Iterator
Iterator it = c.iterator();
//第二步:通过以上获取迭代器对象开始迭代/遍历
/*
以下两个方法时迭代器Iterator中的方法
boolean hasNext() 如果仍有元素可以迭代,则返回 true。
Object next() 返回迭代的下一个元素。
*/
while (it.hasNext()){
//不管你当初存进去什么,取出来统一都是Object.
Object obj = it.next();
System.out.println(obj);
}
}
}
三:如何在循环遍历集合时删除集合元素??
-
对于集合操作的remove()方法的理解
boolean remove(Object o) 从此 collection 中移除指定元素。关于集合元素的remove 重点:当集合的结构发生改变时,不能新获取迭代器,否则会出现异常 重点:在迭代集合元素的过程中,不能用集合对象的remove方法删除元素会出现ava.util.ConcurrentModificationException异常 异常的根本原因:集合中元素删除了,但没有更新迭代器(迭代器不知道集合变化了)
public class Test02 {
public static void main(String[] args) {
Collection c = new ArrayList();
c.add(1);
c.add(2);
c.add(3);
Iterator it = c.iterator();
while (it.hasNext()){
Object obj = it.next();
//删除元素
//删除元素之后,集合的结构发生了变化,应该重新去获取迭代器
//但是,循环下一次的时候并没有重新获取迭代器,会出现异常:java.util.ConcurrentModificationException
//c.remove(obj);//直接通过集合去删除元素,没有通知迭代器(导致迭代器的快照和原集合状态不同)
it.remove();//删除的一定是迭代器指向的当前元素
System.out.println(obj);
}
}
}
四:什么是泛型
-
JDK 5.0之后推出的新特性:泛型
-
泛型这种语法机制,只在程序编译阶段起作用,只是给编译器参考的。(运行阶段泛型没用)
-
使用泛型的好处是什么??
第一:集合中存储的元素统一
了
第二:从集合取出的元素类型是泛型指定的数据类型,不需要进行大量的“向下转型”。 -
泛型的缺点是什么??
导致集合中数据类型缺乏多样性
public class GenericTest01 {
public static void main(String[] args) {
/*
//不使用泛型
List myList = new ArrayList();
//准备对象
Cat c = new Cat();
Bird b = new Bird();
//将对象添加到集合中
myList.add(c);
myList.add(b);
//遍历集合,取出Animal,让他move
Iterator it = myList.iterator();
while (it.hasNext()){
Object obj = it.next();
if (obj instanceof Animal){
Animal a = (Animal)obj;
a.move();
}
}
*/
//使用JDK5之后的泛型机制\
//使用泛型是指定集合中存储的数据类型
List<Animal> myList = new ArrayList<Animal>();
//准备对象
Cat c = new Cat();
Bird b = new Bird();
//将对象添加到集合中
myList.add(c);
myList.add(b);
Iterator<Animal> it = myList.iterator();
while (it.hasNext()){
Animal a = it.next();
a.move();
}
}
}
class Animal{
//父类方法
public void move(){
System.out.println("动物在移动");
}
}
class Cat extends Animal{
//子类特有方法
public void catchMouse(){
System.out.println("猫抓老鼠");
}
}
class Bird extends Animal{
//子类特有方法
public void fly(){
System.out.println("鸟儿在飞翔");
}
}
1. 钻石表达式
- 自动类型推断机制
/*
JDK8之后引入:自动类型推断机制。(又称为钻石表达式)
*/
public class GenericTest02 {
public static void main(String[] args) {
List<Animal> myList = new ArrayList<>();
myList.add(new Animal());
myList.add(new Cat());
myList.add(new Bird());
//遍历
Iterator<Animal> it = myList.iterator();
while (it.hasNext()){
Animal a = it.next();
a.move();
}
}
}
2.如何在自己写类的时候给与泛型机制
/*
自定义泛型
//总结:泛型的作用:
在new对象时给定指定的数据类型
当类使用泛型但new对象时没有给定指定的数据类型时:默认数据类型是Object
*/
public class GenericTest03<asdasdfslk>{
public static void main(String[] args) {
//当new对象时指定泛型
GenericTest03<String> gt = new GenericTest03<>();
gt.doSome("123");
//当new对象时不指定泛型
GenericTest03 gt1 = new GenericTest03();
gt1.doSome(123);
}
public void doSome(asdasdfslk o){
System.out.println(o);
}
}