目录

Java的泛型

JDK1.5以后出现的机制

为什么会有泛型呢?

泛型

泛型类

泛型方法

泛型接口

泛型通配符

?extends E

?superE

增强for

泛型类的测试

泛型方法的测试

泛型接口的测试

集合的嵌套遍历

案例一

案例二

集合嵌套案例(英雄联盟案例)

Java的泛型
JDK1.5以后出现的机制
为什么会有泛型呢?
早期的Object类型可以接受任意的对象类型,但是在实际的使用中,会有类型转换的问题。也就存在着隐患,所以Java提供了泛型来解决这个安全问题。

泛型
  就是把明确数据类型的工作,提前到了编译时期,在创建集合的时候明确数据类型。这样的做法有点像把数据类型当作参数一样进行传递,所以泛型还叫做:参数化类型。

泛型类
把泛型定义在类上
格式;public class 类名<泛型类型1,...>
注意:泛型类型必须是引用类型
泛型方法
把泛型定义在方法上
格式:public<泛型类型>返回类型 方法名(泛型类型.);
参考代码1:

import java.util.ArrayList;
import java.util.Iterator;
 
public class GenericDemo1 {
    public static void main(String[] args) {
        //创建List集合对象
        //JDK1.7之后会自动进行类型推断
        ArrayList list = new ArrayList();
 
        //向集合中添加元素
        list.add("hello");
        list.add("word");
        list.add("java");
        list.add("bigdata");
 
        //获取迭代器对象
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()){
 
            Object next = iterator.next();
            String s = (String)next;
            System.out.println(s);
 
        }
    }
}
输出结果:

hello
word
java
bigdata

在我们没有学习泛型前,iterator返回的是Object,下面我们将引入泛型的思想。

参考代码2:

import java.util.ArrayList;
import java.util.Iterator;
 
public class GenericDemo1 {
    public static void main(String[] args) {
        //创建List集合对象
        //JDK1.7之后会自动进行类型推断
        ArrayList<String> list = new ArrayList<String>();
 
        //向集合中添加元素
        list.add("hello");
        list.add("word");
        list.add("java");
        list.add("bigdata");
 
        //向上转型 10 -- int -- Integer
//        list.add(10);
 
        //获取迭代器对象
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()){
 
            String next = iterator.next();
            System.out.println(next + "---" +next.length());
 
        }
    }
}
 输出结果:

hello---5
word---4
java---4
bigdata---7

引用泛型之后用我们自己定的泛型类型,下面interator则会自动引用类型。

注意:添加元素到集合中必须是相同类型的,向上转型。

泛型接口
把泛型定义在接口上
格式:public interface 接口名<泛型类型1...>
泛型通配符<?>
任意类型,如果没有明确,那么就是Object以及任意的Java类了
?extends E
向下限定,E及其子类
?superE
向上限定,E及其父类
参考代码:

注意:我们要创建泛型类型类

import java.util.ArrayList;
 
public class GenericDemo2 {
    public static void main(String[] args) {
        //如果泛型里面的类型只用一个,并且明确数据类型的时候,前后必须要写一致
        ArrayList<Animal> list1 = new ArrayList<Animal>();
        ArrayList<Dog> list2 = new ArrayList<Dog>();
        ArrayList<Object> list3 = new ArrayList<Object>();
 
        //泛型通配符<?>
        //任意类型,如果没有明确,那么就是Object以及任意的Java类了
        ArrayList<?> objects1 = new ArrayList<Animal>();
        ArrayList<?> objects2 = new ArrayList<Dog>();
        ArrayList<?> objects3 = new ArrayList<Object>();
 
        //?extends E 向下限定,E及其子类
        ArrayList<? extends Animal> list4 = new ArrayList<Animal>();
        ArrayList<? extends Animal> list5 = new ArrayList<Dog>();
        ArrayList<? extends Animal> list6 = new ArrayList<Cat>();
//        ArrayList<? extends Animal> list7 = new ArrayList<Object>();
 
        //? super E 向上限定,E及其父类
        ArrayList<? super Animal> list7 = new ArrayList<Animal>();
        ArrayList<? super Animal> list8 = new ArrayList<Object>();
//        ArrayList<? super Animal> list9 = new ArrayList<Dog>();
 
    }
}
Dog类和Cat类需要 extend Animal类

