System.out.println(((Point)list.get(i)));
}
System.out.println(list);
}
}
classPoint{
intx;
inty;
publicPoint(intx,inty){
this.x=x;
this.y=y;
}
publicStringtoString(){
returnthis.x+","+this.y;
}
}
总结:
集合中存放的依然是对象的引用而不是对象本身。
ArrayList的底层实现是什么原理?
ArrayListList底层采用数组实现,当使用不带参数的构造方法生成ArrayList对象时,实际上会在底层生成一个长度为10的Object类型数组。
如果增加的元素个数超过了10个,那么ArrayList底层会新生成一个数组,长度为原数组的1.5倍+1,然后将原数组的内容复制到新数组当中,并且后续增加的内容都会放到新数组当中。
当新数组无法容纳增加的元素时,复该过程。
对于ArrayList元素的删除操作,需要将被删除元素的后续元素向前移动,代价比较高。
基本上说ArrayList是一个数组。
注意:
在jdk1.5之前,没有包装类自动装箱拆箱,集合类当中只能放置对象的引用,无法放置原生数据类型,我们需要使用原生数据类型的包装类才能加入到集合当中。
还有在集合当中放置的都是Object类型,因此取出来的也是Object类型,那么必须要使用强制类型转换将其转换为真正的类型(放置进去的类型)。
LinkedList
LinkedList的很多方法使用和ArrayList的方法一样,因为实现了接口List。
还有一些其他常用的方法。
1)添加的几种常用方法:
i.publicbooleanadd(Ee):
将指定元素添加到此列表的结尾。
此方法等效于addLast(E)。
ii.publicvoidadd(intindex,Eelement):
在此列表中指定的位置插入指定的元素。
移动当前在该位置处的元素(如果有),所有后续元素都向右移(在其索引中添加.
iii.publicvoidaddLast(Ee):
将指定元素添加到此列表的结尾,此方法等效于add(E)。
iv.publicvoidaddFirst(Ee):
将指定元素插入此列表的开头
2)移除的几种常用方法:
i.publicEremove(intindex):
移除此列表中指定位置处的元素。
将任何后续元素向左移(从索引中减1)。
返回从列表中删除的元素。
ii.publicbooleanremove(Objecto)从此列表中移除首次出现的指定元素(如果存在)。
如果列表不包含该元素,则不作更改。
更确切地讲,移除具有满足(o==null?
get(i)==null:
o.equals(get(i)))的最低索引i的元素(如果存在这样的元素)。
如果此列表已包含指定元素(或者此列表由于调用而发生更改),则返回true。
3)替换方法:
publicEset(intindex,Eelement):
将此列表中指定位置的元素替换为指定的元素.
4)查找:
publicEget(intindex):
返回此列表中指定位置处的元素。
我们对于上面的几个方法,用代码来看看如何使用:
importjava.util.LinkedList;
publicclassLinkedListTest{
publicstaticvoidmain(String[]args){
LinkedListlist=newLinkedList();
/**
*添加的几种方法
*/
list.add("hello");
list.add("world");
list.add("welcome");
list.addFirst("hello0");
list.addLast("welcome1");
list.add(1,"haha");
System.out.println("最初的集合"+list);
/**
*移除的几种方法
*/
list.remove
(1);
list.remove("welcome");
System.out.println("变化后的集合"+list);
/**
*替换set()
*获取get()
*/
Stringvalue=(String)list.get
(2);
list.set(3,value+"changed");
System.out.println("最后的集合"+list);
}
}
其实LinkedList的底层是一种链表形式,链表形式有单向链表和双向链表,我们看看单向链表的实现方式,我们看看如下代码:
publicclassNode{
Stringdata;
Nodenext;
publicNode(Stringdata){
this.data=data;
}
}
publicclassNodeTest{
publicstaticvoidmain(String[]args){
Nodenode1=newNode("node1");
Nodenode2=newNode("node2");
Nodenode3=newNode("node3");
node1.next=node2;
node2.next=node3;
System.out.println("单向链表:
"+node1.data+","+node1.next.data+","
+node1.next.next.data);
System.out.println("------插入--------");
Nodenode4=newNode("node4");
node1.next=node4;
node4.next=node2;
System.out.println("插入后结果:
"+node1.data+","+node1.next.data+","
+node1.next.next.data+","+node1.next.next.next.data);
System.out.println("----------删除------------");
node1.next=node2;
node4.next=null;
System.out.println("删除后结果:
"+node1.data+","+node1.next.data+","
+node1.next.next.data+",");
}
}
现在我们再看看双向链表的实现方式:
publicclassDoubleNode{
DoubleNodeprevious;//前一个对象
Stringdata;//当前数据
DoubleNodenext;//后一个对象
publicDoubleNode(Stringdata){
this.data=data;
}
}
publicclassDoubleNodeTest{
publicstaticvoidmain(String[]args){
DoubleNodenode1=newDoubleNode("node1");
DoubleNodenode2=newDoubleNode("node2");
DoubleNodenode3=newDoubleNode("node3");
node1.previous=node3;
node1.next=node2;
node2.previous=node1;
node2.next=node3;
node3.previous=node2;
node3.next=node1;
System.out.println(node1.data+","+node1.previous.data+","+node1.previous.previous.data+","+node1.previous.previous.previous.data);
System.out.println(node1.data+","+node1.next.data+","+node1.next.next.data+","+node1.next.next.next.data);
System.out.println("-----------插入---------");
DoubleNodenode4=newDoubleNode("node4");
node1.next=node4;
node4.previous=node1;
node4.next=node2;
node2.previous=node4;
System.out.println(node1.data+","+node1.previous.data+","+node1.previous.previous.data+","+node1.previous.previous.previous.data+node1.previous.previous.previous.previous.data);
System.out.println(node1.data+","+node1.next.data+","+node1.next.next.data+","+node1.next.next.next.data+","+node1.next.next.next.next.data);
System.out.println("--------------删除--------------");
node1.next=node2;
node2.previous=node1;
node4.next=null;
node4.previous=null;
System.out.println(node1.data+","+node1.previous.data+","+node1.previous.previous.data+","+node1.previous.previous.previous.data);
System.out.println(node1.data+","+node1.next.data+","+node1.next.next.data+","+node1.next.next.next.data);
}
}
ArrayList与LinkedList的区别
从以上代码可以看出,ArrayList与LinkedList的底层实现是不一样的,我们现在对ArrayList与LinkedList进行比较分析:
a)ArrayList底层采用数组实现,LinkedList底层采用双向链表实现。
b)当执行插入或者删除操作时,采用LinkedList比较好
c)当执行搜索操作时,采用ArrayList比较好
d)当向ArrayList添加一个对象是,实际上就是将该对象放置到了ArrayList底层所维护的数组当中;当向LinkedList中添加一个对象时,实际上LinkedList内部会生成一个Entry对象,该Entry对象的结构为:
Entry{
Entryprevious;
Objectelements;
Entrynext;
}
其中的Object类型的元素elements就是我们向LinkedList中所添加的元素,然后Entry又造好了向前与向后的引用previous,next,最后将生成的这个Entry对象加入到了链表当中。
换句话说,LinkedList中所维护的是一个个的Entry对象。
栈(Stack)和队列(Queue)
无论是栈还是队列,里面都会维护一个成员变量,该成员变量用于存储栈或队列中的元素,该成员变量请使用LinkedList类型。
栈和队列实现代码:
LinkedList提供以下方法:
addFirst();
removeFirst();
addLast();
removeLast();
栈实现代码
在栈中,push为入栈操作,pop为出栈操作。
Push用addFirst(),pop用removeFirst(),实现后进先出。
用isEmpty()--其父类的方法,来判断栈是否为空。
在队列中,put为入队列操作,get为出队列操作。
Put用addFirst(),get用removeLast()实现队列。
用isEmpty()--其父类的方法,来判断队列是否为空?
Package.dataStruct;
importjava.util.LinkedList;
publicclassMyStack{
LinkedListlinkList=newLinkedList
publicvoidpush(Objectobject){
linkList.addFirst(object);
}
publicbooleanisEmpty(){
returnlinkList.isEmpty();
}
publicvoidclear(){
linkList.clear();
}
publicObjectpop(){
if(!
linkList.isEmpty())
returnlinkList.removeFirst();
else
return"栈内无元素";
}
publicintgetSize(){
returnlinkList.size();
}
publicstaticvoidmain(String[]args){
MyStackmyStack=newMyStack();
myStack.push(“a”);
myStack.push(“b”);
myStack.push(“c”);
System.out.println(myStack.pop());
System.out.println(myStack.pop());
}
}
队列实现代码:
packagedataStruct;
importjava.util.LinkedList;
publicclassMyQueue{
LinkedListlinkedList=newLinkedList();
publicvoidput(Objecto){
linkedList.addLast(o);
}
publicObjectget(){
if(!
linkedList.isEmpty())
returnlinkedList.removeFirst();
else
return"";
}
publicbooleanisEmpty(){
returnlinkedList.isEmpty();
}
publicintsize(){
returnlinkedList.size();
}
publicvoidclear(){
linkedList.clear();
}
publicstaticvoidmain(String[]args){
MyQueuemyQueue=newMyQueue();
myQueue.put(“a”);
myQueue.put(“b”);
myQueue.put(“c”);
System.out.println(myQueue.get());
}
}