Java的泛型---(英雄联盟集合嵌套案例)
2021/12/22 1:20:09
本文主要是介绍Java的泛型---(英雄联盟集合嵌套案例),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
目录
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的泛型---(英雄联盟集合嵌套案例)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-09-28微服务架构中API版本控制的实践
- 2024-09-28AI给的和自己写的Python代码,都无法改变输入框的内容,替换也不行
- 2024-09-27Sentinel配置限流资料:新手入门教程
- 2024-09-27Sentinel配置限流资料详解
- 2024-09-27Sentinel限流资料:新手入门教程
- 2024-09-26Sentinel限流资料入门详解
- 2024-09-26Springboot框架资料:初学者入门教程
- 2024-09-26Springboot框架资料详解:新手入门教程
- 2024-09-26Springboot企业级开发资料:新手入门指南
- 2024-09-26SpringBoot企业级开发资料新手指南