? extends E只能向下限定,否则

? super E 只能向上限定,否则

Animal:

public class Animal {
}
Dog:

public class Dog extends Animal{
}
Cat:

public class Cat extends Animal {
}
增强for
简化数组和Collection集合的遍历
格式:

for(元素数据类型 变量 : 数组或者Collection集合){
      使用变量即可,该变量就是元素

}

好处:简化遍历

注意事项:增强for的目标要判断是否为null

把前面的集合代码遍历用增强for改进

参考代码1:

import java.util.ArrayList;
 
//将来能用增强for的时候,就用,可以消除黄色警告线
public class ForDemo1 {
    public static void main(String[] args) {
        //定义一个数组
        int[] arr = {1,2,3,4,5,6};
 
        //普通for循环
        System.out.println("使用普通for循环:");
        for (int i = 0;i < arr.length;i++){
            System.out.println(arr[i]);
        }
        System.out.println("===========================");
 
        //增强for循环
        System.out.println("使用增强for循环遍历:");
        for (int x : arr) {
            System.out.println(x);
        }
 
        System.out.println("===========================");
 
        //创建集合对象
        ArrayList<String> strings = new ArrayList<>();
 
        //向集合中添加元素
        strings.add("hello");
        strings.add("world");
        strings.add("java");
        strings.add("bigdata");
        strings.add("hadoop");
 
        System.out.println("使用增强for遍历集合:");
        //使用增强for循环遍历集合
        for (String string : strings) {
            System.out.println(string);
        }
 
    }
}
输出结果:

使用普通for循环:
1
2
3
4
5
6
===========================
使用增强for循环遍历:
1
2
3
4
5
6
===========================
使用增强for遍历集合:
hello
world
java
bigdata
hadoop

从运行结果来看我们想要的输出效果实现了,但是如果进行遍历的集合为空呢?

所以我们在遍历之前需要判断一下是不是为null 。

参考代码2:

import java.util.ArrayList;
 
//将来能用增强for的时候,就用,可以消除黄色警告线
public class ForDemo1 {
    public static void main(String[] args) {
        //定义一个数组
        int[] arr = {1,2,3,4,5,6};
 
        //普通for循环
        System.out.println("使用普通for循环:");
        for (int i = 0;i < arr.length;i++){
            System.out.println(arr[i]);
        }
        System.out.println("===========================");
 
        //增强for循环
        System.out.println("使用增强for循环遍历:");
        for (int x : arr) {
            System.out.println(x);
        }
 
        System.out.println("===========================");
 
        //创建集合对象
        ArrayList<String> strings = new ArrayList<>();
 
        //向集合中添加元素
        strings.add("hello");
        strings.add("world");
        strings.add("java");
        strings.add("bigdata");
        strings.add("hadoop");
 
        System.out.println("使用增强for遍历集合:");
        //判断集合元素是否为null
        if (strings!=null){
            for (String s : strings) {
                System.out.println(s);
            }
        }
 
    }
}
输出结果:

使用普通for循环:
1
2
3
4
5
6
===========================
使用增强for循环遍历:
1
2
3
4
5
6
===========================
使用增强for遍历集合:
hello
world
java
bigdata
hadoop

增强for循环其实就是用来替代迭代器的,怎么去验证呢?
使用并发修改异常验证:

ConcurrentModificationException并发异常。

泛型类的测试
参考代码:

创建GenericTooll类:

/*
        泛型类:  把泛型定义在类上
        格式:public class 类名<泛型类型1,…>
        注意:泛型类型必须是引用类型
        这里的<>里面的内容仅仅表示的是一种参数数据类型,参数类型是一种变量,
        既然是一种变量,就符合变量的命名规则,可以是任意符合标识符起名规则的名字。
 */
public class GenericTooll<T> {
   private T obj;
 
    public T getObj() {
        return obj;
    }
 
