泛型

复习

数据结构

结构: 进栈的方式:压栈  出栈的方式:弹栈

先进后出: 类似于子弹弹夹

队列:先进先出 

又一个出口一个入口.   先来先出

 

当数据结构是数组的情况:

通过角标进行定位

需求:在当前x一个数组元素后添加一个元素

1.     定义一个新的数组,长度为原数组+1

2.     判断,看是否有x元素

  X元素之前的:将前面的位置对应的元素添加新数组中

  刚好是x:继续存储

  X元素之后的:将后面的数组长度-1存储到新数组中

 

对于数据结构是数组的特点

 查询快   增删慢(需要判断很多的条件)

 

链表结构:由很多链子将很多节点链接起来

   每一个节点(数据):数据域(值)和指针域

  

一个节点内有自己特定的地址值 里面有自己的存储值还有指向的下一个数据域地址值

  当需要查找一个元素是: 对于链接列表来说 从头开始查找指针域.以此来查询

 特点 查询慢(从头开始查找

增删快  

   当需要在x节点后插入一个节点  将x元素对应的指针域用temp来记录.

   插入的y元素有自己的指针域 将y对应的指针域和它进行交换.

   指向y元素  y元素的指针域再指向原本的下一个元素

   当删除元素是 直接将前面的一个元素指向下一个.  将中间的移除.

 

  

    List集合的子实现类特点:

ArrayList 为List接口(可变数组的)的子实现类,实现不同步.

底层数据结构是数组的形势,满足数组的特点.与数组的特点一直.查询快.增删慢

从线程安全问题来看:实现是不同步.因此是不安全的. 因此执行效率高.

Vector:可增长的对象数组,可以使用整数索引访问的组件.查询快.增删慢

从线程安全问题来看:实现是同步的,安全,因此效率低. 可以保证防止出现死锁的现象.

LinkedList:此实现是不同步的,  底层数据结构是连接链表.  特点.增删快,查询慢

在多线程中,只要线程不安全的类,都不回去使用.要使用安全的类.

安全的类 例如:

 StringBuffer   verson<E>  hashtable<K,V >

 

synchronizedList: 返回值指定列表支持的同步(线程安全)列表

在里面调用

Synchronized (同步锁对象).

一般默认采用ArrayList(效率高,速率快)    多线程采用Verson. 

 

ArrayList:

   底层数据结构是数组的形式,满足数组的特点:查询快,增删慢.

   从线程安全问题来看:线程不安全的,不同步,执行效率高

ArrayList是List的子实现类,因此元素可以重复:并且存取一致.

 

     用ArrayList1存储对象 输出:

 Eg: public class ArrayDemo1 {

public static void main(String[] args) {

    ArrayList array=new ArrayList();

    array.add("hello");

    array.add("hello");

    array.add("world");

    array.add("world");

    array.add("beauty");

    array.add("java");

    Iterator it=array.iterator();

    while(it.hasNext()){

       String s=(String)it.next();

       System.out.println(s);

    }

}

}

 

ArrayList存储自定义对象并进行遍历

Eg:1.建立学生对象.

3.     自定义对象,集合添加元素,迭代器遍历

//注意知道自己的类型是什么.j ava.lang.ClassCastException  转换类型不一致的时异常

Eg: public class ArrayListDemo2 {

public static void main(String[] args) {

    ArrayList array=new ArrayList();

    Student s1=new Student("钢铁侠",32);

    Student s2=new Student("绿巨人",30);

    Student s3=new Student("闪电侠",22);

    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=(Student)it.next();

       System.out.println(s.getName()+"--"+s.getAge());

    }  

}

}

 

Verson集合:底层是数组形式, 查询快,增删慢

从线程角度看:线程安全的类,同步,执行效率低

 Verson()构造一个空间量默认的数组大小为10.

 使用addElement来添加元素

  public  void  addElement():添加功能   相当于add方法.

publicsynchronized void addElement():   有同步代码块 转换到方法.

publicEnumeration<E> elements():获取元素.   相当于Iteratoriterator() ;

