一,命名规范定义
1,java.util.collection接口来定义数据结构中方法的命名规范。
2,java.util.List此接口是collection的子接口,要求实现此接口的类,必须满足数据是有序且可以重复的特性。
3,java.util.Set此接口是collection的子接口,要求实现此接口的类,必须满足数据是无序且不可重复的特性。
二,数据结构的实现类
List
1,java.util.ArrayList以可变数组长度的方式实现java.util.List接口。
例:
package myutil;
/*总结: ArrayList适合查找元素,而不适合 删除、插入元素*/
public class ArrayList {
Object[] elementData;
int size;
public ArrayList(){
this(10);
}
public ArrayList(int initialCapacity){
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
}
public boolean add(Object obj){
this.ensureCapacity(this.size+1);
this.elementData[size++] = obj;
return true;
}
/* 由于在数组中删除元素需要调整数组的下标,例如在100个元素中删除第一个元素需要调下标99次,
因此在ArrayList中删除元素的效率很低(特别是删除在数组中靠前的元素)*/
public Object remove(int index){
Object oldEle=this.elementData[index];
for(int i=index;i<size;i++){
this.elementData[i]=this.elementData[i+1];
}
size--;
return oldEle;
}
/* 由于可变长度实际上是新数组和原数组之间一个copy,因此效率很低,在创建ArrayList的时候应该尽量使用
第二种构造函数。*/
private void ensureCapacity(int capacity){
if(capacity>this.elementData.length){
Object[] newElementData = new Object[this.elementData.length*3/2];//扩展到1.5倍。
this.copy(newElementData);
}
}
private void copy(Object[] newElementData){
for(int i=0;i<size;i++){
newElementData[i]=this.elementData[i];
}
this.elementData=newElementData;
}
public Object get(int index){
return this.elementData[index];
}
public int size(){
return this.size;
}
}
2,java.uti.LinkedList以链表的方式实现java.util.List接口。
例:
package myutil;
import java.util.Collection;
import java.util.Iterator;
/*总结:由于LikedList由链表实现(对象的引用),因此在删除链表头或尾部元素的时候效率非常高,这刚好与ArrayList相反
LinkedList的遍历应该按照java.util.Iterator(迭代器规)规范实现遍历,这种方式是从链表表的头部往next或previous顺序返回数据,
效率与ArrayList相同,因此如果要遍历LinkedList应该使用迭代器而不是get方法。
*
* */
public class LinkedList implements Iterable {
Node header = new Node(null);
int size;
public LinkedList(){
this.header.previous = header.next = header;
}
public Iterator iterator(){
class IteratorImp implements Iterator{
Node ele=header;
@Override
public boolean hasNext() {
return ele.next!=header;
}
@Override
public Object next() {
Node n=ele.next;
ele=n;
return n.ele ;
}
@Override
public void remove() {
}
}
return new IteratorImp();
}
public boolean add(Object ele){
Node newNode = new Node(ele);
newNode.previous = header.previous;
newNode.next = header;
header.previous.next = newNode;
header.previous = newNode;
size++;
return true;
}
private Node node =header;
public boolean add2(Object ele){
Node newNode = new Node(ele);
header.previous = newNode;
node.next = newNode;
newNode.previous = node;
newNode.next = header;
node = newNode;
size++;
return true;
}
public void removeFirst(){
Node removeEle=header.next;
removeEle.next.previous = header;
header.next = removeEle.next;
removeEle = removeEle.previous = removeEle.next = null;
size--;
}
public void removeLast(){
}
//查找元素时效率低,需要对链表进行遍历。ArrayList效率高因为数组可以快速定位到指定下标的元素。
public Object get(int index){
if(index < size>>1){
Node node=header;
for(int i=0;i<=index;i++){
node=node.next;
}
return node.ele;
}else{
Node node=header;
for(int i=size;i>index;i--) {
node = node.previous;
}
return node.ele;
}
}
public int size(){
return this.size;
}
class Node{
Node next;
Node previous;
Object ele;
Node(Object ele){
this.ele =ele;
}
}
}
Set
1,java.util.HashSet HashSet由HashMap实现,把所有元素都储存在HashMap的key中。(此实现依照HashMap方法实现)
Map
(map是key-value的数据储存关系,与集合接口没有任何关联)
1,常用实现类java.util.HashMap
例:
package myutil;
import java.util.Iterator;
@SuppressWarnings("all")
public class HashMap{
static final int DEFAULT_INITIAL_CAPACITY = 16;
static final float DEFAULT_LOAD_FACTOR = 0.75f;
Node[] elementsData;
public int threshold;
int size;
public HashMap(int initialCapacity, float loadFactor) {
this.threshold= (int)(initialCapacity*loadFactor);
}
public HashMap(){
this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR);
this.elementsData = new Node[8];
init();
}
public Object get(Object key){
int index= indexFor(key.hashCode());
Node ele=this.elementsData[index];
for(; ele!=null;ele=ele.next){
if(ele.key==key)
return ele.value;
}
return null;
}
public Object put(Object key, Object value){
if(size+1>threshold){
//reHash 扩展Hash表的长度。
}
return addNode(key,value);
}
public void init(){
}
public Node addNode(Object key, Object value){
Node ele=new Node(key,value);
int index= indexFor(key.hashCode());
ele.next = this.elementsData[index];
this.elementsData[index]=ele;
size++;
return ele;
}
public int indexFor(int h) {
int index=h & (this.elementsData.length-1);
if(index<0)
index=index*-1;
return index;
}
public static class Node{
Object key;
Object value;
Node next;
public Node(Object key,Object value){
this.key = key;
this.value = value;
}
public Node(){
}
}
}
2,java.util.LinkedHashMap如果需要使用HashMap的功能又需要对储存的数据进行排序则使用LinkedHashMap。
例:
package myutil;
import java.util.Iterator;
public class LinkedHashMap extends HashMap implements Iterable {
Node header;
@Override
public void init(){
header=new Node(null,null);
header.previous = header.next = header;
}
@Override
public Iterator iterator() {
class IteratorImp implements Iterator{
Node ele=header;
@Override
public boolean hasNext() {
return ele.next!=header;
}
@Override
public Object next() {
Node n=ele.next;
ele=n;
return n.value ;
}
@Override
public void remove() {
}
}
return new IteratorImp();
}
class Node extends HashMap.Node{
Node previous;
Node next;
public Node(Object key,Object value){
super(key,value);
}
public boolean addBefore(){
this.previous = header.previous;
this.next = header;
header.previous.next = this;
header.previous = this;
return true;
}
}
/* 重写addNode方法。由于HashMap在调用put方法时会调用addNode方法。因此重写此方法后
LinkedHashMap在调用put方法时会执行重写的addNode,从而将存储元素存储到Hash表的同时,
在添加到双向链表的结构中去。*/
@Override
public Node addNode(Object key, Object value){
super.addNode(key,value);
Node e = new Node( key, value);
e.addBefore();
return e;
}
}