    public void setObj(T obj) {
        this.obj = obj;
    }
}
 创建GenericTest1测试类:

不加泛型,默认是Object类型

必须要跟泛型类类型一致

/*
   泛型类的测试
 */
public class GenericTest1 {
    public static void main(String[] args) {
 
        GenericTooll<String> gt1 = new GenericTooll<>();
        gt1.setObj("java");
 
        String obj = gt1.getObj();
        System.out.println(obj);
 
    }
}
 泛型方法的测试
参考代码:

创建GenericTool2类:

/*
        泛型方法
            把泛型定义在方法上
            格式:public <泛型类型> 返回类型 方法名(泛型类型 .)
 */
public class GenericTool2 {
    public <T> void show(T t){
        System.out.println(t);
    }
}
 创建GenericTest2测试类:

public class GenericTest2 {
    public static void main(String[] args) {
        //创建对象
        GenericTool2 gt = new GenericTool2();
        gt.show("hadoop");
        gt.show("23");
        gt.show(true);
    }
}
输出结果:

hadoop
23
true

泛型接口的测试
创建GenericTool3接口:

public interface GenericTool3<T> {
    public abstract void show(T t);
}
创建GenericTool3Impl接口类:

public class GenericTool3Impl<T> implements GenericTool3<T>{
 
    @Override
    public void show(T t) {
        System.out.println(t);
    }
}
创建GenericTest3测试类:

public class GenericTest3 {
    public static void main(String[] args) {
        GenericTool3Impl<String> sgt1 = new GenericTool3Impl<>();
        sgt1.show("hadoop");
    }
}
输出结果:

hadoop

集合的嵌套遍历
在我们学泛型之前是创建方法来调用:

public class ArgsDemo {
    public static void main(String[] args) {
        //求两个数之和
        int a = 10;
        int b = 20;
//        System.out.println(a+b);
        sum(a, b);
 
        //求三个数之和
        int c = 30;
        sum(a, b, c);
 
        //求四个数之和
        int d = 40;
        sum(a, b, c, d);
 
    }
 
public static void sum(int a, int b) {
        System.out.println(a + b);
}
 
public static void sum(int a, int b, int c) {
 
        System.out.println(a + b + c);
}
 
public static void sum(int a, int b, int c, int d) {
        System.out.println(a + b + c + d);
}
 
}
输出结果:

30
60
100

假如说如果让我们做求和的数不确定呢?这个时候你怎么办呢?

根据我们的案例发现,方法名一样,参数列表中的数据类型一样,只是个数不一样,这时候,每增加一个参数,方法就要新写一个,非常麻烦,那怎么办呢?

java替我们考虑到了这一点,提供了一个技术给我们:可变参数

概述:定义方法的时候,参数不确定的时候使用

格式:修饰符 返回值的类型 方法名(数据类型...变量名){}

注意:这里的变量其实是一个数组,如果一个方法有可变参数,并且有多个参数,那么,可变参数肯定是最后一个

Arrays工具类中的一个方法

public static <T> List<T> List<T> asList(T... a)

用Arrays工具类中的方法来进行代码的改进

使用可变参数的形式定义加法的方法:

参考代码:

public class ArgsDemo {
    public static void main(String[] args) {
        //求两个数之和
        int a = 10;
        int b = 20;
//        System.out.println(a+b);
        sum(a, b);
 
        //求三个数之和
        int c = 30;
        sum(a, b, c);
 
        //求四个数之和
        int d = 40;
        sum(a, b, c, d);
 
        sum(312,123,1,312,13,13,13,13,13,1,34,5,4,3,131,3);
 
    }
 
    //使用可变参数的形式定义加法的方法
    public static void sum(int... ints){
        int sum = 0;
//        System.out.println(ints);
        for(int i=0;i<ints.length;i++){
            sum = sum + ints[i];
        }
 
        System.out.println(sum);
    }
 
 
}
输出结果:

30
60
100
994

当方法定义的时候既有固定值,也有可变参数的数的时候,将可变参数的定义放在最后一个。
import java.util.Arrays;
import java.util.List;
 