Synchronized可以保证线程安全.

 

Eg:

public class VectorDemo {

public static void main(String[] args) {

    Vector v=new Vector();

    v.addElement("Verson");

    v.addElement("ArrayList");

    v.addElement("List");

    v.addElement("Collection");

    v.addElement("Java");

    //枚举向量的组件

    Enumeration en=v.elements();

    while(en.hasMoreElements()){

       String s=(String)en.nextElement();

       System.out.println(s);

    }  

}

}

 

 

LinkedList:    底层数据结构是链接列表,特点:查询慢,增删快

                          从线程角度看:线程不安全的一个类,不同步,执行效率高

 特有功能:

添加 : public voidaddFirst(E e)将指定元素插入此列表的开头。

          public void addLast(E e)将指定元素添加到此列表的结尾。

获取:  public Object getFirst()返回此列表的第一个元素

            public Object getLast()返回此列表的最后一个元素。

删除:  public Object removeFirst()移除并返回此列表的第一个元素。

            public Object removeLast()移除并返回此列表的最后一个元素。

Eg:

public static void main(String[] args) {

    LinkedList link=new LinkedList();

    link.addFirst("hello");//插入开头

    link.addFirst("Link");

    link.addFirst("List");

    link.addLast("Java")//加到结尾

    Object obj=link.getFirst();

    Object obj2=link.getLast();  //获取第一个和最后一个元素

    移除并返回第一个元素

    System.out.println("removeFirst:"+link.removeFirst());

}

}

 

 

练习题:ArrayList去除集合中的字符串的重复元素.

public class ArrayListText {

public static void main(String[] args) {

    ArrayList array=new ArrayList();

    array.add("RNG");

    array.add("EDG");

    array.add("RNG");

    array.add("WE");

    ArrayList newarray =new ArrayList();

    Iterator it=array.iterator();

    while(it.hasNext()){

    Strings=(String)it.next();

    if(!newarray.contains(s)){

        newarray.add(s);

    }

    }

    Iterator it2=newarray.iterator();

    while(it2.hasNext()){

    Strings=(String)it2.next();

    System.out.println(s);

    }

}

}

ArrayList去除集合中字符串的重复元素,附加条件:不能创建新集合.

由选择排序开始:从0索引对应的元素以此和后面对应的索引进行比较.

继续…

for循环嵌套 比较  如果重复 使用remove方法.

Eg:

import java.util.ArrayList;

import java.util.Iterator;

public class ArrayListDemo {

public static void main(String[] args) {

    ArrayList array=new ArrayList();

    array.add("RNG");

    array.add("EDG");

    array.add("RNG");

    array.add("WE");

    array.add("WE");

    for(int x=0;x<array.size()-1;x++){

    for(inty=x+1;y<array.size();y++){

    if(array.get(x).equals(array.get(y))){

    array.remove(y);

    y--;

    }

    }

    }

    Iterator it=array.iterator();

    while(it.hasNext()){

    Strings=(String) it.next();

    System.out.println(s);

    }

}

}

输出结果:

RNG

EDG

WE

 

ArrayList去除集合中自定义对象的重复值(对象的成员变量值都相同)

 

当使用创建新集合是,用contain()方法比较,发现没有去除掉.

Contains()底层依赖于equals()方法,该方法默认比较的是对象的地址值.

必须重写Object的equlas()方法 才能比较成员变量的值是否相同.

首先在Student类中重写equals放法:

Eg: public class ArrayListText3 {

public static void main(String[] args) {

    ArrayList array=new ArrayList();

    Student s1 = new Student("罗斯", 30) ;

    Student s2 = new Student("猎人", 22) ;

    Student s3 = new Student("法师", 26) ;

    Student s4=  new Student("法师",26);

    Student s5=  new Student("法师",26);

    Student s6=  new Student("法师",26);

    Student s7 = new Student("猎人", 22) ;

    array.add(s1);

    array.add(s2);

    array.add(s3);

    array.add(s4);

    array.add(s5);

    array.add(s6);

    array.add(s7);

    ArrayList newArray = new ArrayList() ;

    Iterator it = array.iterator() ;

    while(it.hasNext()){

       Student s = (Student) it.next() ;

       if(!newArray.contains(s)){

           newArray.add(s) ;

       }

    }

    Iterator it2 = newArray.iterator() ;

    while(it2.hasNext()){

       Student s = (Student) it2.next() ;

       System.out.println(s.getName()+"---"+s.getAge());

    }

}

}

 

