Java学习 ---- List集合子类与泛型

Day16.01_____ArrayList类

  • ArrayList中遍历集合的方式
    • 通过size()方法和get(int index)方法
    • 通过迭代器Iterator中的hasNext()和next()方法
  • ArrayList类的特点
    • 查询快,增删慢
    • 线程不安全,相比Vector效率高
  • ArrayList类的运用
    • 遍历对象,并获取对应对象中的某些属性
    • 删除集合中重复的字符串
      	// 实现删除重复字符串方法
      	private static void demo2() {
      		ArrayList list = new ArrayList();
      		list.add("a");
      		list.add("a");
      		list.add("b");
      		list.add("b");
      		list.add("c");
      		list.add("c");
      		System.out.println(list.toString());
      		System.out.println(getSingle(list));;
      	}
      	public static ArrayList getSingle(ArrayList list) {
      		ArrayList newList = new ArrayList();
      		for(int i = 0 ; i < list.size() ; i++) {
      			String temp = (String)list.get(i);
      			if(!newList.contains(temp)) {
      				newList.add(temp);
      			}
      		}
      		return newList;
      	}
      
    • 删除集合中重复的对象
      // Person类实现
      public class Person {
      		private String name;
      		private int age;
      		public Person() {
      			super();	
      		}
      		public Person(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;
      		}
      		@Override
      		public String toString() {
      		   return "Person [name=" + name + ", age=" + age + "]";
      		}
      }
      
      	// 实现删除重复对象方法
      	private static void demo3() {
      		ArrayList list = new ArrayList();
      		list.add(new Person("张三",23));
      		list.add(new Person("张三",23));
      		list.add(new Person("李四",24));
      		list.add(new Person("李四",24));
      		System.out.println(list);
      		System.out.println(getSingel(list));
      	}
      	public static ArrayList getSingel(ArrayList list) {
      		ArrayList newList = new ArrayList();
      		Iterator it = list.iterator();
      		while(it.hasNext()) {
      			Person p = (Person)it.next();
      			if(!newList.contains(p)) {
      				newList.add(p);
      			}
      		}
      		return newList;
      	}
      
      • 现象:运行代码我们会发现集合并没有发生变化
      • 原因:通过查看contains方法的底层实现,我们发现contains方法底层是依赖于Object类的equals方法的,而Object类中的equals方法比较引用对象时,比较的是对象的地址值,因此!newList.contains§会一直满足,那么解决这个问题,我们的办法是重写equals方法,那么在哪里重写呢?因为Person类默认是继承Object类的,因此我们只需要在Person类中去重写Object类就可以了,修改如下:
        public class Person {
        		private String name;
        		private int age;
        		public Person() {
        			super();	
        		}
        		public Person(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;
        		}
        		@Override
        		public String toString() {
        		   return "Person [name=" + name + ", age=" + age + "]";
        		}
        		@Override
        		public boolean equals(Object obj) {
        		   Person p = (Person)obj;
        		   return this.name.equals(p.name) & this.age == p.age;
        		}
        }
        
      • 集合中除了contatins方法底层是依赖equals方法外,还有remove方法也是依赖于equals方法的,因此如果遇见无法删除的情况,重写equals方法即可解决


Day16.02_____Vector类(了解)

  • 因为Vector类出现的比较早,在JDK1.0的时候就出现了,因此最开始没有List的时候,Vector是没有add这些方法的
  • 成员方法
    • addElement(Object obj)
      添加对象
    • elementAt(int index)
      根据索引查询对象
  • Vector特点:
    • 查询慢,增删快
    • 线性安全,相比于ArrayList效率慢


Day16.03_____LinkedList类

  • LinkedList特有的功能
    • addFirst(Object o)
      返回值类型void,用于在链表的首位添加数据
    • addLast(Object o)
      返回值类型void,用于在链表的末尾添加数据
    • getFirst()
      返回值类型Object,用于获取集合的第一个对象
    • getLast()
      返回值类型Object,用于获取集合的最后一个对象
    • removeFirst()
      返回值类型Object,用于移除集合中的第一个对象,并将该对象返回
    • removeLast()
      返回值类型Object,用于移除集合中的最后一个对象,并将该对象返回


