泛型通配符
泛型的通配符:不知道使用什么类型来接收的时候,此时可以使用?,?表示未知通配符。此时只能接受数据,不能往该集合中存储数据。
package com.claire.day12;
import java.util.ArrayList;
public class Test {
public static void main(String[] args) {
// 关系 String继承Object, Integer继承Number, Number继承Object
ArrayList<Object> list1 = new ArrayList<>();
ArrayList<String> list2 = new ArrayList<>();
ArrayList<Integer> list3 = new ArrayList<>();
ArrayList<Number> list4 = new ArrayList<>();
list2.add("哈哈");
list1.add(11);
// method1(list2);
// method1(list3);
// method1(list4);
method2(list2);
// method2(list3);
}
// 定义一个方法, 可以接受以上4个集合
public static void method1(ArrayList list){
list.add("haha");
Object obj = list.get(0);
System.out.println("obj" + obj);
System.out.println("list" + list);
}
public static void method2(ArrayList<?> list){
// list.add("haha"); 编译报错
Object obj = list.get(0);
System.out.println("obj" + obj);
System.out.println("list" + list);
}
}
通配符高级使用----受限泛型
之前设置泛型的时候,实际上是可以任意设置的,只要是类就可以设置。但是在JAVA的泛型中可以指定一个泛型的上限和下限。
泛型的上限:
- 格式: 类型名称 <? extends 类 > 对象名称
- 意义: 只能接收该类型及其子类
泛型的下限:
- 格式: 类型名称 <? super 类 > 对象名称
- 意义: 只能接收该类型及其父类型
package com.claire.day12;
import java.util.ArrayList;
public class Test2 {
public static void main(String[] args) {
// 关系 String继承Object, Integer继承Number, Number继承Object
ArrayList<Object> list1 = new ArrayList<>();
ArrayList<String> list2 = new ArrayList<>();
ArrayList<Integer> list3 = new ArrayList<>();
ArrayList<Number> list4 = new ArrayList<>();
method3(list3);
method3(list4);
method4(list1);
method4(list4);
// method4(list2); 报错
method4(list3);
}
public static void method1(ArrayList list){
list.add("haha");
Object obj = list.get(0);
System.out.println("obj" + obj);
System.out.println("list" + list);
}
public static void method2(ArrayList<?> list){
// list.add("haha"); 编译报错
Object obj = list.get(0);
System.out.println("obj" + obj);
System.out.println("list" + list);
}
// 泛型的上限: 格式: 类型名称 <? extends 类 > 对象名称 意义: 只能接收该类型及其子类
public static void method3(ArrayList<? extends Number> list){
}
public static void method4(ArrayList<? super Integer> list){
}
}
public boolean addAll(Collection<? extends E> c) {
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew); // Increments modCount
System.arraycopy(a, 0, elementData, size, numNew);
size += numNew;
return numNew != 0;
}
上面点addAll参数是一个Collection类型, 对于集合中元素限制不能大于E类型
综合案例
需求:
- 按照斗地主的规则,完成造牌洗牌发牌的动作。
具体规则:
使用54张牌打乱顺序,三个玩家参与游戏,三人交替摸牌,每人17张牌,最后三张留作底牌。
分析:
- 准备牌:
牌可以设计为一个ArrayList,每个字符串为一张牌。
每张牌由花色数字两部分组成,我们可以使用花色集合与数字集合嵌套迭代完成每张牌的组装。
牌由Collections类的shuffle方法进行随机排序。 - 发牌
将每个人以及底牌设计为ArrayList,将最后3张牌直接存放于底牌,剩余牌通过对3取模依次发牌。 - 看牌
直接打印每个集合。
package com.claire.day12;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
public class Test3 {
public static void main(String[] args) {
// - 准备牌
ArrayList<String> pokerBox = new ArrayList<>();
ArrayList<String> numbers = new ArrayList<>();
ArrayList<String> colors = new ArrayList<>();
numbers.add("J");
numbers.add("Q");
numbers.add("K");
numbers.add("A");
for (int i = 2; i <= 10 ; i++) {
// numbers.add(String.valueOf(i));
numbers.add("" + i);
}
colors.add("♣");
colors.add("♠");
colors.add("♦");
colors.add("♥");
pokerBox.add("大王");
pokerBox.add("小王");
for (String number: numbers){
for (String color:colors){
pokerBox.add( color + number);
}
}
// System.out.println(pokerBox);
// System.out.println(pokerBox.size());
// 洗牌
// Random random = new Random();
// random.setSeed(555);
// Collections.shuffle(pokerBox, random);
Collections.shuffle(pokerBox);
System.out.println(pokerBox);
// 发牌
ArrayList<String> player1 = new ArrayList<>();
ArrayList<String> player2 = new ArrayList<>();
ArrayList<String> player3 = new ArrayList<>();
ArrayList<String> diPai = new ArrayList<>();
for (int i = 0; i < pokerBox.size(); i++) {
String pai = pokerBox.get(i);
if (i >= 51){
diPai.add(pai);
}else if (i%3 ==0){
player1.add(pai);
}else if (i%3 ==1){
player2.add(pai);
}else if (i%3 ==2){
player3.add(pai);
}
}
// 显示
System.out.println("玩家一" + player1);
System.out.println("玩家二" + player2);
System.out.println("玩家三" + player3);
System.out.println("底牌" + diPai);
}
}
Collections类
java.utils.Collections是集合工具类,用来对集合进行操作。
常用方法如下:
- public static void shuffle(List<?> list):打乱集合顺序。
- public static void sort(List list):将集合中元素按照默认规则排序。
- public static void sort(List list,Comparator<? super T> ):将集合中元素按照指定规则排序。
public class Test4 {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
list.add(i);
}
Collections.shuffle(list);
System.out.println("打乱:" + list);
Collections.sort(list);
System.out.println("排序之后:" + list);
}
}
自定义类型比较
实体类
package com.claire.day12;
//public class Student implements Comparable<Student>{
public class Student {
private String name;
private int age;
private int score;
// 比较规则
// @Override
// public int compareTo(Student o) {
// // 前减后 升序排序
// // 后减前 降序排序
// return this.age - o.age;
// }
public Student() {
}
public Student(String name, int age, int score) {
this.name = name;
this.age = age;
this.score = score;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", score=" + score +
'}';
}
}
package com.claire.day12;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class Test5 {
public static void main(String[] args) {
Student s1 = new Student("张三", 15, 90);
Student s2 = new Student("李四", 12, 88);
Student s3 = new Student("王五", 16, 70);
Student s4 = new Student("赵六", 20, 60);
ArrayList<Student> list = new ArrayList<>();
list.add(s1);
list.add(s2);
list.add(s3);
list.add(s4);
// System.out.println(s1.compareTo(s2)); // 3
// System.out.println(s1.compareTo(s3)); //-1
for (Student s :list){
System.out.println(s);
}
// Collections.sort(list);
Collections.sort(list, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.getAge() - o2.getAge();
}
});
System.out.println("排序后");
for (Student s :list){
System.out.println(s);
}
}
}