泛型:

使用ArrayList存储元素:

给ArrayList集合存储一些元素,String类型的元素,Integer类型的元素.

当给ArrayList类型存储元素时,存储不同元素的 当通过迭代器遍历时,编译不会出错.

运行出错 使用string类型接受,会出现 : ClassCastException 类转换异常

 

当定义一个数组时:字符串数组.

数组设计这样好处:提取告诉开发者,这里装String类型的元素.Java根据数组特点.

泛型的使用引用出来

 

格式<引用类型>:泛型只能放引用类型.

泛型的好处:

1. 将运行时期异常提前到编译时期

2. 解决了黄色警告线异常

3. 在获取数据时,不需要进行强制转换.

 

 泛型可以应用在类上,接口上,方法上

在集合中使用比较多..

 

Eg:<String>类型:

Eg:

import java.util.ArrayList;

import java.util.Iterator;

public class GenericDemo2 {

public static void main(String[] args) {

    ArrayList<String> array=new ArrayList<String>();

    array.add("javase");

    array.add("javaweb");

    array.add("javaee");

    //获取迭代器对象

    Iterator <String>it=array.iterator();

    while(it.hasNext()){

       Strings=it.next();

       System.out.println(s);

    }

}

}

 

使用ArrayList集合存储自定义对象并进行遍历

Eg:

public class GenericDemo3 {

public static void main(String[] args) {

    ArrayList<Student>array=new <Student>ArrayList();

    Student s1=new Student("金刚狼",28);

    Student s2=new Student("万磁王",26);

    Student s3=new Student("教授",45);

    Student s4=new Student("冰男",25);

    array.add(s1);

    array.add(s2);

    array.add(s3);

    array.add(s4);

    Iterator<Student> it=array.iterator();

    while(it.hasNext()){

       Student s=it.next();

       System.out.println(s.getName()+"--"+s.getAge());

    }

}

}

输出结果:

金刚狼--28

万磁王--26

教授--45

冰男—25

 

 

泛型可以提供程序的安全性!

  早期时候:用Object类型代替任意的类型

  向上转型是不会出现异常

但是向下转型的时候,由于隐藏了类型转换,导致出现错误!(需要知道自己需要的类型)

   Eg:

public class ObjectToolDemo {

public static void main(String[]args) {

    ObjectTool ot=new ObjectTool();

    ot.setObj(27);//Object类型

    Integer i=(Integer)ot.getObj();//向下转型

    System.out.println("年龄是"+i);

   

    ObjectTool ot2 = new ObjectTool() ;

    ot2.setObj("龙哥");

    String str = (String) ot2.getObj() ;//向下转型

    System.out.println("姓名是:"+str);

}

}

 

将泛型定义在类上:  解决不安全的错误.  

          在开发中根据具体类型在测试中书写

类:

public class ObjectTool<T> {

 private T obj;

 public void setObj(T obj){

     this.obj=obj;

 }

 public T getObj(){

     return obj;

 } 

}

测试类:

public class ObjectToolDemo {

public static void main(String[] args) {

    ObjectTool<String> str=new ObjectTool<String>();

    str.setObj("龙哥");

//  Integer i=str.getObj(); //类型不匹配

    String name=str.getObj();

    System.out.println("姓名是:"+name);

    ObjectTool<Integer> str2=new ObjectTool<Integer>();

    str2.setObj(20);

    Integer i=str2.getObj();

    System.out.println("年龄是"+i);

}

}

输出结果:

姓名是:龙哥

年龄是20

 

