泛型
概念:
- 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
概述:
存在于java.util包中。
内部用数组存放数据,封装了数组的操作,每个对象都有下标。
内部数组默认初始容量是10。如果不够会以1.5倍容量增长。
查询快,增删数据效率会降低。
创建对象:
- 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
}
}