public class ArgsDemo {
    public static void main(String[] args) {
 
        List<String> strings = Arrays.asList("hello", "world", "java", "bigdata");
 
        for (String s : strings) {
            System.out.println(s);
        }
        sum("靓仔",1998,10,21,2048);
    }
 
    public static void sum(String s,int... ints){
        System.out.println(s);
 
        int sum = 0;
 
        for (int i = 0;i < ints.length;i++){
            sum = sum + ints[i];
        }
        System.out.println(sum);
    }
 
}
输出结果:

hello
world
java
bigdata
靓仔
4077

案例一
需求:获取10个1-20之间的随机数,要求不能重复

数组可以实现吗?由于长度不好确定,我们选择集合 。

需要导Random包

参考代码:

import java.util.ArrayList;
import java.util.Random;
public class RandomTest {
    public static void main(String[] args) {
        //创建随机数对象
        Random random = new Random();
 
        //创建集合对象存储随机数
        ArrayList<Integer> arr = new ArrayList<>();
 
        //定义一个变量统计集合中是否有10个元素
        int count = 0;
 
        while (count < 10){
            //产生随机数
            int i = random.nextInt(20) + 1;
 
            //判断集合中是否有该随机数
            if (!arr.contains(i)){
                //向集合中添加随机数
                arr.add(i);
                count++;
            }
        }
        System.out.println(arr);
    }
}
输出结果:

[10, 7, 14, 5, 18, 11, 19, 8, 20, 2]

[11, 5, 7, 16, 4, 1, 19, 9, 17, 10]

[13, 15, 3, 18, 4, 20, 5, 14, 6, 1]

案例二
需求:键盘录入多个数据,以0结束,要求在控制台输出这多个数据中的最大值。

参考代码:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Scanner;
 
/*
        键盘录入多个数据,以0结束,要求在控制台输出这多个数据中的最大值
 */
public class ArrayListTest {
    public static void main(String[] args) {
        //创建键盘录入对象
        Scanner sc = new Scanner(System.in);
 
        //创建集合存储键盘输入的数据
        ArrayList<Integer> arr = new ArrayList<>();
 
        while (true){
            int num = sc.nextInt();
 
            if (num==0){
                break;
            }else {
                arr.add(num);
            }
        }
 
        //Array工具类中有一个方法sort()
        //集合转数组
        Object[] objects = arr.toArray();
        Arrays.sort(objects);
 
        //第一个是最小值
        Integer minNumber = (Integer) objects[0];
 
        //最后一个是最大值
        Integer maxNumber = (Integer)objects[objects.length - 1];
 
        System.out.println("最小值为:" + minNumber);
        System.out.println("最大值为:" + maxNumber);
    }
}
输出结果:

23
343
13
3252
612
631
6143
642
16
7
1
675
0
最小值为:1
最大值为:6143

集合嵌套案例(英雄联盟案例)
需求:召唤师峡谷有红色方和蓝色方,红色方有很多英雄,蓝色方有很多英雄,每一位英雄都是一个召唤师对象,可以用一个集合表示召唤师峡谷有10位英雄。

红色方和蓝色方的召唤师都可以用集合表示:

红色方的英雄:ArrayList<Hero> redList

蓝色方的英雄:ArrayList<Hero>blueList

无论是红色方还是蓝色方,都是召唤师峡谷里的英雄

召唤师峡谷的召唤师也可以用集合表示:ArrayList<ArrayList<Hero>> LOL

这样的现象叫做集合的嵌套。

参考代码:

创建Hero对象:

import java.util.Objects;
public class Hero {
    private String name;//召唤师姓名
    private String heroname;//英雄名
 
    //定义无参的构造方法
    public Hero() {
    }
 
    //定义有参的构造方法
    public Hero(String name, String heroname) {
        this.name = name;
        this.heroname = heroname;
    }
 
    //定义getXxx()和setXxx()方法
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public String getHeroname() {
        return heroname;
    }
 
    public void setHeroname(String heroname) {
        this.heroname = heroname;
    }
 
    //重写toString方法
 