泛型定义在方法上:调用方便,不需要定义多个重载方法,一个级可以返回多个类型

 定义在方法上:

public class ObjectTool{

 public <T>void show(T t){

     System.out.println(t);

 }

}

测试类:

public class ObjectToolDemo {

public static void main(String[] args) {

     ObjectTool ot=new ObjectTool();

     ot.show("javase");

     ot.show(true);

     ot.show(20);

}

}

输出结果:

javase

true

20

 

泛型定义在接口上:

 

接口:

public interface Inter<T> {

    public abstract void show(T t);

}

接口的子实现类:

public class InterImpl<T> implements Inter<T>{

    //子实现类

    @Override

    public void show(T t) {

       System.out.println(t);

    }

}

测试类:

public class InterDemo {

public static void main(String[] args) {

    //第一种状况

//接口加入泛型:接口的子实现类已经知道传递了是什么数据类型

    Inter<String> i=new InterImpl<String>();

    i.show("Javase");

    i.show("javaweb");

    //第二种状况

// 接口的子实现类在实现接口的时候,不知道具体的数据类型是什么

//在测试类的时候,传入具体数据类型

    Inter<Integer>i2=new InterImpl<Integer>();

    i2.show(27);

    Inter<String> i3=new InterImpl<String>();

    i3.show("小虎");

}

}

输出结果:

Javase

javaweb

27

小虎

 

 

泛型的高级:通配符

任意类型<?>   <? Extends E>:向下限定,E类型以及E类型的子类

<? Super E>:向上限定,E类型以及E类型的父类

 

import java.util.ArrayList;

import java.util.Collection;

public class GenericDemo1 {

public static void main(String[] args) {

    //创建Collection集合的对象,前后数据类型保持一致

    //Collection<Object> c1 = newArrayList<Animal>() ;

    //Collection<Object> c3 = newArrayList<Dog>() ;

    //会报错因为前后的数据类型不一致

    Collection<Object> c1=new ArrayList<Object>();

    // <?> :可以是任意类型,包括Object类型以及任意的Java

    Collection<?> c4 = new ArrayList<Object>() ;

    Collection<?> c5 = new ArrayList<Animal>() ;

    Collection<?> c6 = new ArrayList<Cat>() ;

   

    //<? extends E>:向下限定,E类型以及E类型的子类

    Collection<? extends Object> c8 = new ArrayList<Object>() ;

    Collection<? extends Object> c11 = new ArrayList<Cat>() ;

   

    //<? super E>:向上限定,E类型以及E类型的父类

    Collection<? super Animal> c12 = new ArrayList<Object>() ;

    Collection<? super Cat> c13=new ArrayList<Animal>();

   

}

class Animal{

}

class Cat extends Animal{  

}

class Dog extends Animal{  

}

}

 

Jdk5以后提供了很多特性:泛型,增强for循环,可变参数,静态导入,自动拆装箱,枚举等

增强for循环   书写格式

  for(集合或者数组中数据类型 变量名:集合或者数组的对象名){

        输出变量名

}

增强for循环的弊端:

遍历数组或者集合时候,数组对象或者集合对象不能为Null

否则出现空指针异常.

如果对象为空,加上非空判断

增强for循环的出现就是为了替代迭代器遍历集合,以后开发中使用增强for遍历元素

 

Eg:

import java.util.ArrayList;

public class forDemo {

public static void main(String[] args) {

    int []arr ={12,22,5,23,263,23};

    //普通for循环遍历

    for(int x=0;x<arr.length;x++){

       System.out.print(arr[x]+"");

    }

    System.out.println("");

    //使用增强for遍历

    for(int i :arr){

       System.out.print(i+" ");

    }

    System.out.println("");

    String []strArray ={"Javase","JavaWeb","JavaEE"};

    for(String s:strArray){

       System.out.println(s);

    }

    System.out.println("----------");

    for(String s:strArray){

       System.out.println(s);

    }

    ArrayList<String>array =new ArrayList<String>();

    array.add("JavaSE");

    array.add("JavaWeb");

    array.add("JavaEE");

    //当数组为空时:增强for遍历会出现空指针异常

}

}

 

