1、eclipse:自动添加get set 方法,构造器等【alt+shift+s (或者 右击鼠标 source)】
设置断点并调试,右击鼠标选择debug as,进入调试
*2、linked-list:
- add(尾插)
toString
遍历
越界检查(负数,超出)
get set(小于一半,从头节点查找;大于一半,从尾节点开始查找)
remove
insert
泛型
不加泛型的版本:
//节点类
class Node{
Node prev;
Node next;
Object element;
//构造函数(自动生成的)
public Node(Object element) {
super(); //父类有无参构造函数时,可以省略
this.element = element; //参数命名冲突时,使用this区分
}
}
public class Linked {
private int SIZE;
private Node first;
private Node last;
//构造函数
Linked(){
first=null;
last=null;
SIZE=0;
}
//尾插法
public void add(Object obj) {
Node nod=new Node(obj);
if(first==null) {
nod.prev=null;
nod.next=null;
first=nod;
last=nod;
}else {
nod.prev=last;
last.next=nod;
nod.next=null;
last=nod;
}
SIZE++; //别忘记增加SIZE
}
//重写toString方法,按照自己的要求打印
@Override
public String toString() {
// TODO Auto-generated method stub
StringBuilder out=new StringBuilder();
Node nod=first;
out.append('[');
for(int i=0;i<SIZE;i++) {
out.append(nod.element);
out.append(',');
nod=nod.next;
}
out.setCharAt(out.length()-1, ']'); //之前写的SIZE-1,错了,没有考虑到添加了逗号进StringBuilder
return out.toString();
}
//遍历
public void traversal() {
Node nod=first;
for(int i=0;i<SIZE;i++) {
System.out.println(nod.element);
nod=nod.next;
}
}
//封装得到合法节点的方法
public Node getNode(int index) {
Node nod=null;
if(first==null)
throw new NullPointerException(); //通过ALT+/ 快捷键生成
int mid=SIZE>>2;
if(index<mid && index>=0) {
nod=first;
int i=0;
while(i!=index) {
nod=nod.next;
i++;
}
}else if(index>=mid && index<SIZE) {
nod=last;
int i=SIZE-1;
while(i!=index) {
nod=nod.prev;
i--;
}
}else {
throw new ArrayIndexOutOfBoundsException();
}
return nod;
}
//get (小于一半,从头节点查找;大于一半,从尾节点开始查找,提高效率)
public Object get(int index) {
Node nod=getNode(index);
return nod.element;
}
//set
public void set(int index,Object obj) {
Node nod;
nod=getNode(index);
nod.element=obj; //改变值
}
//删除
public void del(int index) {
Node nod=getNode(index); //只能得到合法的索引了
if(index==0) {
first=nod.next;
nod.next.prev=null;
nod=null;
SIZE--;
}
else if(index==SIZE-1) {
nod.prev.next=null;
last=nod.prev;
nod=null;
SIZE--;
}else {
nod.prev.next=nod.next;
nod.next.prev=nod.prev;
nod=null;
SIZE--;
}
}
//插入
public void insert(int index,Object obj) {
Node newone=new Node(obj);
Node nod=getNode(index);
if(index==0) {
first=newone;
newone.next=nod;
newone.prev=null;
nod.prev=newone;
SIZE++;
}else if(index==SIZE-1) {
last=newone;
nod.next=newone;
newone.prev=nod;
newone.next=null;
SIZE++;
}else{
newone.next=nod;
newone.prev=nod.prev;
nod.prev.next=newone;
nod.prev=newone;
SIZE++;
}
}
public static void main(String[] args) {
Linked link=new Linked();
//Linked link1=new Linked(); //创建一个空对象,用来后面测试
link.add(1);
link.add(10);
link.add(20);
link.add("p");
link.add("h");
link.add("t");
System.out.println(link); //[1,10,20,p,h,t]
//link.traversal(); //挨个打印出元素
System.out.println(link.get(2)); //20
//System.out.println(link.get(-1)); //Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
//System.out.println(link.get(6)); //Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
//System.out.println(link1.get(0)); //Exception in thread "main" java.lang.NullPointerException
link.set(0, 100);
System.out.println(link); //[100,10,20,p,h,t]
link.del(2);
System.out.println(link); //[100,10,p,h,t]
link.del(0);
System.out.println(link); //[10,p,h,t]
link.insert(0, 'x');
link.insert(2, 1);
System.out.println(link); //[x,10,1,p,h,t]
}
}
3、Hashmap
jdk1.6中使用的是Entry
jdk1.8中使用的是Node
class Entry{
int hashValue;
Object key;
Object value;
Entry next; //JDK1.6源码中为Entry,JDK1.8中为Node。是一样的
public Entry(Object key,Object value){ //构造函数
hashValue=key.hashCode();
this.key=key; //重名使用this
this.value=value;
next=null;
}
}
public class Hash {
static Entry[] bucket;
int size;
//数组长度直接从成员变量里取出来:bucket.length
//构造函数
Hash(){
size=16;
bucket=new Entry[size]; //hashmap初始size默认16
//size为2的整数倍,方便位运算
}
//哈希函数,通过输入Key的哈希值,输入哈希function,得到一个装桶数组的索引
public int hash(int hashcode,int length) {
return hashcode&(length-1); //与运算,效率高于取模运算
//等价于hashcode%length
}
//add,添加元素
public void add(Object key,Object value) {
int index=hash(key.hashCode(),bucket.length);
Entry newnode=new Entry(key,value);
Entry target=bucket[index]; //栈中的target指向了bucket[index]
Entry re=null;
if(bucket[index]==null) {
bucket[index]=newnode;
}else {
while(target!=null) {
re=target; //re与target都指向了目标对象,对他们进行操作都等价与对目标进行操作
target=target.next;
}
re.next=newnode;
}
}
//get键值对
public Object get(Object key) {
int hashcode=key.hashCode();
int bucketnum=hash(hashcode,bucket.length);
Entry target=bucket[bucketnum];
Entry re=null; //用于判断最后是否找到该key的键值对
if(target==null) {
throw new NullPointerException();
}else if(target.key!=key) {
while(target!=null) {
if(target.key==key) {
re=target;
}
target=target.next;
}
return re.value; //如果链表中没找到,则返回值为null
}else {
return target.value;
}
}
//重写toString
@Override
public String toString() {
StringBuilder st=new StringBuilder();
st.append('[');
for(int i=0;i<bucket.length;i++) {
Entry now=bucket[i];
while(now!=null) {
st.append(now.key+":"+now.value+","); //必须使用双引号
now=now.next;
}
}
st.setCharAt(st.length()-1, ']');
return st.toString();
}
public static void main(String[] args) {
Hash h=new Hash(); //已经自动调用了无参构造函数
h.add(1,'a');
h.add(2,'b');
h.add(3,'c');
System.out.println(h);
//Object x=h.get(4); //无法找到键值 Exception in thread "main" java.lang.NullPointerException
Object y=h.get(2);
System.out.println(y); //b
}
}