目录
泛型概述及使用
为什么会有泛型呢?
a.通过案例引入
b.早期的Object类型可以接收任意的对象类型,但是在实际的使用中,会有类型转换的问题。也就存在这隐患,所以Java提供了泛型来解决这个安全问题
泛型的语句定义格式
<引用数据类型> 括号中的数据类型只能是引用数据类型
例:创建一个List 集合对象
ArrayList<String> list = new ArrayList<>();
泛型为String,这样集合只能去添加String类型的元素。
泛型的好处
a.将运行时期出现的问题提前到编译时期
b.不需要做强制类型转换
c.优化了代码,减少出错的机会
泛型应用
泛型类
把泛型定义在类上
格式:public class 类名<泛型类型1,…>
注意:泛型类型必须是引用类型
//这里<>里面的内容仅仅表示使用的一种参数数据类型,参数类型使一种变量,可以使用任意符合标识符规则的名字
public class GenericTest2<A> {
private A name;
public void setName(A name) {
this.name = name;
}
public A getName() {
return name;
}
}
泛型方法
把泛型定义在方法上
格式:public <泛型类型> 返回类型 方法名(泛型类型 .)
class Generic{
//泛型方法
public <B> void show(B b){ //B代表你传任意类型数据它就变成什么类型的数据
System.out.println(b);
}
}
public class GenericTest3 {
public static void main(String[] args) {
//创建Generic类的对象
Generic generic = new Generic();
generic.show("sad23"); //可以传任意类型数据
generic.show(223);
generic.show(2322.232);
}
}
泛型接口
把泛型定义在接口上
格式:public interface 接口名<泛型类型1…>
//泛型接口
interface Generic1<C>{
void show(C c);
}
//创建类实现接口
class Ter<C> implements Generic1<C>{
//重写接口的方法
@Override
public void show(C c) {
System.out.println(c);
}
}
//测试
public class GenericTest4 {
public static void main(String[] args) {
//创建Ter类对象
Ter<String> s = new Ter<>();
s.show("sad");
}
}
泛型高级(通配符)
1.泛型通配符<?>
任意类型,如果没有明确,那么就是Object以及任意的Java类了
//泛型通配符<?> 任意类型,如果没有明确,那么就是Object以及任意的Java类了
ArrayList<?> list1= new ArrayList<String>();
ArrayList<?> list2 = new ArrayList<Integer>();
ArrayList<?> list3 = new ArrayList<Character>();
通配符使集合能存放任意类型的数据
2. ? extends E
向下限定,E及其子类
class Teacher{} //创建老师类
class Student extends Teacher{} //创建学生类继承老师类
public class GenericTest1 {
public static void main(String[] args) {
// ? extends E 向下限定,E及其子类
ArrayList<?extends Teacher> list1=new ArrayList<Teacher>(); //存放自身类型数据
ArrayList<?extends Teacher> list2=new ArrayList<Student>(); //存放子类类型数据
3. ? super E
向上限定,E及其父类
//? super E 向上限定,E及其父类
ArrayList<? super Teacher> list1 = new ArrayList<Teacher>(); //存放自身类型数据
ArrayList<? super Teacher> list2 = new ArrayList<Object>(); //存放父类类型数据
增强for概述及使用
增强for概述
简化数组和Collection集合的遍历
格式: for(元素数据类型 变量 : 数组或者Collection集合) {
使用变量即可,该变量就是元素 }
好处:简化遍历
注意事项:增强for的目标要判断是否为null
增强for循环使用
例:遍历数组
public class ForTest1 {
public static void main(String[] args) {
//创建普通数组
int[] arr ={23,2,332,34};
//普通for循环遍历
for(int i=0;i<arr.length;i++){
System.out.println(arr[i]);
}
System.out.println("=====分界线=====");
//增强for循环遍历
for (int s :arr){
System.out.println(s);
}
}
}
同理也能遍历集合
import java.util.ArrayList;
public class ForTest2 {
public static void main(String[] args) {
//创建list集合
ArrayList<String> list = new ArrayList<>();
//向集合添加元素
list.add("java");
list.add("hive");
list.add("bigdata");
list.add("flink");
//增强for循环遍历,先判断集合是否为空
if (list!=null) {
for (String s : list) {
System.out.println(s);
}
}else {
System.out.println("该集合为空");
}
}
}
静态导入概述及使用
静态导入概述
格式:import static 包名….类名.方法名;
可以直接导入到方法的级别
例:静态导入Math方法
import static java.lang.Math.abs; //静态导入Math的abs方法
public class StaticTest1 {
public static void main(String[] args) {
//没导保之前调用Math方法
System.out.println(Math.abs(-233)); //求绝对值
//静态导入之后,不用写类名,直接写方法名 (如在最上方导入:import static java.lang.Math.abs; )
System.out.println(abs(-233));
}
}
注意事项
a,方法必须是静态的
b.如果有多个同名的静态方法,容易不知道使用谁?这个时候要使用,必须加前缀。由此可见,意义不大,所以一般不用,但是要能看懂。
c.可以导入自己创建的方法,但方法必须是静态的,如果导入方法名与本类方法冲突,将调用本类方法(若还想使用静态导入的方法,需补齐导入方法包的路径)
例 :
先创建一个公共类
public class Static2 {
public static void show(){
System.out.println("Static2的静态方法");
}
}
再创建测试类,静态导入方法
import static com.shujia.ys.day19.Static2.show; //静态导入方法(这是我创建类的路径)
public class StaticTest2 {
public static void main(String[] args) {
show(); //虽然静态导入了,但方法名与本类方法名冲突,需补齐路径
com.shujia.ys.day19.Static2.show();
}
public static void show(){
System.out.println("本类中的静态方法");
}
}
可变参数概述及使用
可变参数概述
定义方法的时候不知道该定义多少个参数
格式
修饰符 返回值类型 方法名(数据类型… 变量名){}
注意事项
a.这里的变量其实是一个数组
例:创建方法求多个数的和
public class VarargsTest1 {
public static void main(String[] args) {
int a=10;
int b=20;
int c=30;
int d=40;
sum(a,c); //调用该方法能求任意数的和
sum(a,c,b,d);
sum(c,c,c);
}
public static void sum(int...ints){ //用可变参数创建求和方法 变量名ints是形成的数组
//增强for循环遍历
int sum=0;
for(int i:ints){
sum=sum+i;
}
System.out.println(sum);
}
}
b.如果一个方法有可变参数,并且有多个参数,那么,可变参数肯定是最后一个
例:创建方法求学生任意成绩和
public class VarargsTest2 {
public static void main(String[] args) {
sum("student1",55,65,78);
sum("student2",55,66,78,34);
sum("student3",55,32);
}
public static void sum(String s,int...ints){ //可变参数放在后面
//增强for循环遍历
int sum=0;
for(int i:ints){
sum=sum+i;
}
System.out.println(s+":"+sum);
}
}
Arrays工具类中的一个方法
public static <T> List<T> asList(T... a) 数组转成集合的方法
例:
import java.util.Arrays;
import java.util.List;
public class ArrayListTest1 {
public static void main(String[] args) {
//数组————>ArrayList集合
List<String> strings = Arrays.asList("java", "hive", "flink", "spark");
//增强for遍历
for(String s:strings){
System.out.println(s);
}
}
}
集合的嵌套
例:用list集合嵌套实现:一个学校有两个班级,两个班级学生的遍历
首先封装一个公共的学生类 (不会看 封装 )
public class Student2 {
private String name;
private int age;
public Student2() {}
public Student2(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student2{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
再创建大集合(学校)添加两个小集合(班级)进行遍历
import java.util.ArrayList;
public class ArrayListTest2 {
public static void main(String[] args) {
//创建两个班级集合
ArrayList<Student2> class1 = new ArrayList<>();
ArrayList<Student2> class2 = new ArrayList<>();
//创建学生对象
Student2 s1 = new Student2("student1",18);
Student2 s2 = new Student2("student2",22);
Student2 s3 = new Student2("student3",20);
Student2 s4 = new Student2("student4",19);
Student2 s5 = new Student2("student5",21);
Student2 s6 = new Student2("student6",20);
//向集合添加学生对象
class1.add(s1);
class1.add(s2);
class1.add(s3);
class2.add(s4);
class2.add(s5);
class2.add(s6);
//创建学校集合,把两个班级集合添加进去
ArrayList<ArrayList<Student2>> school = new ArrayList<>();
school.add(class1);
school.add(class2);
//增强for循环遍历集合 (看不到学生对应的班级)
for (ArrayList<Student2> s:school){ //先遍历school中的班级集合
for (Student2 t :s){ //再遍历班级中的学生对象
System.out.println(t.getName()+"-----"+t.getAge());
}
}
System.out.println("========分界线==========");
//普通for循环遍历 (能分别遍历班级)
for (int i=0;i<school.size();i++){
if (i==0){
System.out.println("班级一的学生:");
for (int j=0;j<school.get(i).size();j++){ //school.get(i) ==class1
System.out.println(school.get(i).get(j));
}
}else if (i==1){
System.out.println("班级二的学生:");
for (int j=0;j<school.get(i).size();j++){ //school.get(i) ==class2
System.out.println(school.get(i).get(j));
}
}
}
}
}