Java基础复习(九)
泛型
定义:
通过<数据类型>接收一种数据类型,在编译的时候会使用这种数据类型检测集合中的元素,如果元素不是<>中规定的类型,就不允许添加到当前的集合中(编译失败)
作用:
- 使用了泛型不再需要进行容错处理,向下转型,强制类型转换----简化代码
- 将运行阶段的问题提前到编译阶段检查,提高了代码的安全性和编程效率
泛型可以修饰类,方法,接口。
1.泛型应用在类上
给Student类加泛型,方式:在类的后面直接添加,E代表任意一种数据类型,注意:这里不一定是E,任意字母都可以
-
这就是在类上使用泛型
-
在类上确定的泛型可以直接在方法上使用
-
当泛型没有指定时默认是Object
-
当泛型确定后,类型就确定了
Student<Phone> student1 = new Student<>(); class Student<E>{ E tools; public E getTools() { return tools; } public void setTools(E tools) { this.tools = tools; } }
2.泛型应用在方法上
-
泛型在使用时可以一次定义多个.之间使用,隔开
-
方法上的泛型与类上的泛型保持一致
class Dog<F>{ public void eat(F f) { System.out.println(f); } } -
方法上独立使用泛型
-
注意:泛型在使用之前一定要先进行定义
-
定义的方式:在当前方法的最前面添加<泛型>
-
作用:让方法与方法内的泛型保持一致
public <E> void song(E e) { ArrayList<E> arrayList = new ArrayList<>(); System.out.println(e); }
-
-
静态方法上使用泛型
-
必须独立使用
-
方式:在static 后面定义泛型 <泛型>
public static <W> void show(W w) { }
-
-
实例
package Collection; import java.util.ArrayList; public class demo8 { public static void main(String[] args) { Dog<String> dog = new Dog<>(); dog.eat("吃"); dog.song("汪汪"); } } class Dog<E>{ public void eat(E e){ System.out.println(e); } public <F> void song(F f){ ArrayList<F> arrayList = new ArrayList<>(); System.out.println(f); } public static <W> void show(W w) { } }
3.泛型应用在接口上
主要研究的是实现接口的子类上的泛型是如何使用的
-
子类上的泛型与接口上的一致
- 类上的泛型确定了,接口上的泛型就确定了,方法上的泛型就确定了
-
接口上使用泛型,子类上不用泛型
- 在实现的接口位置必须指定一个具体的泛型
-
方法使用泛型的情况:
- 如果是重写的方法,泛型与接口一致
- 如果是子类自己的方法,可以与接口一致,也可以有自己的泛型
-
实例
package com.qf.test; /* * 泛型应用在接口上 * 我们主要研究的是实现接口的子类上的泛型是如何使用的 */ public class Demo13 { public static void main(String[] args) { //1.子类上的泛型与接口上的一致 Pig<String> pig = new Pig<>(); pig.show("哈哈"); //2.接口上使用泛型,子类上不用泛型 Bird bird = new Bird(); bird.show("haha"); Class<?> class1 = bird.getClass(); } } interface Inte<E>{ public void show(E e); } //1.子类上的泛型与接口上的一致 /* 类上的泛型确定了,接口上的泛型就确定了,方法上的泛型就确定了 */ class Pig<E> implements Inte<E>{ @Override public void show(E e) { System.out.println(e); } } //2.接口上使用泛型,子类上不用泛型 /*在实现的接口位置必须指定一个具体的泛型 * * 方法使用泛型的情况: * 1.如果是重写的方法,泛型与接口一致 * 2.如果是子类自己的方法,可以与接口一致,也可以有自己的泛型 */ class Bird implements Inte<String>{ public void show(String e) {}; }
关于Java中?的使用
1)用于?: 这里是算目运算符一部分,前面是判断条件,后面是两个分支结果
2)用于数据库的sql语句 select * from emp where name=? :表示占位符
3)用于泛型,表示任意一种数据类型.
//这里的Object与前面的?没有关系
Class<?> class1 = Object.class;
//如果类的泛型使用时写成?是可以的.作为返回值时,会默认成Object类型,但是作为参数不行.所以在给对象指定泛型时要写具体类型
Test<?> test = new Test();
//test.run(new Object());
class Test<T>{
T e;
public T run(T a) {
T t = null;
return t;
}
}
?:通配符
可以表示一种或几种数据类型
-
限制上限:<? extends E>限制的是整个的<>可以取的泛型类型的上限是E,<>中可以取的类型是E及E的子类
public class Demo14 { public static void main(String[] args) { // ArrayList<Student2> list1 = new ArrayList<>(); list1.add(new Student2("bingbing", 1)); //可以传参:因为Student2是Person1的子类,可以实现遍历 bianli(list1); ArrayList<Teacher> list2 = new ArrayList<>(); list2.add(new Teacher("bingbing", 1)); //可以传参:因为Teacher1是Person1的子类,可以实现遍历 bianli(list2); ArrayList<Person4> list3 = new ArrayList<>(); list3.add(new Person4("bingbing", 1)); //可以传参 bianli(list3); ArrayList<Object> list4 = new ArrayList<>(); list4.add(new Object()); //不可以传参:因为Object是Person1的父类,不可以实现遍历 //bianli(list4); } public static void bianli(Collection<? extends Person4> e){ System.out.println("遍历了"); } } class Person4{ String name; int age; public Person4() { super(); // TODO Auto-generated constructor stub } public Person4(String name, int age) { super(); this.name = name; this.age = age; } @Override public String toString() { return "Person4 [name=" + name + ", age=" + age + "]"; } } class Teacher extends Person4{ public Teacher(String name, int age) { super(name, age); } } class Student2 extends Person4 { public Student2(String name, int age) { super(name, age); } } -
限制下限:<? super E>限制的是整个的<>可以取的泛型类型的下限是E,<>中可以取的类型是E及E的父类
可变参数
参数的个数可以改变,简化代码,简化操作。
可变参数的特点
-
给可变参数传值的实参可以直接写,个数不限制,内部会自动的将他们放入可变数组中.
-
当包括可变参数在内有多个参数时,可变参数必须放在最后面,并且一个方法中最多只能有一个可变参数
-
当可变参数的方法与固定参数的方法是重载关系时,调用的顺序,固定参数的优先于可变参数的.
-
构成:数据类型+… 实际上就是数据类型[] 即:int[]
-
实例
package Collection; public class demo9 { public static void main(String[] args) { System.out.println(sum1(5,6,7)); System.out.println(sum2(2,1,2)); System.out.println(sum3(1,4)); } //求和 //通过可变参数 public static int sum1(int... a) { int sum = 0; for (int i = 0; i < a.length; i++) { sum+=a[i]; } return sum; } //2.当包括可变参数在内有多个参数时,可变参数必须放在最后面,并且一个方法中最多只能有一个可变参数 public static int sum2(float b,int... a) { int sum = 0; for (int i = 0; i < a.length; i++) { sum+=a[i]; } return sum; } //3.当可变参数的方法与固定参数的方法是重载关系时,调用的顺序,固定参数的优先于可变参数的. public static int sum3(int a, int b) { System.out.println("a"); int sum = 0; return sum; } public static int sum3(int... a) { System.out.println("b"); int sum = 0; return sum; } }
增强for循环
可以遍历的内容有:数组,Collection,Map.但是Map不能直接遍历
- 原理:每次遍历开始后,会自动从数组中依次取出一个元素放入前面的变量中,当次循环的操作使用的就是这个元素.
- 遍历完成之后,会自动进行第二次遍历.一直到数组的末尾.所有元素遍历结束.循环停止.
* for(元素:数组/Collection){
* 内容
* }
实例
package Collection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class demo10 {
public static void main(String[] args) {
//遍历数组
int arr[] = {4,5,7,9,9};
for(int i : arr)
{
System.out.println(i);
}
//遍历Collection
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("java");
arrayList.add("java1");
arrayList.add("java2");
arrayList.add("java3");
arrayList.add("java4");
System.out.println(arrayList);
for(String string : arrayList)
{
System.out.println(string);
}
//遍历Map
HashMap<String,String> map = new HashMap<>();
map.put("05", "iOS");
map.put("01", "java");
map.put("02", "html");
map.put("03", "BigData");
map.put("02", "iOS");//会将前面的值覆盖
for(String key : map.keySet())
{
System.out.println(key);
}
for(Map.Entry<String,String> entry : map.entrySet())
{
System.out.println(entry);
}
}
}
Collections类
封装了大量操作Collection的工具
实例
public class Demo18 {
public static void main(String[] args) {
//要求:存储多个数据,可排序,可重复
ArrayList<String> list = new ArrayList<>();
list.add("java");
list.add("java1haha");
list.add("java2BigData");
list.add("java3ok");
list.add("java2");
System.out.println(list);
//使用Collections排序
//第一种排序:默认按照字典进行排序
//注意:要想list中的元素可以按照字典排序,元素必须实现Comparable接口
Collections.sort(list);
System.out.println("默认的字典排序:"+list);
//按照从短到长排序
//使用比较器
ComStrWithLength1 comStrWithLength = new ComStrWithLength1();
Collections.sort(list, comStrWithLength);
System.out.println("从短到长排序:"+list);
//按照从长到短排序
Comparator<String> comparator1 = Collections.reverseOrder(comStrWithLength);
Collections.sort(list, comparator1);
System.out.println("从长到短排序:"+list);
//倒叙字典排序
Comparator<String> comparator2 = Collections.reverseOrder();
Collections.sort(list, comparator2);
System.out.println("倒叙字典排序:"+list);
Collections.reverse(list);
System.out.println("现有顺序的反转排序:"+list);
//求最大值
String max = Collections.max(list, comStrWithLength);
System.out.println(max);
}
}
class ComStrWithLength1 implements Comparator<String>{
@Override
public int compare(String o1, String o2) {
int num = o1.length()-o2.length();
return num==0?o1.compareTo(o2):num;
}
}
本文深入讲解Java泛型的基础概念,包括泛型在类、方法和接口上的应用,以及泛型的限制、通配符的使用、可变参数和增强for循环的特性。同时,介绍了Collections类的实用功能。

被折叠的 条评论
为什么被折叠?



