day07_面向对象(Collection、泛型)
一.集合
1.集合的介绍&集合和数组的区别
什么是集合:是一种Java中的容器
集合和数组的区别:
a.数组的长度固定 而集合的长度是可变的
b.数组可以保存任意类型 而集合只能保存引用类型
2.集合框架的介绍********
Collection 集合的根接口
-List 子接口(所有的实现类有索引)
-ArrayList 实现类
-LinkedList 实现类
-Vector 实现类(基本上不用了,底层实现和ArrayList差不多,但是性能较低)
-Set 子接口(所有的实现类无索引)
-HashSet 实现类
-LinkedHashSet 实现类
-TreeSet 实现类
3.Collection(无下标)中的通用方法******************
增:boolean add(E e)
删:boolean remove(Object obj)
改:无(无索引)
查:无(无索引)
其他:
int size():获取集合的长度
boolean isEmpty():判断集合中是否有元素
boolean contains(E e):判断集合中是否包含这个元素e
Object[] toArray():集合转数组
void clear():清空集合
二.集合的通用遍历方式——迭代器
1.集合迭代器的介绍和使用
什么是迭代器:
帮助我们从集合中取出元素对象
迭代器属于Iterator类型
public class TestIteratorDemo {
public static void main(String[] args) {
//1.创建ArrayList
Collection<String> cc = new ArrayList<String>();
cc.add("java");
cc.add("iso");
cc.add("python");
cc.add("php");
cc.add("c++");
cc.add("go");
//2.使用迭代器 遍历集合
//a.获取迭代器对象
Iterator<String> it = cc.iterator();
//b.先问
while (it.hasNext()) {
//c.后取
String next = it.next();
System.out.println(next);
}
}
}
迭代器的两个注意事项(两个异常):
a.NoSuchElementException 没有此元素异常
b.concurrentModificationException 并发修改异常
Java规定使用迭代器的过程中不能对集合进行增删操作,否则就抛出并发修改异常
注意:
迭代器的作用就是单纯的遍历!!!
2.迭代器的原理(画图)
底层原理:通过指针实现
hasNext()方法不会移动指针
next()方法会移动指针,并且取出指针移动经过的元素
3.增强for循环**********(foreach)
增强for循环是一种语法糖,底层就是迭代器(代码格式是底层实现,看不到源码)
格式:
for(数据类型 变量名:集合/数组){
拿到变量名
}
public class ForEachDemo {
public static void main(String[] args) {
//1.数组
int[] arr = {1,2,3,4,5,7,8,9,10};
for (int num : arr){
System.out.println(num);
}
//2.集合
ArrayList<String> names = new ArrayList<String>();
names.add("jack1");
names.add("jack2");
names.add("jack3");
names.add("jack4");
names.add("jack5");
for (String name : names) {
System.out.println(name);
}
}
}
注意:foreach循环底层就是迭代器,所以也不能在遍历的过程中增删元素,foreach一般用於单纯的遍历
三.泛型
1.什么是泛型
是一种不确定的类型,由程序员在具体使用才能确定
格式:
<E>,<P>,<MVP>,...
2.泛型的好处
ArrayList arr = new ArrayList(); // 不使用泛型默认是Object
添加:
arr.add("java");
arr.add(123);
arr.add(3.14);
arr.add('A');
取出:
String s = (String)arr.get(0); // 需要强转
String s = (String)arr.get(1); // 出现ClassCastException
泛型的好处:
a.避免了强制转换的麻烦
b.避免了类型转换异常,转移到了编译时期,变成编译失败
总结:
JDK1.5之后提供了泛型,Java强烈要求必须使用泛型!!!
Java的泛型是伪泛型,有种技术叫泛型的擦除,即在编译阶段会被替换 3.泛型的定义和使用
i.泛型类:类上加泛型
//泛型类定义
public class Dog<E> {
private E e;
public E getE() {
return e;
}
public void setE(E e) {
this.e = e;
}
}
//泛型类的使用
public class TestDog {
public static void main(String[] args) {
//1.使用泛型类
Dog<String> d1 = new Dog<String>();
d1.setE("aaa");
System.out.println(d1.getE());
Dog<Integer> d2 = new Dog<Integer>();
d2.setE(111);
System.out.println(d2.getE());
}
}
ii.泛型方法:在方法上加泛型
//泛型方法的定义
public class Pig {
public <T> void show(T t) {
System.out.println(t);
}
}
//泛型方法的使用
public class TestPig {
public static void main(String[] args) {
//1.创建对象
Pig p = new Pig();
//2.调用方法
p.<String>show("abc");
p.<Double>show(3.14);
}
}
iii.泛型接口:在接口上加泛型
//泛型接口的定义
public interface MyCollection<E> {
public abstract void setE(E e);
public abstract E getE();
}
//泛型接口有两种确定泛型的方式
//a.实现类在实现接口时,确定泛型
class MyClass1 implements MyCollection<Integer>{
@Override
public void setE(Integer integer) {
}
@Override
public Integer getE() {
return null;
}
}
//b.实现类咋实现接口时,不确定泛型,实现类继续保留泛型
class MyClass2<E> implements MyCollection<E>{
@Override
public void setE(E e) {
}
@Override
public E getE() {
return null;
}
}
//此时MyClass2<E>就是一个泛型类,回到泛型类的使用上
4.泛型通配符(泛型没有多态)(<?>不加其实效果一样)
泛型通配符:?代表任意泛型
public class TongPeiFuDemo {
public static void main(String[] args) {
//1.集合1
ArrayList<String> arr1 = new ArrayList<String>();
ArrayList<Integer> arr2 = new ArrayList<Integer>();
ArrayList<Double> arr3 = new ArrayList<Double>();
//2.调用方法
printArrayList(arr1);
printArrayList(arr2);
printArrayList(arr3);
//ArrayList<Object> arr = new ArrayList<String>();
}
//定义方法,接收一个集合
public static void printArrayList(ArrayList<?> arr){
}
5.泛型的上下限
ArrayList<?> 代表任意泛型的集合均可
上限:<? extends Animal>:代表泛型必须是Animal本类或者Animal的子类
下限:<? super Cat>:代表泛型必须是Cat本类或者Cat的父类
public class ShangXiaXianDemo {
public static void main(String[] args) {
Collection<Integer> list1 = new ArrayList<Integer>();
Collection<String> list2 = new ArrayList<String>();
Collection<Number> list3 = new ArrayList<Number>();
Collection<Object> list4 = new ArrayList<Object>();
//Object
// Number String
// Integer
getElement1(list1);
getElement1(list2);
getElement1(list3);
getElement1(list4);
getElement2(list1);
getElement2(list2);
getElement2(list3);
getElement2(list4);
}
// 泛型的上限:此时的泛型?,必须是Number类型或者Number类型的子类
public static void getElement1(Collection<? extends Number> coll){}
// 泛型的下限:此时的泛型?,必须是Number类型或者Number类型的父类
public static void getElement2(Collection<? super Number> coll){}
}
四.集合综合案例*******************
1.斗地主案例介绍
2.斗地主案例步骤分析
3.代码实现
public class DouDiZhuDemo {
public static void main(String[] args) {
// 斗地主案例步骤分析:
// 1.创建一副牌(54张)
ArrayList<String> cardBox = new ArrayList<String>();
String[] colors = {"♠", "♥", "♣", "♦"};
String[] nums = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"};
//嵌套循环
for (String color : colors) {
for (String num : nums) {
String card = color + num;
cardBox.add(card);
}
}
//大小王
cardBox.add("小王吧");
cardBox.add("大王吧");
// 2.洗牌(打乱顺序)
//Collections 一种工具类 其中的方法都是静态的
Collections.shuffle(cardBox);
// 3.发牌(轮流发给三个人,剩下3张)
ArrayList<String> p1 = new ArrayList<String>();
ArrayList<String> p2 = new ArrayList<String>();
ArrayList<String> p3 = new ArrayList<String>();
ArrayList<String> dp = new ArrayList<String>();
//发牌
for (int i = 0; i < cardBox.size() - 3; i++) {
//取出牌
String card = cardBox.get(i);
//发给谁????????????
// i = 0 3 6 p1
// i = 1 4 7 p2
// i = 2 5 8 p3
if (i % 3 == 0) {
p1.add(card);
} else if (i % 3 == 1) {
p2.add(card);
} else{
p3.add(card);
}
}
//底牌 53 52 51
dp.add(cardBox.get(51));
dp.add(cardBox.get(52));
dp.add(cardBox.get(53));
// 4.看牌(打印牌值)
System.out.println("令狐冲:"+p1);
System.out.println("田伯光:"+p2);
System.out.println("任盈盈:"+p3);
System.out.println("底 牌"+dp);
}
}
总结:
-[] 能够说出集合与数组的区别
-[] 能够使用Collection集合的常用功能
public boolean add(E e);
public boolean remove(E e);
public int size();
public boolean isEmpty();
public void clear();
public boolean contains(E e);
public Object[] toArray();
-[] 能够使用迭代器对集合进行取元素
a.获取迭代器 Iterator<E> it = 集合对象.iterator();
b.先判断 boolean b = it.hasNext();
c.后取出 E e = it.next();
-[] 能够使用增强for循环遍历集合和数组
格式:
for(数据类型 变量名:数组/集合){
底层是迭代器
}
-[] 能够使用集合存储自定义类型
-[] 能够使用泛型创建集合对象
-[] 能够阐述泛型通配符的作用
-[] 能够理解泛型上下限
上限:<? extends 类名>
下限:<? super 类名>
-[] 斗地主案例**************