学习记录:泛型与集合框架
一 泛型
泛型是JDK1.5后推出,目的是建立具有安全类型的集合框架,如散列映射,链表等数据结构
1.1 泛型类的声明
语法:class 名称<泛型列表>
该语法可声明一个类,叫泛型类
泛型类声明的时候,泛型列表给出的泛型可以作为类的成员变量的类型,方法的类型以及局部变量的类型
public class Cone<E> {
double height;
E bottom;
public Cone(E b){
bottom=b;
}
}
1.2 使用泛型类声明对象
和普通的类相比,泛型类声明和创建对象时,类名后多了一对"<>",而且必须用具体的类型替换”<>“
Cone<Circle> coneOne;
coneOne=new Cone<Circle>(new Circle());
例1
Cone.java
package second;
public class Cone<E> {
double height;
E bottom;
public Cone(E b) {
bottom = b;
}
public void setHeight(double h){
height=h;
}
public double computerVolume() {
String s = bottom.toString();
//泛型变量只能调用从Object 类继承或重写的方法
Double area = Double.parseDouble(s);
return 1.0 / 3.0 * area * height;
}
}
Rect.java
package second;
public class Rect {
double sideA,sideB,area;
Rect(double a,double b){
sideA=a;
sideB=b;
}
public String toString(){
area=sideA*sideB;
return area+"";
}
}
Circle.java
package second;
public class Circle {
double area,radius;
Circle(double r){
radius=r;
}
public String toString(){
area=radius*radius*Math.PI;
return area+"";
}
}
测试主类
package second;
public class Example15_1 {
public static void main(String[] args) {
Circle circle = new Circle(10);
Cone<Circle> coneOne = new Cone<>(circle);
coneOne.setHeight(10);
System.out.println(coneOne.computerVolume());
Rect rect = new Rect(15,23);
Cone<Rect> rectCone = new Cone<>(rect);
rectCone.setHeight(98);
System.out.println(rectCone.computerVolume());
}
}
java泛型的目的:
1)建立具有类型安全的数据结构
2)使用泛型类建立的数据结构时,不必进行强制类型转换
二 链表
需要动态的减少或增加数据项时可以使用链表
链表是由若干结点的对象组成的一种数据结构,每个结点含有一个数据和下一个结点的引用(单链表),或含有一个数据并含有上一个结点的引用和下一个结点的引用(双链表)
2.1 LinkedList 泛性类
java.util包LinkedList 泛型类创建的对象已链表存储数据,创建的对象成为链表对象
LinkedList<String> mylist=new LinkedList<String>();
//声明链表的时候要指明E的具体类型
链表mylist使用add方法添加结点
mylist.add("how");
mylist.add("are");
结点自动连接,不需要操作安排结点中所存放的下一个或上一个结点的引用
2.2 常用的方法
LinkedList 实现泛型接口List的泛型类,而泛型接口List又是Collection泛型接口的子接口
接口回调:LinkedList 对象的引用赋值给Collection对象的引用赋值给Collection接口变量或List接口变量,接口就可以调用类实现的接口方法
LinkedList 的绝大部分方法都是泛型接口方法的是实现
常用的方法:
public boolean add 链表末尾添加一个结点
public void add(int index,E element) 链表的指定位置添加一个新的结点
public void clear() 删除链表的所有结点
public E remove(int index)删除指定位置上的结点
public boolean remove(E element) 删除首次出现含有的element的结点
public E get(int index) 得到链表中指定位置上的结点
public int indexOf(E element) 返回element结点首次出现的位置,无此结点则返回-1
public int lastIndexOf(E element) 返回element结点最后出现的位置,无此结点返回-1
public E set(int index,E element) 链表中index位置的数据替换为element ,并返回被替换的数据
public int size() 链表长度(结点个数)
public boolean contains(Object element) 判断链表中是否有结点含有数据element
LinkedList 泛型类本省新增加的常用方法
public void addFirst(E element) 链表的头添加新结点,结点的数据是element指定的数据
public void addLast(E element)链表的末尾添加新结点,结点的数据是element指定的数据
public E getFirst() 得到链表的第一个结点中的数据
public E getLast()得到链表的最后一个结点中的数据
public E removeFirst() 删除第一个结点,并返回该结点中的数据
public E removeLast() 删除最后一个结点,并返回该结点中的数据
public Object clone()得到当前列表的一个克隆列表克隆链表中的结点数据的改变不会影响到原来的链表,反之亦然
2.3 遍历链表
java集合框架为各种数据结构的集合人,如链表,散列表等都提供了迭代器
LinkedList不是顺序存储结构,so 链表调用get(int index) 方法的速度比顺序存储结构的集合调用get(int index)方法的速度慢
I think:顺序存储结构遍历查找速度快,链表适合增删等
链表对象可使用iterator()方法获取一个iterator对象,该对象就是针对当前链表的迭代器
package second;
public class Example15_2 {
public static void main(String[] args) {
LinkedList<String> linkedList = new LinkedList<>();
//添加数据
for(int i=0;i<60096;i++){
linkedList.add(i+"");
}
//遍历
Iterator<String> iterator = linkedList.iterator();
long starttime=System.currentTimeMillis();
while (iterator.hasNext()){
String te=iterator.next();
}
long endtime=System.currentTimeMillis();
long result=endtime-starttime;
System.out.println("使用迭代器遍历花费的时间"+result);
starttime=System.currentTimeMillis();
for (int i=0;i<linkedList.size();i++){
String te=linkedList.get(i);
}
endtime=System.currentTimeMillis();
result=endtime-starttime;
System.out.println("使用get方法遍历集合所画的时间"+result+"毫秒");
}
}
2.4 排序与查找
Collections类提供排序与查找的方法
public static sort(List list) 将list中的元素排序
int binarySearch(List list,T key,CompareTo c)使用折半查找list是否含有和参数key相等的元素,如果key与链表中某个元素相等,方法返回和key相等的元素在链表中索引位置(链表的索引位置从0开始)否则返回-1
String 类实现Comparable接口,规定字符串按字典序排序,如果链表中的对象不是字符串,那么创建对象的类必须实现Comparable接口,在int compareTo(Object b)来规定对象的大小关系
案列
Student.java
package second;
public class Student implements Comparable {
int height=0;
String name;
Student(String n,int h){
name=n;
height=h;
}
@Override
public int compareTo(Object o) {
Student st= (Student)o;
return (this.height-st.height);
}
}
测试的main
package second;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
public class Example15_4 {
public static void main(String[] args) {
LinkedList<Student> students = new LinkedList<>();
students.add(new Student("颤三", 188));
students.add(new Student("李三", 178));
students.add(new Student("周三", 198));
Iterator<Student> iterator = students.iterator();
System.out.println("排序前链表中的数据");
while (iterator.hasNext()) {
Student s = iterator.next();
System.out.println(s.name + ":" + s.height);
}
//进行排序
Collections.sort(students);
System.out.println("排序后的数");
iterator = students.iterator();
while (iterator.hasNext()) {
Student s = iterator.next();
System.out.println(s.name + ":" + s.height);
}
Student jack = new Student("jack0", 178);
int index = Collections.binarySearch(students, jack, null);
System.out.println(index+"index");
if (index > 0) {
System.out.println(jack.name + "和链表中" + students.get(index).name + "身高一样");
}
}
}
2.5 洗牌与翻转
Collections类还提供将链表中的数据重新随机排序的类方法以及旋转链表中数据的类方法
public static void shuffle(List list) 将list中的数据重新随机排列
public void rotate(List list,int distance) 旋转链表中的数据
distance>0 向右转动
distance<0 向做转动
public static void reverse(List list) 翻转数据