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.当前案例用于演示制造异常--这个异常在以后的操作中可能会出现
```java
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 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("-----------------------------");
//创建对象的时候指定Integer
MyClass<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");//String
my.method(12); //Integer
my.method(12.12);//Double
my.method(true); //Boolean
my.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> {
@Override
public 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);
//利用泛型的最高级别处理--泛型一定是对象类型--顶级父类--Object
Object 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);
}
}