泛型 Generic Class
泛型是指通用的类型。它是设计上的术语。
原始的通用链表
GenericList类
GenericList:该类封装了链表结构,可以使用任何类型作为节点类型。
示例:
GenericList list = new GenericList();
list.add(new Student(1, "Shao", "13810012323"));
list.add(new Student(2, "Wang", "13323232145"));
list.add(new Student(3, "Zhou", "13045461789"));
设计思路
1 不限制节点类型,所以使用Object作为节点的引用。
class GenericNode
{
Object value;
GenericNode next;
}
2 迭代器
使用Iterator进行链表的遍历。
GenericList实现
package my;
public class GenericList
{
// 通用节点类型
private static class GenericNode
{
Object value;
GenericNode next;
}
// 固定头节点
private GenericNode head = new GenericNode();
public GenericList(){}
// 添加一个对象
public void add ( Object value )
{
// 找到末节点
GenericNode tail = head;
while( tail.next != null)
tail = tail.next;
// 附加到末尾
GenericNode node = new GenericNode ();
node.value = value;
tail.next = node;
}
// 长度
public int length()
{
int count = 0;
GenericNode m = head.next;
while( m != null)
{
count += 1;
m = m.next;
}
return count;
}
// 获取迭代器
public Iterator getIterator()
{
Iterator iter = new Iterator();
iter.node = this.head;
return iter;
}
//迭代器
public static class Iterator
{
private GenericNode node;
// 是否还有下一节点
public boolean hasNext()
{
return node.next != null;
}
// 获取下一节点的值
public Object next()
{
Object value = node.next.value;
node = node.next;
return value;
}
}
}
泛型的规范使用
泛型的定义
泛型一般用于描述一种通用的算法、数据结构,对象类型其实并不关心。所以,用一个代号T来代表目标类型。(Template)
在java语言里,泛型的规范写法:
public class Sample <T>
{
}
在类的定义里,T代表一个通用的类型,称为类型参数。
泛型的使用
正规写法下,使用泛型应指定类型参数。
GenericList<Student> list = new GenericList<Student>();
list.add( new Student(1, "shao", "13810012345"));
list.add( new Student(2, "wang", "15290908889"));
list.add( new Student(3, "li", "13499230340"));
GenericList.Iterator<Student> iter = list.getIterator();
while(iter.hasNext())
{
Student s = iter.next();
System.out.println(s);
}
GenericList 的规范写法
package my;
public class GenericList <T>
{
// 通用节点类型
private static class GenericNode<T>
{
T value;
GenericNode<T> next;
}
// 固定头节点
private GenericNode<T> head = new GenericNode<T>();
public GenericList(){}
// 添加一个对象
public void add ( T value )
{
// 找到末节点
GenericNode<T> tail = head;
while( tail.next != null)
tail = tail.next;
// 附加到末尾
GenericNode<T> node = new GenericNode<T> ();
node.value = value;
tail.next = node;
}
// 长度
public int length()
{
int count = 0;
GenericNode<T> m = head.next;
while( m != null)
{
count += 1;
m = m.next;
}
return count;
}
// 获取迭代器
public Iterator<T> getIterator()
{
Iterator<T> iter = new Iterator<T>();
iter.node = this.head;
return iter;
}
// 迭代器
public static class Iterator<T>
{
private GenericNode<T> node;
// 是否还有下一节点
public boolean hasNext()
{
return node.next != null;
}
// 获取下一节点的值
public T next()
{
T value = node.next.value;
node = node.next;
return value;
}
}
}
再谈ArrayList
常用泛型
List, ArrayList
Map, HashMap
注:通常我们自己是不用写泛型的,因为JDK自带的这两个泛型已经够用了。
ArrayList
数组链表,既可以用数组的形式进行操作,又可以使用链表的形式进行操作。
示例:
ArrayList<Student>
ArrayList<Teacher>
ArrayList<Integer>
注:不能直接使用ArrayList,必须要用包装类。(因为int等八大基本类型不是Object的子类)
使用
添加,插入
遍历(分数组、链表两种方式)
删除(分数组、链表两种方式)
排序
一般来说使用链表的方式进行操作执行效率更高。
使用数组的方式进行操作编码效率更高。
通常情况下,我们追求的是更简单,而不是更高效。
常用方法详见:ArrayList的常用方法
HashMap
Map:映射表,抽象类
HashMap:哈希映射表,是Map的一个实现
HashMap的存储
Key:Value
1、键值对
2、每一个value都有一个唯一的Key
3、通过key可以迅速找到value
HashMap的创建
创建HashMap的时候,需要指定Key和Value的类型
示例:(学号:学生)
HashMap<Integer, Student> map = new HashMap<Integer, Student>()
HashMap常见操作
添加
map.put(1, new Stdudent(1, "Shao", "13089465738"));
查找
map.get(id);
判空
map.isEmpty();
删除
map.remove(id);
遍历(三种方式)
//第一种
for(Integer key : map.keySet())
{
System.out.println("Key:"+key+" Value:"+map.get(key));
}
//第二种
Iterator map1it = map.entrySet().iterator();
while(map1it.hasNext())
{
Map.Entry<Integer, String> entry = (Entry<Integer, String>) map1it.next();
System.out.println("Key:" + entry.getKey() + " Value:" + entry.getValue());
}
//第三种(效率最高)
for(Map.Entry<Integer, String> entry: map.entrySet())
{
System.out.println("Key:" + entry.getKey() + " Value:" + entry.getValue());
}