1.ArrayList
1.1回顾
- 集合:存放多个数据类型或者是对象的容器
- 持有的数据:
- 单一数据—可以定义对应类型的变量直接持有
- 多个数据—可以使用数组的方式记录,通过索引来访问数据
- 在oop的基础上,可以使用集合的方式进行记录,常用ArrayList
- 基本使用:
- 1.创建集合对象
- 2.向集合中添加数据
- 3.从集合中获取元素/其他信息
| 方法声明 | 功能描述 |
|---|---|
| boolean add(Object obj) | 将指定元素obj追加到集合的末尾 |
| Object get(int index) | 返回集合中指定位置上的元素 |
| int size() | 返回集合中的元素个数 |
package com.igeek_Collection.ArrayList.ArrayList_01;/*** @author Lynn* @create 2020-12-07-14:05*/import java.sql.SQLOutput;import java.util.ArrayList;public class ArrayListDemo {public static void main(String[] args) {//创建集合对象ArrayList<Integer> list=new ArrayList<>();list.add(20);list.add(30);list.add(40);//从集合中获取元素Integer i= list.get(1);System.out.println(i);//获取长度Integer l=list.size();System.out.println(l);//遍历for (int j = 0; j < list.size() ; j++) {System.out.println(list.get(j));}}}
1.2 练习
package com.igeek_Collection.ArrayList.ArrayList_02;/*** @author Lynn* @create 2020-12-07-14:32*/import java.util.ArrayList;import java.util.Iterator;/*** 实现功能:** 定义一个测试类,在测试类中定义一个集合,集合中存储3个数据--Person对象,这三个人的属性分别为* Jack 18* rose 16* aobama 60** 最终遍历的集合,分别打印三个人的姓名,年龄* 并打印三个人的总年龄*/public class ArrayListDemo {public static void main(String[] args) {//创建集合对象ArrayList<Person> list=new ArrayList<>();//添加对象list.add(new Person("Jack",18));list.add(new Person("Rose",16));list.add(new Person("AObama",60));// System.out.println(list);//调用Iterator方法,获取迭代器的对象Iterator<Person> iterator= list.iterator();//声明一个变量用来保存年龄int sum=0;//迭代集合while (iterator.hasNext()){//问//取Person p= iterator.next();System.out.println(p.getName()+":"+p.getAge());//年龄累加sum+=p.getAge();}System.out.println("三个人的总年龄是:"+sum);}}
2.Iterator—迭代器
迭代器的使用:
- 迭代器:就是一个用来遍历数据的工具
- 在java中不止ArrayList一种集合,java中提供了众多的集合
- 不同的容器(集合),提供了不同的数据存储
- 不同的集合特点不同,ArrayList是有序且可重复的集合
*但是由于集合的不同,所以有些集合是没有下标的,就不可以使用get()方法来获取数据 - 可以通过迭代器来处理:
- 所有的集合通过获取元素的方法并不是唯一的,但是可以通过统一使用迭代器来处理
- 迭代器:Iterator—接口
- 利用迭代器进行遍历的时候需要以下几步:
- 1.问—是否存在下一个元素
- 2.取—把这个存在的下一个元素取出
- 3.删—可以处理
- Iterator接口的常用方法如下:

hasNext()方法:用来判断集合中是否有下一个元素可以迭代。如果返回true,说明可以迭代。
next()方法:用来返回迭代的下一个元素,并把指针向后移动一位。
while (iterator.hasNext()){//问//取Integer thisNumber= iterator.next();System.out.println(thisNumber);}
- 理解:
- 在迭代器中其实有一个指针,通过指针来进行问取操作 ```java package com.igeek_Collection;
/**
- @author Lynn
- @create 2020-12-07-14:13 */
import java.util.ArrayList; import java.util.Iterator;
public class IteratorDemo {
public static void main(String[] args) {
ArrayList
//利用迭代器来处理--import java.util.Iterator;//Iterator是一个接口,不能直接实例化,要通过集合去获取Iterator<Integer> iterator= list.iterator();//使用迭代器来遍历while (iterator.hasNext()){//问//取Integer thisNumber= iterator.next();System.out.println(thisNumber);}}
}
<a name="lt8e5"></a># 3.当前案例用于演示制造异常--这个异常在以后的操作中可能会出现```javapackage com.igeek_Collection.ArrayList.ArrayList_03;/*** @author Lynn* @create 2020-12-07-14:58*/import com.igeek_Collection.ArrayList.ArrayList_02.Person;import java.util.ArrayList;import java.util.Iterator;/*** 当前案例用于演示制造异常--这个异常在以后的操作中可能会出现** 使用集合的存储多个对象的时候,当遇到16岁的人时就添加一个90岁的人* 该案例中,可能会出现并发修改异常,迭代器所认为的集合状态和集合真正的状态不统一,所以报错*/public class CurrentModificationDemo {public static void main(String[] args) {//创建集合对象ArrayList<Person> list = new ArrayList<>();//添加对象list.add(new Person("Jack", 18));list.add(new Person("Rose", 16));list.add(new Person("AObama", 60));list.add(new Person("Lucy", 25));list.add(new Person("Tom", 30));list.add(new Person("Jerry", 90));//调用迭代器Iterator<Person> iterator = list.iterator();//制造异常--添加元素while (iterator.hasNext()) {Person p = iterator.next();System.out.println(p.getAge() + "岁的" + p.getName());//判断--年龄是不是为16岁if (p.getAge() == 16) {//存在则添加90岁的人list.add(new Person("Jerry", 90));}}}}
4.当前案例用于演示制造异常—这个异常在以后的操作中可能会出现—解决方案
package com.igeek_Collection.ArrayList.ArrayList_03;/*** @author Lynn* @create 2020-12-07-14:58*/import com.igeek_Collection.ArrayList.ArrayList_02.Person;import java.util.ArrayList;import java.util.Iterator;/*** 当前案例用于演示制造异常--这个异常在以后的操作中可能会出现--解决方案** 使用集合的存储多个对象的时候,当遇到16岁的人时就添加一个90岁的人* 该案例中,可能会出现并发修改异常,迭代器所认为的集合状态和集合真正的状态不统一,所以报错*/public class CurrentModificationDemo2 {public static void main(String[] args) {//创建集合对象ArrayList<Person> list = new ArrayList<>();//添加对象list.add(new Person("Jack", 18));list.add(new Person("Rose", 16));list.add(new Person("AObama", 60));list.add(new Person("Lucy", 25));list.add(new Person("Tom", 30));//调用迭代器Iterator<Person> iterator = list.iterator();//制造异常--添加元素while (iterator.hasNext()) {Person p = iterator.next();System.out.println(p.getAge() + "岁的" + p.getName());//判断--年龄是不是为16岁if (p.getAge() == 16) {//存在则添加90岁的人list.add(new Person("Jerry", 90));//1.当遇到16岁的人的时候,就退出当前操作break;}}//2.曲线救国--重新迭代集合中的数据--重新获取迭代器Iterator<Person> iterator2 = list.iterator();while (iterator2.hasNext()){//如果有就取出Person p2=iterator2.next();System.out.println(p2.getAge() + "岁的" + p2.getName());}}}
5.增强for循环
增强for循环是JDK1.5以后出来的一个高级for循环,专门用来遍历数组和集合的。
它的内部原理其实是个Iterator迭代器,所以在遍历的过程中,不能对集合中的元素进行增删操作。
它用于遍历Collection和数组。通常只进行遍历元素,不要在遍历的过程中对集合元素进行增删操作。
package com.igeek_Collection.ForEach;/*** @author Lynn* @create 2020-12-07-15:22*/import java.util.ArrayList;/*** 增强for循环:* 用来完成容器中获取元素的** 格式:* for(容器内的类型 临时变量:容器的引用){* 内部可以直接使用临时变量来访问数据* }** 注意:增强for循环的底层就是一个Iterator,因为迭代器在处理数据的时候有可能会出现并发修改的异常,* 所以增强for循环中就不进行数据的添加或者删除操作,只是用于查看数据** 可以理解为是迭代器的一个实用展示*/public class ForEachDemo {public static void main(String[] args) {//创建一个集合对象ArrayList<Integer> list=new ArrayList<>();list.add(10);list.add(100);list.add(1000);list.add(10000);//使用增强for循环遍历for(Integer thisNumber:list){System.out.println(thisNumber);}System.out.println("----------------------");//遍历字符串类型的数组String[] arr={"王嘉尔","王一博","卡卡西","猪猪侠"};for(String name:arr){System.out.println(name);}}}
6.类泛型使用的测试:
package com.igeek_Collection.Izidingyifanxing;/*** @author Lynn* @create 2020-12-07-15:37*//*** 演示自定义泛型的使用--类使用类型** 泛型是jdk5.0推出的新特性** 在一个类中定义成员变量,使用泛型** 不指定其数据类型,是一个不确定的数据类型* 创建不同对象的时候,指定不同的数据类型*/public class MyClass<T> {//我的泛型字段private T myFiled;public MyClass() {}public MyClass(T myFiled) {this.myFiled = myFiled;}public T getMyFiled() {return myFiled;}public void setMyFiled(T myFiled) {this.myFiled = myFiled;}}
package com.igeek_Collection.Izidingyifanxing;/*** @author Lynn* @create 2020-12-07-15:41*//*** 类泛型使用的测试:** 泛型类:在类中使用泛型** 定义:类型的后面<变量> 如:class<E>* 使用:创建对象的时候确定类型** 一般定义的泛型使用:E T K V*/public class MyClassTypeDemo {public static void main(String[] args) {//测试自己定义的类泛型MyClass<String> my=new MyClass();//调用使用泛型类的方法my.setMyFiled("王嘉尔");String myFiled=my.getMyFiled();System.out.println(myFiled);System.out.println("-----------------------------");//创建对象的时候指定IntegerMyClass<Integer> my1=new MyClass();my1.setMyFiled(88);System.out.println(my1.getMyFiled());}}
7.定义和使用含有泛型的方法
package com.igeek_Collection.Izidingyifanxing.fanxingfangfa;/*** @author Lynn* @create 2020-12-07-16:06*//*** 演示泛型方法--在类中定义一个成员变量,使用泛型** 格式:* 修饰符<T,Q,E············> 返回值的类型 方法名(T t,Q q········){* //方法上定义的泛型在返回值的前面* }*/public class MyClassType {//定义泛型的方法public <T> void method(T t){System.out.println(t);}}
package com.igeek_Collection.Izidingyifanxing.fanxingfangfa;/*** @author Lynn* @create 2020-12-07-16:06*/import com.igeek_Collection.Izidingyifanxing.fanxingfangfa.MyClassType;/*** 测试泛型方法** 泛型方法:方法的返回值面前加上<变量>* 使用:调用方法的时候确定类型*/public class MyClassTypeDemo2 {public static void main(String[] args) {//实例化自己定义的类MyClassType my=new MyClassType();//调用方法的时候确定类型my.method("ABC");//Stringmy.method(12); //Integermy.method(12.12);//Doublemy.method(true); //Booleanmy.method('A'); //Character}}
8.泛型接口
package com.igeek_Collection.Izidingyifanxing.fanxingfangfa3;/*** @author Lynn* @create 2020-12-07-16:15*//*** 自定义泛型的接口** 接口用于规范子类的内容--写抽象方法*/public interface MyInterType<T> {//接口中的方法使用接口泛型public void method(T t);}
package com.igeek_Collection.Izidingyifanxing.fanxingfangfa3;/*** @author Lynn* @create 2020-12-07-16:17*//*** 接口的实现类** 定义类的时候,仍然不实现接口的数据类型* 则此时相当于将这种不确定的数据类型使用到了子类当中* 包含不确定的数据类型的类就是泛型类*** 在实现接口的时候,必须实现接口中所有的抽象方法和泛型--用于父类中不确定子类具体类型的时候使用*/public class MyClassInter<T> implements MyInterType<T> {@Overridepublic void method(T t) {System.out.println(t);}}
package com.igeek_Collection.Izidingyifanxing.fanxingfangfa3;/*** @author Lynn* @create 2020-12-07-16:21*//*** 测试泛型接口--在使用的时候才会确定类型*/public class MyClassInterTest {public static void main(String[] args) {//实例化子类MyClassInter<String> my=new MyClassInter<>();// my.method(23232326262333);//泛型不匹配my.method("年轻的时候不拼搏,老了拿什么谈曾经");}}
package com.igeek_Collection.Izidingyifanxing.fanxingfangfa4;/*** @author Lynn* @create 2020-12-07-16:38*/import java.util.ArrayList;/*** 泛型的作用:约束数据类型* 优点:* 1.提高了程序的安全性:将运行期的问题提前到编译期进行处理* 2.提高了程序的性能:省去了类型之间转换的时间** 泛型的通配符:* 演示--谨慎使用--用于汇总数据*/public class Demo {public static void main(String[] args) {//定义一个集合ArrayList<String> list=new ArrayList<>();list.add("王");list.add("嘉");list.add("尔");ArrayList<Integer> listB=new ArrayList<>();listB.add(1);listB.add(2);listB.add(3);//利用泛型的最高级别处理--泛型一定是对象类型--顶级父类--ObjectObject o=new String();//向上造型ArrayList<Object> listA=new ArrayList<>(list);listA.add("好");listA.add("帅");System.out.println(listA);ArrayList<Object> listA1=new ArrayList<>(listB);listA1.add("好");listA1.add("帅");System.out.println(listA1);}}
9.扑克牌案例
/*** @author Lynn* @create 2020-12-08-9:10*/import java.util.ArrayList;import java.util.Collections;/*** 按照斗地主的规则,完成洗牌发牌的动作。* ♣♦♠♥大☺小☺* 具体规则:* 使用54张牌打乱顺序* 三个玩家参与游戏,三人交替摸牌,每人17张牌,最后三张留作底牌。* 3.2 斗地主需求分析:* A:准备牌:* 牌可以设计为一个ArrayList<String>,每个字符串为一张牌。* 每张牌由花色、数字两部分组成,我们可以使用花色集合与数字集合嵌套迭代完成每张牌的组装。* 牌由Collections类的shuffle方法进行随机排序。* B:发牌:* 将每个人以及底牌设计为ArrayList<String>,将最后3张牌直接存放于底牌,剩余牌通过对3取模依次发牌。* C:看牌:* 直接打印每个集合*/public class CardDemo {public static void main(String[] args) {//准备牌//集合中记录的是54张牌ArrayList<String> list=new ArrayList<>();//定义花色--定义一个集合用于存在花色ArrayList<String> colors=new ArrayList<>();colors.add("♣");colors.add("♦");colors.add("♠");colors.add("♥");//定义一个集合用于存放数字ArrayList<String> numbers=new ArrayList<>();//使用循环赋值for (int i = 2; i <=10 ; i++) {numbers.add(i+"");}numbers.add("J");numbers.add("Q");numbers.add("K");numbers.add("A");//嵌套迭代的方式完成每张牌的组装--放了52张//利用增强for循环for (String thisColor:colors){//外层循环遍历花色for (String thisNumber:numbers){//内层循环遍历数字//通过花色与数字对应成每张牌String thisCard=thisColor+thisNumber;//字符串的拼接//将拼接好的牌放入整副牌的集合中list.add(thisCard);}}//补充大小王list.add("大☺");list.add("小☺");//测试// System.out.println(list);//洗牌---直接调用方法//Collections是一个集合工具类,提供了很多的集合中处理的静态方法Collections.shuffle(list);//测试// System.out.println(list);//发牌---将每个人以及底牌设置为一个集合,最后的3张底牌直接存放到底牌中,//剩余牌通过对3进行取余依次发牌ArrayList<String> player1=new ArrayList<>();ArrayList<String> player2=new ArrayList<>();ArrayList<String> player3=new ArrayList<>();ArrayList<String> dipai=new ArrayList<>();//使用普通for循环,通过下标进行处理//除了最后的三张牌,其他的都发给玩家for (int i = 0; i < list.size()-3; i++) {//获取当前这张牌String thisCard= list.get(i);//对3进行取余if (i%3==0){player1.add(thisCard);}else if (i%3==1){player2.add(thisCard);}else {player3.add(thisCard);}}//最后的3张底牌--从倒数第3张牌开始发for (int i = list.size()-3; i < list.size() ; i++) {//抽取这张牌String thisCard= list.get(i);dipai.add(thisCard);}//看牌System.out.println(player1);System.out.println(player2);System.out.println(player3);System.out.println(dipai);}}