输出结果:

12 22 5 23 263 23 

12 22 5 23 263 23

Javase

JavaWeb

JavaEE

----------

Javase

JavaWeb

JavaEE

 

当使用该方法添加元素时,出现ConcurrentModificationException异常

    //使用增强for遍历该集合

       for(Strings :array){

           //获取到每一个元素

           //java.util.ConcurrentModificationException

           判断当前集合中是否有"world",如果有就添加元素

           if("world".equals(s)){

              array.add("javaee");

           }

       }

 

增强for循环是为了替代迭代器:

代码简单,开发中经常使用.

 

使用ArrayList集合存储自定义对象并遍历

方式:

1. toArray()

2. Collection集合的迭代器: Iterator iterator();

3. List集合的迭代器:ListIterator listiterator();     

4. 普通for循环:size()和get(int index)相结合

5. 增强for循环

 

Eg:

import java.util.ArrayList;

import java.util.Iterator;

public class ForText1 {

public static void main(String[] args) {

   // 创建ArrayList集合

    ArrayList<Student> array = new ArrayList<Student>();

    Student s1=new Student("钢铁侠",29);

    Student s2=new Student("鹰眼",26);

    Student s3=new Student("绿巨人",31);

    Student s4=new Student("猪猪侠",7);

    array.add(s1);

    array.add(s2);

    array.add(s3);

    array.add(s4);

    //普通for循环:sizeget(intindex)方法结合

    for(int x =0 ; x < array.size() ; x ++){

       Student s = array.get(x) ;

       System.out.println(s.getName()+"---"+s.getAge());

    }

  //Collection集合的迭代器:Iterator iterator();

    Iterator<Student> it =array.iterator() ;

    while(it.hasNext()){

       Student s = it.next() ;

       System.out.println(s.getName()+"----"+s.getAge());

    }

    //增强for循环

    for(Student s : array){

       System.out.println(s.getName()+"----"+s.getAge());

    }

}

}

 

上周作业题:

ArrayList<Student>不止一个

大的集合:ArrayList<ArrayList<Student>>

集合的嵌套遍历.

首先建一个学生类:

Eg:

import java.util.ArrayList;

public class ArrayListText {

public static void main(String[] args) {

    //大集合对象

    ArrayList<ArrayList<Student>> bigArray=newArrayList<ArrayList<Student>>();

    //第一个子集合对象

    ArrayList<Student>firstArray=new ArrayList<Student>();

    Student s1=new Student("钢铁侠",32);

    Student s2=new Student("美国队长",28);

    Student s3=new Student("鹰眼",26);

    firstArray.add(s1);

    firstArray.add(s2);

    firstArray.add(s3);

    bigArray.add(firstArray);//将第一个小集合添加到大集合里面

   

    ArrayList<Student>secondArray=new ArrayList<Student>();

    Student s4=new Student("金刚狼",34);

    Student s5=new Student("风暴女",26);

    Student s6=new Student("火男",32);

    secondArray.add(s4);

    secondArray.add(s5);

    secondArray.add(s6);

    bigArray.add(secondArray);

   

    ArrayList<Student>thirdArray=new ArrayList<Student>();

    Student s7=new Student("索隆",24);

    Student s8=new Student("娜美",20);

    Student s9=new Student("乌索普",23);

    thirdArray.add(s7);

    thirdArray.add(s8);

    thirdArray.add(s9);

    bigArray.add(thirdArray);

    //增强for遍历

    //大集合:ArrayList<ArrayList<Student>>

    for(ArrayList<Student> array:bigArray){

       //子集合:ArrayList<Student>

       for(Student s:array){

           System.out.println(s.getName()+"--"+s.getAge());

       }

    }

}

}

 

输出结果:

钢铁侠--32

美国队长--28

鹰眼--26

金刚狼--34

风暴女--26

火男--32

索隆--24

娜美--20

乌索普--23

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值