Day16.04_____泛型的基本概念

  • 泛型的表示(通过<>进行表示)
    例子:ArrayList类的泛型表示(其余接口类的泛型表示也是一样的)
    ArrayList list = new ArrayList();
    list.add(new Person("张三",23));
    list.add(new Person("李四",24));
    Iterator it = list.iterator();   
    while(it.hasNext()) {
    	Person p = it.next();		//不用在强制转换
    	System.out.println(p);
    }
    
    在JDK1.7版本以后泛型可以这么写:
    ArrayList list = new ArrayList<>();
  • 泛型的类型
    在<>中只能是引用数据类型,如果想要传入基本类型数据,里面必须使用基本数据类型对应的包装类
  • 泛型解决的问题
    我们没有规定泛型的时候,通常<>中的Object类型的,因为Object类是所有类的根类,可以接收所有的子类(通过父类引用指向子类对象),但正因为如此会出现以下问题,如代码:
    ArrayList list = new ArrayList();
    list.add(123);
    list.add("abc");
    list.add(new Person("张三",23));
    Iterator it = list.iterator();
    while(it.hasNext()) {
    		Person p = (Person)it.next();
    		System.out.println(p.getName() + p.getAge());
    }
    
    以上代码在编译的时候不会报错,但是在运行的时候会报错,原因在于我们用add方法的时候不仅添加了int类型的数据,还添加了String类型的数据,但是我们在遍历的时候,把int类型和String类型的数据都强转成了Person类型的数据,这样肯定会报错,而报的错就是java.lang.ClassCastException ----> 类转换异常,为了解决这样的问题,在JDK1.5的时候引入了泛型这样的概念
  • 泛型的意义
    将运行出现的问题转换成编译的问题
  • 泛型什么时候创建
    泛型在创建对象的时候创建
  • 泛型的好处
    • 在遍历的时候,获取对象时不用在强转
    • 解决了类转换异常
  • 定义泛型的注意事项
    • 在我们遍历集合的时候,Iterator的泛型类型必须和集合的泛型类型相同
  • 泛型的应用
    • 当我们想要将遍历集合的方法抽取出来提供给每个类用时,我们就可以运用到泛型
      public static void print(ArrayList list) {
      			Iterator it = list.iterator();
      			while(it.hasNext()) {
      				T t = it.next();
      				System.out.println(t);
      			}
      }
      



Day16.05_____泛型类

  • 泛型类的定义

    public class Demo{
    		private T t;
    		public void set(T t){
    			this.t = t;
    		}
    		public T get(){
    			return t;
    		}
    }
    
  • 泛型方法的定义

    public class Demo{
    		private T t;
    		public void set(T t){
    			this.t = t;
    		}
    		public T get(){
    			return t;
    		}
    		public void method(T t){
    			System.out.print(t);
    		}
    }
    
  • 泛型类中静态方法的定义

    public class Demo{
    		private T t;
    		public void set(T t){
    			this.t = t;
    		}
    		public T get(){
    			return t;
    		}
    		public void method(T t){
    			System.out.print(t);
    		}
    		public static void print(M m){
    			System.out.print(m);
    		}
    }
    

    注意:因为静态的方法是随着类的加载而加载的,而泛型是在创建对象的时候产生的,那么在泛型类中如果要定义静态方法,必须给静态方法重新设置一个泛型,让使用端在调用这个方法的时候对其重新赋值泛型。还需要注意的是即便static与类中的泛型类型相同,但两个仍然属于两个泛型,总结一句话就是,静态方法的泛型是你在调用的时候传入的泛型,传入的是什么就是什么,和类的泛型无关


Day16.06_____泛型接口

  • 泛型接口的定义
    interface Inter{
    		public void method(T t);
    	}
    	class Demo implements Inter{
    		public void method(String t){
    			System.out.println("hello");
    		}
    }
    
  • 泛型接口中泛型在什么时候指定?
    当类实现接口的时候,就会确定泛型的类型


Day16.07_____泛型高级之通配符

  • 泛型通配符表示
    通过?来表示
  • ?extends E含义
    表示?继承于E
  • ?extends E的用处:
    当我们为一个集合指定了泛型后,整个泛型只能添加指定类型的泛型,但是如果我们在泛型中使用ArrayList时,这个集合中不仅可以接收Person类型的数据,还可以接收Person子类的数据。其中E是,这种类型也叫固定上边界


Day16.08_____增强for循环—>foreach

  • foreach格式

    • 集合的遍历
       for(泛型类型 临时变量名:容器名){
      		语句;
      }
      
      这里的容器名指的是,定义集合的变量名;
      如果没有泛型类型,默认为Object类型
    • 数组的遍历
       for(数组类型 临时变量名:容器名){
      		语句;
       }
      
      这里的容器名指的是,定义数组的变量名字
  • foreach例子

    ArrayList list = new ArrayList<>();
    list.add("a");
    list.add("b");
    list.add("c");
    list.add("d");
    for (String string : list) {
    	System.out.println(string);
    }
    
  • foreach与Iterator的区别

    • foreach既可以遍历数组又可以遍历集合,而Iterator只能遍历集合
    • foreach书写简洁,Iterator书写复杂


Day16.09_____可变参数

  • 什么是可变参数
    可变参数其实就是一个长度可以变化的数组
  • 可变参数的定义
    public void method(int … arr){}
  • 例子
    public static void main(String[] args) {
    		method(11,22,33,44,55);
    }
    public static void method(int ... arr) {
    		for (int i : arr) {
    			System.out.println(i);
    		}
    }
    
    可变参数的取值范围为0—正无穷
    传入参数的时候,必须与可变参数的参数类型一致
  • 注意事项
    当我们使用了可变参数以后,可变参数后面不能再定义其他参数,因为后面的这个参数永远也没有办法获取到。但是在可变参数的前面我们可以定义其他参数

    public static void method(int … arr,int a) ----> 这样是错误的
    public static void method(int a,int … arr) ----> 这样是可以的



Day16.10_____JDK1.5特性

  • 自动拆装箱
  • 泛型
  • for增强循环
  • 静态导入( 静态导入导入的其实是方法 )
  • 可变参数

你可能感兴趣的:(Java基础)