本文共 12016 字,大约阅读时间需要 40 分钟。
定义:将明确的集合类型的工作推迟到了创建对象或者调用方法的时候,属于一种参数化类型,可以作为参数传递;
原因:数组直接定义了存储的类型,防止出现其他的类型的元素,集合也像数组一样,直接规定集合的数据类型,针对这种情况,诞生除了泛型这个概念 ===> 泛型的引出可以提供程序的安全性;
泛型的好处:
1> 将运行时期异常提前到了编译时期; 2> 优化了设计,解决了黄色警告线问题; 3> 避免了强制类型转换;举例:
import java.util.ArrayList;import java.util.Iterator;public class GenericDemo { public static void main(String[] args) { //创建集合对象 ArrayListarray = new ArrayList () ; //添加元素 array.add("hello") ; array.add("world") ; array.add("java") ; //array.add(new Integer(100)) ; //已经定了当前集合时String类型 //遍历 //获取迭代器 Iterator it = array.iterator() ; while(it.hasNext()) { //java.lang.ClassCastException:类转换异常 String s = it.next() ; //这里不需要强制类型转换,因为已经定义了集合的类型树String类型 System.out.println(s); } }}
ArrayList集合存储自定义类型的对象,并遍历:
举例:
package org.westos_01;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;/** * 使用ArrayList集合存储自定义对象并遍历,加入泛型 * @author Administrator * */class Student { private String name ; private int age ; public Student() { super(); } public Student(String name, int age) { super(); 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; }}public class GenericDemo2 { public static void main(String[] args) { //创建集合对象 ArrayListObject中的泛型:array = new ArrayList () ; //=号右边的泛型:泛型推断 //创建学生对象 Student s1 = new Student("王昭君",25) ; Student s2 = new Student("西施",27) ; Student s3 = new Student("杨贵妃",25) ; Student s4 = new Student("貂蝉",28) ; //添加到集合中 array.add(s1) ; array.add(s2) ; array.add(s3) ; array.add(s4) ; //获取迭代器 Iterator it = array.iterator() ; while(it.hasNext()) { Student s = it.next() ; System.out.println(s.getName()+"----"+s.getAge()); } System.out.println("------------------"); //普通for循环 for(int x = 0 ; x < array.size() ; x ++) { Student s = array.get(x) ; System.out.println(s.getName()+"---"+s.getAge()); } }}
在早期的时候,使用Object类型代表任意类型,向上转型没有问题,使用向下转型的时候,可能会出现问题(需要的类型有问题),这个时候就需要引入泛型操作;
举例:
class ObjectTool方法中也可以定义泛型:{ //T表示可以接受的数据类型为任意类型 private T obj ; public T getObj() { return obj ; } public void setObj(T obj) { this.obj = obj ; }}public class ObjectToolDemo { public static void main(String[] args) { //创建ObjectTool对象 ObjectTool ot = new ObjectTool () ; //赋值 ot.setObj(new String("高圆圆")); String s = ot.getObj() ; System.out.println("姓名是:"+s); //ot.setObj(new Integer(27)); 直接隐藏的问题解决了 System.out.println("---------------"); ObjectTool ot2 = new ObjectTool () ; ot2.setObj(new Integer(27)); //ot2.setObj(new String("高圆圆")); Integer i = ot2.getObj() ; System.out.println("年龄是:"+i); }}
public class ObjectTool{ //泛型是可以在方法上定义的 public泛型在接口中: 两种情况:void show(T t) { //泛型的参数为任意类型 System.out.println(t); }}
//将泛型定义在接口上public interface Inter泛型高级(通配符): <?>:代表任意类型Object类型,或者任意的Java类; <? extends E>:向下限定,E的子类或者E这个类型;{ //接口中变量是常量: public static final int num ; public abstract void show() ; //抽象方法}//接口中泛型,子实现类的第一种情况,就是已经知道是什么类型了public class InterImpl implements Inter { @Override public void show() { System.out.println("hello"); }}//第二种情况,就是不知道具体的类型是什么public class Inter2Impl implements Inter { @Override public void show() { System.out.println("hello"); }}//测试类public class InterDemo { public static void main(String[] args) { //第一种情况的测试 //创建接口的子实现类对象 Inter i = new InterImpl() ; //第一种因为定义了String类型,所以只能用String的类型实现 i.show(); System.out.println("---------------------"); //第二种情况的测试 Inter i2 = new Inter2Impl (); //第二种可以使用任何累心进行定义 i2.show() ; Inter i3 = new Inter2Impl () ; i3.show(); }}
<? super E>:向上限定,E及其他的父类;
举例:
import java.util.ArrayList;import java.util.Collection;class Animal{ }class Cat extends Animal { }class Dog extends Animal{ }public class GenericDemo { public static void main(String[] args) { //创建集合对象,泛型如果明确的情况下,前后必须保持一致 //Collection
解决:对集合进行判断,非空判断解决;
举例:
public class ForDemo { public static void main(String[] args) { //定义一个数组,静态初始化 int[] arr = {11,22,33,44,55} ; //正常的方式,普通for循环 for(int x = 0 ; x < arr.length ; x ++) { System.out.println(arr[x]); } System.out.println("---------------------"); //增强for循环 for(int a :arr) { System.out.println(a); } //定义一个字符串类型的数组 String[] str = {"hello","world","java","javaee"} ; //增强for for(String s : str) { System.out.println(s); } System.out.println("-------------------------"); //创建一个集合 List静态导入: 特点: 1> 前提是该方法必须是静态的; 2> 导入到的一个方法的级别; 静态导入的格式: import static 包名 . 类名 . 方法名; ==> 方法必须是静态方法;list = new ArrayList () ; //添加元素 list.add("hello") ; list.add("world") ; list.add("java") ; //直接增强for for(String s:list) { System.out.println(s); } list = null ; //NullPointerException:如果集合为空遍历的话会报异常 //解决方法:给集合进行非空判断 if(list !=null) { for(String s:list) { System.out.println(s); } } }}
之前学习的导包:java.util.Scanner; 导入到类的级别;
举例:
import static java.lang.Math.abs; //导入到方法的级别import static java.lang.Math.pow;public class ImportStaticDemo { public static void main(String[] args) { System.out.println(Math.abs(-100)); System.out.println(Math.pow(2,3)); //可以使用带前缀的方式 System.out.println(java.lang.Math.abs(-100)); System.out.println("-------------------------"); //在测试,直接写方法名,前提静态导入 //System.out.println(abs(-100)); System.out.println(java.lang.Math.abs(-100)); System.out.println(pow(2,3)); //本身当前的某个类中的方法名和需要被静态导入的方法名一样,必须加上前缀 } //Date ---->有两个包下 java.util.Date java.sql.Date}可变参数: 当一个方法的参数个数不确定的时候,要使用可变参数; 格式: 修饰符 返回值类型 方法名(数据类型 . . . 变量名){...} 注意: 1> 变量名:看成一个数组;
2> 使用的时候数据类型;
举例:
public class ArgsDemo { public static void main(String[] args) { int a = 10 ; int b = 20 ; int c = 30 ; int d = 40 ; //当我们的参数不确定的情况下,就可以使用jdk5一个特性:可变参数 System.out.println(sum(a,b,c,d,50)); } //定义一个参数不确定的方法,通过可变参数操作 public static int sum(int...a) { //将a看成一个数组的形式 //求和:将a是多个参数的,看成数组 //先定义最终结果变量 int result = 0 ; //增强for遍历可变参数a for(int n :a) { result += n ; } return result; }}
ArrayList集合存储自定义对象并遍历:
举例:
package org.westos_01;import java.util.ArrayList;import java.util.Iterator;/** * * ArrayList集合存储自定义对象并遍历,有几种方式? * Iterator iterator() ; * listIterator listiterator();(可以不写) * 普通for循环:size()/get(int index) * 增强for循环 */public class ArrayListTest { public static void main(String[] args) { //创建ArrayList集合 ArrayListarray = new ArrayList () ; //创建学生对象 Student s1 = new Student("张三", 20) ; Student s2 = new Student("李四", 19) ; Student s3 = new Student("王五", 22) ; Student s4 = new Student("赵六", 26) ; //添加元素 array.add(s1) ; array.add(s2) ; array.add(s3) ; array.add(s4) ; //方式1:迭代器遍历:Iterator Iterator it = array.iterator() ; while(it.hasNext()) { Student s = it.next() ; System.out.println(s.getName()+"----"+s.getAge()); } System.out.println("-------------------"); //方式2:普通for for(int x = 0 ; x < array.size() ; x ++) { Student s = array.get(x) ; System.out.println(s.getName()+"----"+s.getAge()); } System.out.println("-------------------"); //方式3:增强for循环 for(Student s : array) { System.out.println(s.getName()+"----"+s.getAge()); } }}
针对数组操作的工具类:
Arrays提供了一个方法: public static <T> List<T> asList(T... a):将数组转换成固定大小的集合;注意:如果使用此方法,那么集合的长度不可变;
举例:
public class ArraysDemo { public static void main(String[] args) { //定义数组: /*String[] str = {"hello","world","java"} ; //将数组转换成固定大小的集合 List综合练习1:list = Arrays.asList(str) ;*/ //一步完成 List list = Arrays.asList("hello","world","java") ; //添加元素 //list.add("javaee") ;// java.lang.UnsupportedOperationException :集合固定的,长度是固定的 //list.remove("world") ; list.set(1, "javaee"); //将指定位置的元素修改为"javaee" //增强for for(String s:list) { System.out.println(s); } }}
package org.westos_03;import java.util.ArrayList;import java.util.Random;/** * * 需求:求10个1~20之间的随机数,要求数据不能重复 set集合 * *分析: * 可以使用数组,数组的长度固定,不够好,使用集合去做 * * 创建一个随机数类对象 * Random * * 获取指定的随机数的范围: * int nextInt() ; 获取的int类型的范围 * int nextInt(int n) ;获取1~n之间的数据 ,[0,n) * * 创建一个ArrayList集合对象,元素类型:Integer类型 * 定义统计遍历:count 是从0开始 * 判断如果统计遍历小于10 * 先计算出1-20之间的随机数,还需要判断集合中是否包含这些元素 * 如果不包含,添加,count++ * 包含,重复,不搭理了.... * * 大于10,不搭理 * * 遍历即可 */public class ArrayListTest { public static void main(String[] args) { //创建随机数类对象 Random r = new Random() ; //创建一个ArrayList集合 ArrayList综合练习2:array = new ArrayList () ; //定义统计变量 int count = 0 ; //判断统计变量的个数 while(count <10) { //个数符合的情况下,计算出1-20之间的随机数 int number = r.nextInt(20) +1 ; //需要判断集合总是发包含这个number if(!array.contains(number)) { array.add(number) ; count ++ ; } } //增强for for(Integer i : array) { System.out.println(i); } }}
package org.westos_02;import java.util.ArrayList;import java.util.HashSet;/** *需求 集合的嵌套遍历 有一个Java基础班,里面有很多学生,把一个班级集合:ArrayList不止一个Java基础班,这个时候就定义大集合:ArrayList >有三个基础班,分别遍历每一个班里面学生信息:(name,age) * */class Student { private String name ; private int age ; public Student() { super(); } public Student(String name, int age) { super(); 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; } }public class ArrayListTest { public static void main(String[] args) { //创建一个大的集合 ArrayList > bigArrayList = new ArrayList >() ; //创建第一个班的集合对象 ArrayList firstArray = new ArrayList () ; //创建学生对象 Student s1 = new Student("曹操",35) ;//后知后觉 Student s2 = new Student("诸葛亮", 29);//先知先觉 Student s3 = new Student("蒋干", 30) ;//不知不觉 //给第一个班添加元素 firstArray.add(s1) ; firstArray.add(s2) ; firstArray.add(s3) ; //将第一个集合添加到大集合中 bigArrayList.add(firstArray) ; //创建第二个班集合对象 ArrayList secondArray = new ArrayList () ; Student s11 = new Student("宋江",38) ; Student s22 = new Student("鲁智深", 29); Student s33 = new Student("武松", 30) ; secondArray.add(s11) ; secondArray.add(s22) ; secondArray.add(s33) ; //添加到大集合 bigArrayList.add(secondArray) ; //创建第三个集合对象 ArrayList thirdArray = new ArrayList () ; Student s111 = new Student("高圆圆",38) ; Student s222 = new Student("唐嫣", 29); Student s333 = new Student("刘若英", 30) ; thirdArray.add(s111) ; thirdArray.add(s222) ; thirdArray.add(s333) ; //添加到集合 bigArrayList.add(thirdArray) ; //增强for遍历:大集合 for(ArrayList array: bigArrayList) { for(Student s:array) { System.out.println(s.getName()+"---"+s.getAge()); } } }}
转载地址:http://tozad.baihongyu.com/