    @Override
    public String toString() {
        return "Hero{" +
                "name='" + name + '\'' +
                ", heroname='" + heroname + '\'' +
                '}';
    }
 
    //重写equals方法
 
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Hero hero = (Hero) o;
        return Objects.equals(name, hero.name) &&
                Objects.equals(heroname, hero.heroname);
    }
 
}
创建LOLHero测试类:

import java.util.ArrayList;
import java.util.Iterator;
 
public class LOLHero {
    public static void main(String[] args) {
        //定义红色方召唤师的集合
        ArrayList<Hero> redList = new ArrayList<>();
 
        //定义蓝色方召唤师的集合
        ArrayList<Hero> blueList = new ArrayList<>();
        
        //定义召唤师峡谷集合
        ArrayList<ArrayList<Hero>> LOL = new ArrayList<>();
 
        //将红色方和蓝色方英雄放到召唤师峡谷中
        LOL.add(redList);
        LOL.add(blueList);
 
        //创建红色方英雄对象
        Hero h1 = new Hero("TheShay", "暗裔剑魔");
        Hero h2 = new Hero("麻辣香锅", "永恒梦魇");
        Hero h3 = new Hero("大魔王", "影流之主");
        Hero h4 = new Hero("UZI", "暗夜猎手");
        Hero h5 = new Hero("刘青松", "蒸汽机器人");
 
        //将红色方英雄放入召唤师峡谷中
        redList.add(h1);
        redList.add(h2);
        redList.add(h3);
        redList.add(h4);
        redList.add(h5);
 
        //创建蓝色方英雄对象
        Hero h6 = new Hero("圣枪哥", "圣枪游侠");
        Hero h7 = new Hero("大司马", "虚空掠夺者");
        Hero h8 = new Hero("硬币哥", "离群之刺");
        Hero h9 = new Hero("德莱文", "文森特");
        Hero h10 = new Hero("青蛙", "魂锁典狱长");
 
        //将蓝色方英雄放入召唤师峡谷中
        blueList.add(h6);
        blueList.add(h7);
        blueList.add(h8);
        blueList.add(h9);
        blueList.add(h10);
 
        //迭代器遍历
        Iterator<ArrayList<Hero>> LOLhero = LOL.iterator();
 
        while (LOLhero.hasNext()){
            ArrayList<Hero> heros = LOLhero.next();
 
            Iterator<Hero> LOLheros = heros.iterator();
            while (LOLheros.hasNext()){
                Hero heros1 = LOLheros.next();
                System.out.println(heros1);
            }
        }
 
 
    }
}
输出结果:

Hero{name='TheShay', heroname='暗裔剑魔'}
Hero{name='麻辣香锅', heroname='永恒梦魇'}
Hero{name='大魔王', heroname='影流之主'}
Hero{name='UZI', heroname='暗夜猎手'}
Hero{name='刘青松', heroname='蒸汽机器人'}
Hero{name='圣枪哥', heroname='圣枪游侠'}
Hero{name='大司马', heroname='虚空掠夺者'}
Hero{name='硬币哥', heroname='离群之刺'}
Hero{name='德莱文', heroname='文森特'}
Hero{name='青蛙', heroname='魂锁典狱长'}

德莱文玩的文森特是不是很厉害?

