集合框架介绍
Collection集合常用功能
Collection接口:所有单列集合的最顶层的接口,里面定义了所有单列集合共性的方法,任意的的单列集合都可以使用Collection接口中的方法
共性方法
import java.util.ArrayList;
import java.util.Collection;
public class t1 {
public static void main(String[] args){
//创建集合对象,可以使用多态
Collection<String> coll = new ArrayList<>();
System.out.println(coll); //[]
//add(E e)把给定对象添加到当前集合中
coll.add("张三");
coll.add("李四");
coll.add("王五");
System.out.println(coll); //[张三, 李四, 王五]
//remove(E e):把给定的对象在当前集合中删除
coll.remove("王五");
//contains(E e):判断当前集合是否包含给定对象,包含true,不包含false
boolean b1 = coll.contains("李四");
System.out.println("b1:"+b1);//true
//isEmpty():判断当前集合是否为空
boolean b2 = coll.isEmpty();
System.out.println("b2:"+b2);//false
//size():返回集合中元素的个数
int size = coll.size();
System.out.println("size:"+size);//2
//toArray():把集合变成一个数组
Object[] arr = coll.toArray();
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);//张三 李四
}
//clear(:清空集合中所有的元素,但是不删除集合,集合还存在
coll.clear();
System.out.println(coll);//[]
}
}
Iterator接口介绍
迭代器使用场景?
对于Collection接口中是没有索引的,你是无法对其进行遍历循环拿到其中元素的,怎么解决取出元素的问题哪??这个时候就可以使用迭代器啦.
- 总结一句话:对于数组无索引情况使用迭代取,取出数组内部元素
Iterator常用方法
注意事项:
1.Iterator迭代器,是一个接口,我们无法直接使用,需要使用Iterator接口的实现类对象
2.Iterator迭代器获取实现类的方式比较特殊Collection接口中有一个方法,叫iterator(),这个方法返回的就是迭代器的实现类对象
迭代器使用步骤:
1.使用集合中的方法iterator()获取迭代器的实现类对象,使用Iterator接口接收(多态)
2.使用Iterator接口中的方法hasNext判断还有没有下一个元素
3.使用Iterator接口中的方法next取出集合中的下一个元素
迭代器的代码实现
package test.code.src.cn.itcast.day11.demo08;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class t1 {
public static void main(String[] args){
//创建一个集合对象
Collection<String> coll = new ArrayList<>();
coll.add("张三");
coll.add("张李四");
coll.add("王五");
coll.add("赵六");
//1.创建实现类对象
Iterator<String> it = coll.iterator();//多态
//2.使用jIterator接口中的方法hasNext判断还有没有下一个元素
boolean b = it.hasNext();
System.out.println(b);//true
//3.取元素
String s = it.next();
System.out.println(s);//张三
//使用循环优化
while (it.hasNext()){
String s1 = it.next();
System.out.println(s1);
}
}
}
增强for循环
for each循环使用场景是什么?
专门用来遍历数组和集合的.
格式:
for(集合/数组的数据类型 变量名:集合名/数组名){
sout(变量名);
}
import java.util.ArrayList;
public class t1 {
public static void main(String[] args){
demo02();
}
private static void demo02() {
ArrayList<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
for (String s : list) {
System.out.println(s);//aaa bbb ccc
}
}
private static void demo01() {
int[] arr={1,2,3,4,5};
for (int i : arr) {
System.out.println(i);// 1 2 3 4 5
}
}
}
注意事项:
1.在变量的过程中,不能对集合的元素进行增删操作
2.增强for遍历的对象只能数组或集合
泛型的概念
泛型的基本概念
泛型:是一种未知的数据类型,当我们不知道使用什么数据类型的时候,可以使用泛型
泛型也可以看成一个变量,用来接收数据类型
E e:Element 元素
T t:Type 类型
泛型的应用场景是什么?
Arraylist集合在定义的时候,不知道集合中会存储什么类型的数据,所以使用泛型
那么什么时候泛型会被确定?
创建集合对象的时候,就会确定泛型的数据类型
ArrayListlist = new ArrayList();
使用泛型的好处
首先,创建集合对象,我们不使用泛型的情况
好处:
集合不使用泛型,默认的类型就是Object类型,可以存储任意类型的数据
弊端:
不安全,会引发异常
import java.util.ArrayList;
import java.util.Iterator;
public class t1 {
public static void main(String[] args){
demo02();
}
private static void demo02() {
//没有写泛型:<>
ArrayList list = new ArrayList();
list.add("abc");
list.add(1);
Iterator it = list.iterator();
while (it.hasNext()){
Object obj = it.next();
System.out.println(obj);//abc 1
/*我们要使用String类的特有方法Length,
但是多态弊端是多态不能使用子类特有方法,
如果要使用需要向下转型*/
//向下转型
String s = (String) obj;
/*抛出异常ClassException类型转换异常,
不能把Integer类型转换为String类型,
*/
System.out.println(s.length());
}
}
}
因为你没有使用泛型,所以数据类型并没有统一,一个集合对象可能会被传入多种数据类型.当你取出,想使用子类方法时,就会面临,使用String特有的方法,而集合中的其他数据类型无法转换成String类型,而产生异常.
那么我们来看一下,使用泛型的情况
好处:
1.避免了类型转换的麻烦,存储的是什么类型,取出的就是什么类型
2.把运行期异常,提升到了编译期
弊端:
泛型是什么类型,就只能存储什么类型的数据
import java.util.ArrayList;
import java.util.Iterator;
public class t1 {
public static void main(String[] args){
demo02();
}
private static void demo02() {
ArrayList<String> list = new ArrayList<>();
list.add("abc");
//list.add(1)直接报错
Iterator<String> it = list.iterator();
while (it.hasNext()){
String s = it.next();
System.out.println(s.length());//3
}
}
}
定义和使用含有泛型的类
等于一个含有泛型的类
public class GenericClass<E> {
private E name;
public E getName() {
return name;
}
public void setName(E name) {
this.name = name;
}
}
主程序
import java.util.ArrayList;
import java.util.Iterator;
public class t1 {
public static void main(String[] args){
GenericClass<Integer> gc1 = new GenericClass<>();
gc1.setName(1);
Integer name = gc1.getName();
System.out.println(name); //1
//泛型使用String
GenericClass<String> gc2 = new GenericClass<>();
gc2.setName("马格");
String name1 = gc2.getName();
System.out.println(name1); // 马格
}
}
定义和使用含有泛型的方法
如何定义和使用泛型的方法?
泛型定义在方法的修饰符和返回值类型之间
含有泛型的方法,在调用方法的时候确定泛型的数据类型
传递什么类型的参数,泛型就是什么类型
格式:
修饰符 <泛型> 返回值 方法名称(参数列表(使用泛型)){
方法体;
}
创建一个含有泛型方法的类
package test.code.src.cn.itcast.day11.demo08;
public class GenericClass {
public <M> void method01(M m){
System.out.println(m);
}
//定义一个含有泛型的静态方法
public static <S> void method02(S s){
System.out.println(s);
}
}
主程序
import java.util.ArrayList;
import java.util.Iterator;
public class t1 {
public static void main(String[] args){
GenericClass gc = new GenericClass();
//传递什么类型,泛型就是什么类型
gc.method01(10);
gc.method01("abc");
gc.method01(true);
GenericClass.method02(10);
GenericClass.method02("abc");
GenericClass.method02(true);
}
}
定义和使用含有泛型的接口
定义格式
修饰符 interface接口名<代表泛型的变量>{
}
创建一个接口
public interface GenericInterface<I> {
public abstract void method(I i);
}
方法一:创建一个实现类,自定义泛型
//自定义泛型
public class GenericInterImpl implements GenericInterface<String>{
@Override
public void method(String s) {
System.out.println(s);
}
}
方法二:创建一个实现类,接口使用什么类型,实现类就使用什么泛型.类跟着接口走
//接口使用什么类型,实现类就使用什么泛型.类跟着接口走
public class GenericInterImpl2<I> implements GenericInterface<I> {
@Override
public void method(I i) {
System.out.println(i);
}
}
泛型通配符
泛型的通配符的使用场景是什么?
不知道使用什么类型来接收的时候,此时可以使用?,?表示任意的数据类型
import java.util.ArrayList;
import java.util.Iterator;
public class t1 {
public static void main(String[] args){
ArrayList<Integer> list01 = new ArrayList<>();
list01.add(1);
list01.add(2);
ArrayList<String> list02 = new ArrayList<>();
list02.add("a");
list02.add("b");
demo01(list01);
demo01(list02);
}
private static void demo01(ArrayList<?> list) {
Iterator<?> it = list.iterator();
while (it.hasNext()){
Object next = it.next();
System.out.println(next);
}
}
}
泛型的上下限限定格式(只要求看懂源码即可平时很少使用)
上限限定:? extends E 代表使用的泛型只能是E类型的子类或本身
下限限定:? super E 代表使用的泛型只能是E类型的父类或本身
注意事项:
1.通配符不能创建对象使用
2.通配符只能作为方法的参数使用
当使用通配符时,此时只能接受数据,不能往该集合中存储数据
斗地主案例的实现
**取模% 后面的数往前凑,拿前面减后面凑的数,就是结果
5%2 (22=4)= 1
3%2 (21=2) =1
7%5 (5*1=5) = 2
如何实现发牌:
索引值%3 有三个值(0,1,2) 0%3=0 1%3=1 2%3=2 3%3=1
import java.util.ArrayList;
import java.util.Collections;
public class t1 {
public static void main(String[] args) {
ArrayList poker = new ArrayList<>();
String[] num = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "j", "Q", "K"};
String[] color = {"♦", "♣", "♥", "♠"};
poker.add("大王");
poker.add("小王");
for (String s : num) {
for (String s1 : color) {
poker.add(s + s1);
}
}
//洗牌
shuffle(poker);
//发牌
ArrayList<String> player01 = new ArrayList<>();
ArrayList<String> player02 = new ArrayList<>();
ArrayList<String> player03 = new ArrayList<>();
ArrayList<String> hand = new ArrayList<>();
for (int i = 0; i < poker.size(); i++) {
if (i>=51){
hand.add((String) poker.get(i));
}
if (i%3 == 0){
player01.add((String) poker.get(i));
}
else if (i%3 ==1){
player02.add((String) poker.get(i));
}
else if (i%3 == 2){
player03.add((String) poker.get(i));
}
}
//看牌
System.out.println(player01);
System.out.println(player02);
System.out.println(player03);
System.out.println(hand);
}
private static void shuffle(ArrayList list) {
Collections.shuffle(list);
}
}