Java进阶技术:泛型

泛型

概念:

  • public class LinkedList
  • extends AbstractSequentialList
  • implements List, Deque, Cloneable, java.io.Serializable{}
  • public interface Deque extends Queue {}
  • public interface Queue extends Collection {}
  • public interface Collection extends Iterable {}

我们上面的代码中出现的<?>是什么东西呢,它叫泛型,常用来和集合对象一同使用,所以我们在开始学习集合之前,必须先了解下什么是泛型。而且泛型概念非常重要,它是程序的增强器,它是目前主流的开发方式。

泛型是(Generics)是JDK1.5 的一个新特性,其实就是一个『语法糖』,本质上就是编译器为了提供更好的可读性而提供的一种小手段,小技巧,虚拟机层面是不存在所谓『泛型』的概念的。

作用:

  • 通过泛型的语法定义,约束集合元素的类型,进行安全检查,把错误显示在编译期
  • 代码通用性更强,后面有案例
  • 泛型可以提升程序代码的可读性,但它只是一个语法糖(编译后这样的东西就被删除,不出现在最终的源代码中),对于JVM运行时的性能是没有任何影响的。

泛型声明 :
泛型可以在接口、方法、返回值上使用:

  • java.util.List泛型接口/类:
    public interface Collection {}
  • 泛型方法的声明:
    public void print(E e) {}
  • 在方法返回值前声明了一个表示后面出现的E是泛型,而不是普通的java变量。

常用名称:

  • E - Element (在集合中使用,因为集合中存放的是元素)
  • T - Type(Java 类)
  • K - Key(键)
  • V - Value(值)
  • N - Number(数值类型)
  • ? - 表示不确定的java类型
public class Test1 {
    public static void main(String[] args) {
       int[] a = new int[3];
       a[0]=1;
       a[1]=2;   
       //int类型的数组,规定了数组里的数据类型,类型不对就报错。
//     a[2]="hello";       
       //1,泛型的标志<>
       //2,泛型的好处:规定了数据的类型,不能想放什么数据就放什么类型,要遵守泛型规定的类型
       //3,泛型的数据类型只能是引用类型,不能是基本类型
       List<Integer> list = new ArrayList<Integer>();
       list.add(1);
       list.add(2);
       
//4,如果类型不对,把运行时期才会 报的错ClassCastException直接在编译时期就报出来

//     list.add("a");
//     list.add('b');       
       Iterator it = list.iterator();
       while(it.hasNext()) {
           Integer s = (Integer) it.next();
           System.out.println(s);
       }      
    }
  • 代码通用性更强
  • 传统方式通过重载多态实现,方法同名,参数类型不同。
public class TestOldStyle {
    public static void print(Integer[] dArray) {
       for( Integer d : dArray) {
           System.out.println(d);
       }
    } 
    
    public static void print( String[] sArray) {
       for( String s : sArray) {
           System.out.println(s);
       }
    }   
    
    public static void main(String[] args) {
       Integer[] scores = new Integer[]{100,98,80};
       String[] names = new String[]{"语文","数学","英语"};      
       TestOldStyle.print(scores);
       TestOldStyle.print(names);
    }
}

泛型方式:

public class TestGenarics {
    public static <E> void print(E[] arr) {
       for(E e : arr) {
           System.out.println(e);
       }
    } 
    
    public static void main(String[] args) {
       Integer[] scores = new Integer[]{ 100,98,80 };
       String[] names = new String[]{ "语文","数学","英语" };
       Double[] moneys = new Double[] { 10.1,20.2,30.3 };      
       TestGenarics.print(scores);
       TestGenarics.print(names);
       TestGenarics.print(moneys);
    }
}

Collection接口

概述:

  • 英文名称Collection,是用来存放对象的数据结构。其中长度可变,而且集合中可以存放不同类型的对象。并提供了一组操作成批对象的方法。
  • 数组的缺点:长度是固定不可变的,访问方式单一,插入、删除等操作繁琐。

集合的继承结构
在这里插入图片描述

>Collection接口

>-- List接口  : 数据有序,可以重复。

   -- ArrayList子类

   -- LinkedList子类

>-- Set接口  : 数据无序,不可以存重复值