Java的泛型---(英雄联盟集合嵌套案例)相关推荐

  1. 基于java的简单英雄联盟胜率计算

    基于java的简单英雄联盟胜率计算 首先声明,楼主是一个LOLer,技术还说的过去.今天下午楼主的同学看到楼主匹配胜率感人,非说楼主是"小学生",非说匹配胜率要50%以上才算不坑, ...

  2. java计算胜率_基于java的简单英雄联盟胜率计算

    基于java的简单英雄联盟胜率计算 首先声明,楼主是一个LOLer,技术还说的过去.今天下午楼主的同学看到楼主匹配胜率感人,非说楼主是"小学生",非说匹配胜率要50%以上才算不坑, ...

  3. Java中集合相关案例(泛型通配符、Collections工具类、TreeSet、TreeMap、HashMap、HashSet和集合嵌套案例)

    集合 一.集合相关案例 1.泛型通配符案例 2.集合工具类(Collections工具类) 3.TreeSet和TreeMap案例 4.HashMap案例 5.HashSet案例 6.TreeSet案 ...

  4. 学习Java第二十五天--集合框架之集合嵌套案例

    Map集合和其它集合嵌套的案例.以及Map集合和Map集合嵌套的案例 案例1:Map和ArrayList的嵌套 案例2:Map和Map的嵌套 案例1:Map和ArrayList的嵌套 import j ...

  5. 英雄联盟的小案例理解Java中如何实现OCP原则

    案例: 英雄联盟的英雄.道具.地图,每年都会进行频繁变更 如果没有使用软件工程的开发思想,随便改其中一个道具的属性,就可能会导致非常严重的错误 要实现变更/增加英雄时,可选英雄数量和玩家开始一局游戏时 ...

  6. Java编程基础19——Map集合斗地主案例

    1_Map集合概述和特点 A:Map接口概述 查看API可以知道: 将键映射到值的对象 一个映射不能包含重复的键 每个键最多只能映射到一个值 B:Map接口和Collection接口的不同 Map是双 ...

  7. ssm+java计算机毕业设计英雄联盟俱乐部管理系统j4oh6(程序+lw+源码+远程部署)

    项目运行 项目含有源码(见文末).文档.程序.数据库.配套开发软件.软件安装教程 环境配置: Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ E ...

  8. 策略模式详解(英雄联盟上王者案例)

    "且听说书人把对和错变成利与弊,把铜板藏入衣袖笑着说道德里哪有枪和毙"

  9. 对英雄联盟比赛预测(四)- 数据清洗

    系列文章目录 对英雄联盟比赛预测(一)- 特征分析 对英雄联盟比赛预测(二)- 数据获取api分析 对英雄联盟比赛预测(三)- 数据获取Java实现 对英雄联盟比赛预测(四)- 数据清洗 文章目录 前 ...

最新文章

  1. linux停止客户端,linux – 从客户端打印motd停止ssh登录?
  2. python使用matplotlib绘制水平条形图并在条形图上添加实际数值标签实战
  3. 5G时代渐行渐近 移动承载网络面临新挑战
  4. django oracle clob,记一次clob字段损坏导致的01555错误
  5. noj 邮票分你一半z的生日
  6. linux 使用退格键时出现^H解决方法
  7. oracle 自带table,Oracle中table函数的使用详解
  8. 特斯拉花式作妖:停售Model S标准续航版 国内官网已下架
  9. pyecharts实现多节点、长路径的sankey桑基图
  10. linux sql 语句菜鸟,sql语句
  11. 在运行microsoft windows 非核版本的计算机上_系统版本决定获得Win10 2004与20H2版更新时间...
  12. ad18/ad19/ad20/ad21/ad22新版ADgaber导出(含官方教程)(含坐标文件)
  13. 中国住户收入调查(CHIP)数据及问卷(1988-2008年)
  14. 计算机创新课堂教案,1 1.1计算机概述1.2计算机系统课堂教学教案
  15. 实验设计的道德伦理考量
  16. 将markdown文档转化为pdf格式
  17. 电脑如何防蹭网?使用防蹭网功能杜绝未知设备连接WiFi
  18. 谓词函数和谓词函数对象_称为形容词的函数
  19. 游客 计算机英语,游客的英文,游客怎么都用英语!
  20. 【报告分享】2021年度小红书高效种草营销手册-标记我的生活-小红书(附下载)

热门文章

  1. 在 2040 年前,实现净零碳排放
  2. c语言stdin输入字符,scanf如何从stdin中读取数据的
  3. 【Jaya算法解决柔性作业车间调度问题(附代码)】
  4. arduino 继电器控制led灯开关
  5. Cura切片3d打印设置
  6. 金融学习之十——远期利率和远期利率协议
  7. 能测试手机信号不好的软件,买手机别只看性能!教你测试手机信号好坏
  8. 启动计算机实现5秒开机,电脑3秒开机,怎么做到的?
  9. 如何做一名优秀的程序员?
  10. 在JS中的数字存储问题