目錄
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='魂鎖典獄長'}
德萊文玩的文森特是不是很厲害?
🉑來給靚仔一個關注吧!🉑
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/389103.html
標籤:其他