   -- HashSet子类

>-- Map接口  : 键值对存数据

   -- HashMap

>-- Collections工具类
常用方法:
  • boolean add(E e):添加元素。
  • boolean addAll(Collection c):把小集合添加到大集合中 。
  • boolean contains(Object o) : 如果此 collection 包含指定的元素,则返回 true。
  • boolean isEmpty() :如果此 collection 没有元素,则返回 true。
  • Iterator iterator():返回在此 collection 的元素上进行迭代的迭代器。
  • boolean remove(Object o) :从此 collection 中移除指定元素的单个实例。
  • int size() :返回此 collection 中的元素数。
  • Objec[] toArray():返回对象数组

List接口:

有序的 collection(也称为序列)。此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。

特点:
1、 数据有序
2、 允许存放重复元素
3、 元素都有索引

常用方法:

ListIterator listIterator()

  •      返回此列表元素的列表迭代器(按适当顺序)。
    

ListIterator listIterator(int index)

  •      返回列表中元素的列表迭代器(按适当顺序),从列表的指定位置开始。
    

void add(int index, E element)

  •      在列表的指定位置插入指定元素(可选操作)。
    

boolean addAll(int index, Collection<? extends E> c)

  •      将指定 collection 中的所有元素都插入到列表中的指定位置(可选操作)。
    

List subList(int fromIndex, int toIndex)

  • 返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图。
    

E get(int index)

  •      返回列表中指定位置的元素。  
    

int indexOf(Object o)

  •      返回此列表中第一次出现的指定元素的索引;如果此列表不包含该元素,则返回 -1。
    

ArrayList

概述:

  1. 存在于java.util包中。
    
  2. 内部用数组存放数据,封装了数组的操作,每个对象都有下标。
    
  3. 内部数组默认初始容量是10。如果不够会以1.5倍容量增长。
    
  4. 查询快,增删数据效率会降低。
    

创建对象:

  • new ArrayList():初始容量是10

测试常用方法:

public class Test3_AL {
       public static void main(String[] args) {
              ArrayList list = new ArrayList();
              list.add("aaa");//存入数据
              list.add("123");
              list.add("ccc");
              list.add("ddd");
              System.out.println(list);//list中内容
              System.out.println(list.size());//集合长度
              System.out.println(list.get(1));//根据下标获取元素                     
              System.out.println();
              System.out.println(list.remove(2));//移除下标对应的元素
              System.out.println(list);   
                                
               //下标遍历
	for (int i = 0; i < list.size(); i++) {
		System.out.print(list.get(i));
}
                     
       //Iterator迭代遍历,封装了下标
                     Iterator<String> it = list.iterator();
                     while (it.hasNext()) {//如果有数据
                            String s = it.next();//一个一个向后遍历
                            System.out.println(s);
                     }      
         }
}

LinkedList

在这里插入图片描述
常用方法:

  • add() get()
  • size()
  • remove(i)
  • remove(数据)
  • iterator()
  • addFirst() addLast()
  • getFirst() getLast()
  • removeFirst() removeLast()

测试迭代器遍历,双向链表:下标遍历效率低,迭代器遍历效率高

public class tt {
       public static void main(String[] args) throws Exception {
              LinkedList ll = new LinkedList ();
              for (int i = 0; i < 100000; i++) {
                     ll.add(100);
              }
              f1(ll);
              f2(ll);
       } 
       private static void f2(LinkedList<Integer> ll) {
              long t = System.currentTimeMillis();
              Iterator it = ll.iterator();
              while(it.hasNext()) {
                     it.next();
              }
              t = System.currentTimeMillis()-t;
              System.out.println("=====iterator========="+t);//16
       } 
       private static void f1(LinkedList<Integer> ll) {
              long t = System.currentTimeMillis();
              for (int i = 0; i < ll.size(); i++) {
                     ll.get(i);
              }
              long t1 = System.currentTimeMillis();
              System.out.println("~~~~for~~~~~~~"+(t1-t));//9078
       }
}

发布了36 篇原创文章 · 获赞 13 · 访问量 1061

猜你喜欢

转载自blog.csdn.net/weixin_44598691/article/details/104847105