本期知识点:
泛型
JDK5新特性
泛型
JDK5新特性
1.泛型
a. 泛型的引出:
定义一个字符串数组:
String[] strArray = {"hello","world","java"};String[] strArray = {"hello","world","java",100};//报错,
给集合中存储了字符串类型和Integer类型,在最终遍历完成之后,报异常,原因是有两种类的元素,最终用String去接收,只能接受跟它相关的类型的元素!java提供了一种技术:叫泛型(JDK5以后的特性)这里常出现的异常: java.lang.ClassCastException:类转换异常
b.格式:
<数据类型> :引用类型
c.特点:
i.将运行时期的异常提前到了编译期间。ii.不用在强制类型转换了。iii.优化了程序设计,解决了一个黄色警告线的问题。
d.遍历方式:
i.普通for循环,size()/get()方法。ii.Iterator iterator()iii.ListIterator listIterator()列表迭代器
import java.util.ArrayList; import java.util.Iterator; import java.util.ListIterator; public class Student { ...略 ...略 } public class Demo01 { public static void main(String[] args) { //创建集合对象 ArrayList<Student> a = new ArrayList<Student>(); //创建4个学生对象 Student s1 = new Student("Tom",21); Student s2 = new Student("Tom2",22); Student s3 = new Student("Tom3",23); Student s4 = new Student("Tom4",24); //添加 a.add(s1); a.add(s2); a.add(s3); a.add(s4); //方式1 for (int i = 0; i < a.size(); i++) { Student s = a.get(i); System.out.println(s.getName()+"---"+s.getAge()); } System.out.println("------------"); //方式2 Iterator<Student> t = a.iterator(); while(t.hasNext()){ Student s =t.next();//不需要强制类型转换; System.out.println(s.getName()+"---"+s.getAge()); } System.out.println("------------"); //方式3 ListIterator<Student> tt = a.listIterator(); while(tt.hasNext()){ Student s = tt.next(); System.out.println(s.getName()+"---"+s.getAge()); } } } out: Tom---21 Tom2---22 Tom3---23 Tom4---24 ------------ Tom---21 Tom2---22 Tom3---23 Tom4---24 ------------ Tom---21 Tom2---22 Tom3---23 Tom4---24
e.泛型的分类:
i.泛型类ii.泛型接口iii.泛型方法iv.泛型高级通配符:
1)?:代表任意数据类型:可以是Object类型以及Java类2)? extends E:向下限定,要么跟当前类型一样,要么是它的子类3)? super E:向上限定,保持当前类型一致,或者是他的父类
//将泛型定义在类上 class LeiDemo<T> { public void fun(T t){ System.out.println(t); } } //把泛型定义在方法上 class LeiFanDemo{ public <T> void fun(T t){ System.out.println(t); } } public class LeiTool { public static void main(String[] args) { // 没有泛型的时候 LeiDemo l = new LeiDemo(); l.fun(100); l.fun(true); l.fun("hello"); System.out.println("----------"); // 创建工具类对象:已经将给数据类型给定了 LeiDemo<String> a = new LeiDemo<String>(); a.fun("HELLO"); System.out.println("----------"); LeiFanDemo b = new LeiFanDemo(); b.fun("hello"); b.fun(100); b.fun(true); } }
interface Inter <T>{ public abstract void fun(T t); } //第一种:知道了实现类的数据类型:数据类型明确 /*class InterDemo implements Inter<String>{ @Override public void fun(String t) { System.out.println(t); } }*/ /* //第二种情况:不明确数据类型不明确接口的数据类型是什么 class InterDemo<T> implements Inter<T>{ @Override public void fun(T t) { System.out.println(t); } } //泛型接口测试类 public class InterTool { public static void main(String[] args) { //创建接口对象:接口多态 /*第一种 知道了实现类的数据类型:数据类型明确 Inter i = new InterDemo(); i.fun("String"); //第二种: Inter<String> i = new InterDemo<String>(); i.fun("hello"); Inter<Integer> ii = new InterDemo<Integer>(); ii.fun(100); } }
import java.util.ArrayList; import java.util.Collection; class Animal {} class Cat extends Animal{} class Dog extends Animal{} public class Demo01 { public static void main(String[] args) { //创建集合对象 //如果明确数据类型,要保证前后数据类型一致; Collection<Object> a = new ArrayList<Object>(); Collection<Animal> b = new ArrayList<Animal>(); Collection<Cat> c = new ArrayList<Cat>(); Collection<Dog> d = new ArrayList<Dog>(); //? 代表任意数据类型,可以是Object类以及Java类; Collection<?> a1 = new ArrayList<Object>(); Collection<?> b1 = new ArrayList<Animal>(); Collection<?> c1 = new ArrayList<Cat>(); Collection<?> d1 = new ArrayList<Dog>(); // ? extends E 向下限定 和当前类型一样 或者 是它的子类 Collection<? extends Object> a2 = new ArrayList<Animal>(); Collection<? extends Animal> b2 = new ArrayList<Animal>(); Collection<? extends Animal> c2 = new ArrayList<Dog>(); Collection<? extends Animal> d2 = new ArrayList<Cat>(); // ? super E 向上限定,保持当前类型一致,或者是他的父类 Collection<? super Animal> c11 = new ArrayList<Animal>() ; Collection<? super Animal> c12 = new ArrayList<Object>() ; } }
f.泛型的应用场景:
定义在类(具体类或者抽象类),接口的后面.一般情况,在集合中使用居多!
2.增强型for
a.归属:
是for循环的一种。
b.格式:
for(数据类型(引用类型) 变量名:数组或集合的对象名){
使用该变量。
}
c.应用场景:
集合或者数组(int 类型(Integer)/String类型的居多)。
d.优点和缺点:
i.优点:简化了数组和集合的遍历。ii.缺点:增强型for循环的目标不能为null,在使用前,进行非空判断。在使用前,进行非空判断。
e.给ArrayList集合存储字符串并遍历
i.普通for循环ii.迭代器:Iterator iterator()iii.列表迭代器:ListIterator listIterator():List集合iv.增强for循环
import java.util.ArrayList; import java.util.Iterator; public class Demo01 { public static void main(String[] args) { //创建ArrayList集合对象 ArrayList<String> a = new ArrayList<String>(); //添加元素 a.add("hello"); a.add("is"); a.add("me"); //方法一:size()/get()遍历 for (int i = 0; i < a.size(); i++) { String s = a.get(i); System.out.println(s); } System.out.println("------------"); //方法二:迭代器遍历 Iterator<String> t = a.iterator(); while(t.hasNext()){ String s = t.next(); System.out.println(s); } System.out.println("------------"); //增强型for for (String s : a) { System.out.println(s); } } } /* out: hello is me ------------ hello is me ------------ hello is me */
class Student{ private String name; private int age; public Student() { super(); } public Student(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return name+"---"+age; } //重写equals方法 比较的是内容 @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Student other = (Student) obj; if (age != other.age) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } } import java.util.ArrayList; import java.util.ListIterator; public class Demo02 { public static void main(String[] args) { ArrayList<Student> a = new ArrayList<Student>(); a.add(new Student("Tom",21)); a.add(new Student("Jack",22)); a.add(new Student("Peter",23)); //方法一:size()/get()遍历 for (int i = 0; i < a.size(); i++) { Student s = a.get(i); System.out.println(s); } System.out.println("------------"); //方法二:列表迭代器遍历 ListIterator<Student> t = a.listIterator(); while(t.hasNext()){ Student s = t.next(); System.out.println(s); } System.out.println("------------"); //方法三:增强型for for (Student s : a) { System.out.println(s); } } } /* out: Tom---21 Jack---22 Peter---23 ------------ Tom---21 Jack---22 Peter---23 ------------ Tom---21 Jack---22 Peter---23 */
3.静态导入(JDK5新特性)
a.可以导入到方法级别的导入
b.格式:
import static 包名.类名.方法名;例:import static java.lang.Math.abs;
c.注意事项:
i.类中的方法必须是静态的。ii.如果要使用静态导入,为了防止在一个类中出现同名的方法,那么调用的时候需要前缀来区别开来
import static java.lang.Math.abs; import static java.lang.Math.pow; import static java.lang.Math.sqrt; public class Demo01 { public static void main(String[] args) { //Math类的一个绝对值; System.out.println(Math.abs(-100)); System.out.println(Math.pow(2, 3)); System.out.println(Math.sqrt(4)); System.out.println("------"); //利用JDK5特性 静态导入 System.out.println(abs(-100)); System.out.println(pow(3,2)); System.out.println(sqrt(4)); } } /*out: 100 8.0 2.0 ------ 100 9.0 2.0 */
4.可变参数(JDK5新特性)
a.如果我们在写方法的时候,参数个数不明确,就应该定义可变参数。
b.格式:
修饰符 返回值类型 方法名(参数类型...变量){}
注意: i.该变量的其实是一个数组名
ii.如果一个方法有多个参数,并且有可变参数,可变参数必须在最后
public class Demo01 { public static void main(String[] args) { int a = 1; int b = 2; int c = 3; int d = 4; System.out.println(sum(a,b,c,d,5));//15 } public static int sum(int...a){ int sum = 0; for (int i = 0; i < a.length; i++) { sum+=a[i]; } return sum; } }
c.Arrays工具类的一个方法
public static <T> List<T> asList(T... a) 返回一个受指定数组支持的固定大小的列表,把数组转成集合。注意:这个集合的长度不能改变。
5.练习:
a.集合的嵌套遍历
import java.util.ArrayList; public class 集合嵌套遍历 { public static void main(String[] args) { ArrayList<ArrayList<Student>> a = new ArrayList<ArrayList<Student>>(); ArrayList<Student> x = new ArrayList<Student>(); ArrayList<Student> y = new ArrayList<Student>(); ArrayList<Student> z = new ArrayList<Student>(); a.add(x); a.add(y); a.add(z); x.add(new Student("Tom1",21)); x.add(new Student("Tom2",22)); x.add(new Student("Tom2",23)); y.add(new Student("Peter1",21)); y.add(new Student("Peter2",20)); y.add(new Student("Peter3",22)); y.add(new Student("Peter4",23)); z.add(new Student("Ash1",21)); z.add(new Student("Ash2",23)); z.add(new Student("Ash3",25)); for (ArrayList<Student> student : a) { System.out.println(student); } } } /* out: [Tom1---21, Tom2---22, Tom2---23] [Peter1---21, Peter2---20, Peter3---22, Peter4---23] [Ash1---21, Ash2---23, Ash3---25] */
b.获取10个1-20之间的随机数,要求不能重复
import java.util.ArrayList; import java.util.Random; public class TestDemo { public static void main(String[] args) { //创建一个Random随机数对象 Random r = new Random(); //创建一个ArrayList集合对象 ArrayList<Integer> array = new ArrayList<Integer>() ; //定义一个统计变量 int count = 0 ; //判断统计变量是否是10个 while(count < 10){ //存在10个随机数,获取1-20之间的随机数,使用随机数的这个对象 int number = r.nextInt(20) +1 ; //判断集合中是否存在该数据,不存在,添加数据,统计变量++ if(!array.contains(number)){ array.add(number) ; count ++; } } //遍历集合 for(Integer i : array){ System.out.println(i); } } }