❶ java中LinkedList問題
那個沒有錯誤,只是返猜正一個警告,可以漏悔不用理睬的
也可以
@SuppressWarnings("unchecked") //添加兆早這個就可以了
public void push(Object o) {
l.addFirst(o);
}
或者
private LinkedList<Object> l = new LinkedList<Object>(); 都可以
❷ java中LinkedList的問題
//單鏈表類
package dataStructure.linearList;
import dataStructure.linearList.Node; //導入單鏈表結點類
import java.util.Iterator; //導入迭代器介面
public class SinglyLinkedList<E> extends AbstractList<E> implements LList<E> //單鏈表類,實橘早廳現線性表介面
{
protected Node<E> head; //頭圓隱指針,指向單鏈表第1個結點
public SinglyLinkedList() //構造空單鏈表
{
this.head = null;
}
public SinglyLinkedList(Node<E> head) //構造指定頭指針的單鏈表
{
this.head = head;
}
public boolean isEmpty() //判斷單鏈表是否為空睜碧,O(1)
{
return this.head==null;
}
public int length() //返回單鏈表長度
{ //單鏈表遍歷演算法,O(n)
int i=0;
Node<E> p=this.head;
while (p!=null)
{
i++;
p = p.next;
}
return i;
}
public E get(int index) //返回序號為index的對象,index初值為0
{ //若單鏈表空或序號錯誤返回null,O(n)
if (this.head!=null && index>=0)
{
int j=0;
Node<E> p=this.head;
while (p!=null && j<index)
{
j++;
p = p.next;
}
if (p!=null)
return (E)p.data;
}
return null;
}
public E set(int index, E element) //設置序號為index的對象為element,O(n)
{ //若操作成功返回原對象,否則返回null
if (this.head!=null && index>=0 && element!=null)
{
int j=0;
Node<E> p=this.head;
while (p!=null && j<index)
{
j++;
p = p.next;
}
if (p!=null)
{
E old = (E)p.data;
p.data = element;
return old; //若操作成功返回原對象
}
}
return null; //操作不成功
}
public boolean add(int index, E element) //插入element對象,插入後對象序號為index
{ //若操作成功返回true,O(n)
if (element==null)
return false; //不能添加空對象(null)
if (this.head==null || index<=0) //頭插入
this.head = new Node<E>(element, this.head);
else //單鏈表不空且index>=1
{
int j=0;
Node<E> p=this.head;
while (p.next!=null && j<index-1) //尋找插入位置
{
j++;
p = p.next;
}
p.next = new Node<E>(element, p.next);//中間/尾插入
}
return true;
}
public boolean add(E element) //在單鏈表最後添加對象,重載,O(n)
{
return add(Integer.MAX_VALUE, element);
}
public E remove(int index) //移去序號為index的對象,O(n)
{ //若操作成功返回被移去對象,否則返回null
E old = null;
if (this.head!=null && index>=0)
if (index==0) //頭刪除
{
old = (E)this.head.data;
this.head = this.head.next;
}
else //中間/尾刪除
{
int j=0;
Node<E> p=this.head;
while (p.next!=null && j<index-1) //定位到待刪除結點的前驅結點
{
j++;
p = p.next;
}
if (p.next!=null)
{
old = (E)p.next.data; //操作成功,返回原對象
p.next = p.next.next; //刪除p的後繼結點
}
}
return old;
}
public void clear() //清空單鏈表,O(1)
{
this.head = null;
}
public String toString() //返回顯示單鏈表所有元素值對應的字元串
{ //單鏈表遍歷演算法,O(n)
String str="(";
Node<E> p = this.head;
while (p!=null)
{
str += p.data.toString();
p = p.next;
if (p!=null)
str += ", ";
}
return str+")";
}
//以上實現LList介面,第2章
//以下2.4 迭代器內容
public Iterator<E> iterator() //返回一個迭代器對象
{
return new Itr();
}
private class Itr implements Iterator<E> //私有內部類,實現迭代器介面
{
private Node<E> cursor = head;
public boolean hasNext() //若有後繼元素,返回true
{
return cursor!=null && cursor.next!=null;
}
public E next() //返回後繼元素
{
if (cursor != null && cursor.next!=null)
{
E element = cursor.next.data;
cursor = cursor.next;
return element;
}
return null;
}
public void remove() //不支持該操作
{
throw new UnsupportedOperationException();
}
}//內部類Itr結束
//以下第8章 8.2.1 順序查找,散列表中用
public Node<E> search(E element, Node<E> start) //從單鏈表結點start開始順序查找指定對象
{ //若查找成功返回結點,否則返回null
if (this.head==null || element==null)
return null;
Node<E> p=start;
while (p!=null && !element.equals(p.data))
{
System.out.print(p.data+"? ");
p = p.next;
}
return p;
}
public Node<E> search(E element) //順序查找指定對象
{
return search(element, head);
}
/*
public boolean contain(E element) //以查找結果判斷單鏈表是否包含指定對象
{ //若包含返回true,否則返回false
return this.search(element)!=null;
}
*/
public boolean remove(E element) //移去首次出現的指定對象,O(n)
{ //若操作成功返回true
if (this.head==null || element==null)
return false;
if (element.equals(this.head.data))
{
this.head = this.head.next; //頭刪除
return true;
}
Node<E> front=this.head, p=front.next; //中間/尾刪除
while (p!=null && !element.equals(p.data))
{
front = p;
p=p.next;
}
if (p!=null)
{
front.next = p.next;
return true;
}
return false;
}
//以下是第2章習題
public SinglyLinkedList(E[] element) //由指定數組中的多個對象構造單鏈表
{
this.head = null;
if (element!=null && element.length>0)
{
this.head = new Node(element[0]);
Node<E> rear=this.head;
int i=1;
while (i<element.length)
{
rear.next = new Node(element[i++]);
rear = rear.next;
}
}
}
public void concat(SinglyLinkedList list) //將指定單鏈表list鏈接在當前單鏈表之後
{
if (this.head==null)
this.head = list.head;
else
{
Node<E> p=this.head;
while (p.next!=null)
p = p.next;
p.next = list.head;
}
}
public SinglyLinkedList(SinglyLinkedList<E> list) //以單鏈表list構造新的單鏈表
{ //復制單鏈表
this.head = null;
if (list!=null && list.head!=null)
{
this.head = new Node(list.head.data);
Node<E> p = list.head.next;
Node<E> rear = this.head;
while (p!=null)
{
rear.next = new Node<E>(p.data);
rear = rear.next;
p = p.next;
}
}
}
//遞歸方法
// public SinglyLinkedList(SinglyLinkedList<E> list) //以單鏈表list構造新的單鏈表
public void (SinglyLinkedList<E> list) //復制單鏈表
{
this.head = (list.head);
}
private Node<E> (Node<E> p) //復制單鏈表,遞歸方法
{
Node<E> q=null;
if (p!=null)
{
q = new Node(p.data);
q.next = (p.next);
}
return q;
}
/*//遞歸方法
public String toString()
{
return "("+ this.toString(this.head) +")";
}
public String toString(Node<E> p) //遞歸方法
{
if (p!=null)
return p.data.toString() + ", " + this.toString(p.next); //遞歸調用
return "";
}
public SinglyLinkedList(E[] element) //由指定數組中的多個對象構造單鏈表
{
this.head = null;
if (element!=null)
this.head = create(element,0);
}
private Node<E> create(E[] element, int i) //由指定數組構造單鏈表
{ //遞歸方法
Node<E> p=null;
if (i<element.length)
{
p = new Node(element[i]);
p.next = create(element, i+1);
}
return p;
}
*/
public boolean equals(Object obj) //比較兩條單鏈表是否相等
{
if (obj == this)
return true;
if (obj instanceof SinglyLinkedList)
{
SinglyLinkedList list = (SinglyLinkedList)obj;
return equals(this.head, list.head);
}
return false;
}
private boolean equals(Node<E> p, Node<E> q) //比較兩條單鏈表是否相等,遞歸方法
{
if (p==null && q==null)
return true;
if (p!=null && q!=null)
return p.data.equals(q.data) && equals(p.next, q.next);
return false;
}
//以下是第8章習題
public boolean replace(Object obj, E element)//將元素值為obj的結點值替換為element,O(n)
{ //若替換成功返回true,否則返回false
if (obj==null || element==null)
return false;
Node<E> p=this.head;
while (p!=null)
{
if (obj.equals(p.data))
{
p.data = element;
return true;
}
p = p.next;
}
return false;
}
public boolean replaceAll(Object obj, E element) //將所有元素值為obj的結點值替換為element,O(n)
{ //若替換成功返回true,否則返回false
boolean done=false;
if (obj!=null && element!=null)
{
Node<E> p=this.head;
while (p!=null)
{
if (obj.equals(p.data))
{
p.data = element;
done = true;
}
p = p.next;
}
}
return done;
}
public boolean removeAll(Object obj) //將所有元素值為obj的結點刪除
{
if (this.head==null || obj==null)
return false;
boolean done=false;
while (this.head!=null && obj.equals(this.head.data))
{
this.head = this.head.next; //頭刪除
done = true;
}
Node<E> front=this.head, p=front.next;
while(p!=null)
{
if (obj.equals(p.data))
{
front.next = p.next; //刪除p結點
p = front.next;
done = true;
}
else
{
front = p;
p = p.next;
}
}
return done;
}
public static void main(String[] args)
{
String[] letters={"A","B","C","D","E","F"};
SinglyLinkedList<String> list1 = new SinglyLinkedList<String>(letters);
SinglyLinkedList<String> list2 = new SinglyLinkedList<String>(list1);
list2.(list1);
System.out.println(list2.toString());
System.out.println("equals(), "+list2.equals(list1));
}
}
/*
程序運行結果如下:
(A, B, C, D, E, F)
*/
/* 第2章 //可行,但效率低,時間復雜度是O(n*n)。
public String toString()
{
String str="{";
if (this.length()!=0)
{
for(int i=0; i<this.length()-1; i++)
str += this.get(i).toString()+", ";
str += this.get(this.length()-1).toString();
}
return str+"}";
}
*/
❸ ArrayList和LinkedList中的transient關鍵字和序列化
在看ArrayList和LinkedList的 源碼 的時候,發現ArrayList和LinkedList的一些成員變數變數被transient修飾了,有點不解,就查了一些資料。分享給大家。
序列化是java提供的一種將內存中的對象信息轉化為二進制數組的方法,可以將數組保存和傳輸,然後使用原來的類模板恢復對象的信息。源頌賀
轉化後的二進制數組中包含以下信息:序列化版本,完整類名,serialVersionUID,各個屬性的類型、名字和值、父類信息。
實現Serializable介面,使用ObjectOutputStream.writeObject(Object Object)寫對象信息,使用ObjectInputStream.readObject()讀對象信息。
ObjectOutputStream.writeObject(ObjectA objectA)首先判斷ObjectA有沒有重寫writeObject方法,如果有,反射調用ObjectA的writeObject方法完成序列化;否則,調用默認的序列化方法序列化。反序列化也一樣
被transient修飾的成員變數不會被序列化。
哪些情況下可以不用序列化呢?我認為有以下兩種情況。
1.節省空間
比如,一個長方形類有成員變數:長、寬、面積。那麼面積就不用序列化,因為面積可以根據其他兩個計算出來,這樣節省存儲空間和傳輸空間。
2.持有對象的引用
比如,我們創建鏈表的結點如下。結點中持有前驅結點和後繼結點的引用,引用就是對象在內存中的地址值。對於這樣的結點形成的鏈表,我們序列化這個鏈表後,結點的前序和後繼引用都失效了,因為內存地址變了。這種情況下我們需要重新連接鏈表。
首先說以下結論:
1.ArrayList中將elementData修飾成transient是為了節省空間
2.LinkedList中將first和last修飾成transient是為了節省空間和重新連接鏈表。
查看 源碼 我們知道ArrayList中使用數組transient Object[] elementData保存數據,當數組空間不夠時,數組長度擴容為原來的1.5倍。那麼數組中可能有沒有使用的空間,比如elementData的長度時15,但是裡面只裝了11個元素,那麼後面的4個元素都是空值。序列化的時候可以不把這4個元素序列化。
ArrayList中定義了writeObject和readObject方法,實現了自定義序列化。前面我們說了序列化的時候ObjectStream會判斷類中有沒有自定義序列化方法?如果有,使用自定義序列化方法:否則使用默認的序列化方法。
ArrayList自定義序列化方法如下
查看 源碼 我們知道LinkedList中使用雙向鏈表櫻培保存數據,結點中保存前驅和後繼的引用。但是序列化之後前序結點和後繼結點的地址都變了,我們應該連接新的結點。
下面看以下LinkedList是怎麼自定義序列化的
我們看到了,LinkedList序列化的時候將鏈表按順序拆分開來,僅序列化結雹派點中保存的數據,反序列化的時候重新連接鏈表,保證了鏈表的有效性。
❹ java中源文件LinkedList.java
在 AbstractList 中定義的,初始值是 0。笑橋歲
api 中對此有比較具體的說明,摘給你:
---------------------------------------------------------------
protected transient int modCount
已從結構上修改 此列表的次數。從結構上修改是指更改列表的大小,或者打亂列表,從而使正在進行的迭代產生錯誤的結果。
此欄位由 iterator 和 listIterator 方法返回的迭代器和列表迭代器實現使用。如果意外更改了此欄位中的值,則迭代器(或列表迭代器)將拋出 來響應 next、remove、previous、set 或 add 操作。在迭代期間面臨並發修改時,它提供了快速失敗 行為,而不是非確定性行為。
子類是否使用此欄位是可選的。如果子類希望提供快速失敗迭代器(和列表迭代器),則它只需在其 add(int, E) 和 remove(int) 方法(以及它所重寫的、導致列表消慧結構上修改的任何其他方法)中增加此欄位。對 add(int, E) 或 remove(int) 的單個調用向此欄位添加的數量不得超過 1,否則迭代器(和列表迭代器)將拋出虛假的 s。如果某個實現不希望提供快速失敗迭碰睜代器,則可以忽略此欄位。
❺ Java LinkedList問題
這跟腔則並發有毛關系啊,你們在哪能看出這個程序有並發?
只是在迭代的時候把尾元素刪除核纖了,所以it.next()遍歷的元素伍氏棚不一致報的錯
JDK源碼
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ();
}
與期待值不同報 異常
❻ Java中的linkedlist有兩個方法,element()和getFirst(),有什麼不一樣
這種最好的就是看jdk源碼和源碼上的注釋,以及編寫測試代碼實際調用測試一下。
看jdk源碼,LinkedList<E>源碼
先看getFirst()
/**
*Returns改扮thefirstelementinthislist.
*
*@returnthefirst斗殲喚elementinthislist
*@
*/
publicEgetFirst(){
finalNode<E>f=first;
if(f==null)
();
returnf.item;
}
看注釋Returns the first element in this list,返回列表的第一個元素,沒毛病。
然空凱後來看element()
/**
*Retrieves,butdoesnotremove,thehead(firstelement)ofthislist.
*
*@returntheheadofthislist
*@
*@since1.5
*/
publicEelement(){
returngetFirst();
}
結果…… LinkedList 裡面 element()就是直接調用的getFirst()方法
❼ java中的LinkedList的問題在線等,急
import java.util.LinkedList;
/*
*利用LinkedList來實現堆或慧碼棧
*LinkedList容器具有有續性,以及插入刪除方便的特衫哪征
*
*/
public class Stack<T>{
/碧慎/建立一個鏈表保存數據
private LinkedList<T> stack;
public Stack(){
stack = new LinkedList<T>();
}
//入棧操作
public void push(T obj){
stack.addFirst(obj);
}
//獲取棧頂元素
public T top(){
//判斷棧是否為空
if(!isEmpty()){
return stack.getFirst();
}else{
return null;
}
}
//出棧操作
public T pop(){
//判斷棧是否為空
if(!isEmpty()){
return stack.removeFirst();
}else{
return null;
}
}
//判斷棧是否為空
public boolean isEmpty(){
return stack.isEmpty();
}
//測試堆棧
public static void main(String[] args){
String[] list = "my name is beyondlife".split(" ");
Stack<String> stack = new Stack<String>();
for(String obj : list){
stack.push(obj);
}
while(stack.peek() != null){
System.out.print(stack.pop() + " ");
}
}
}
給你改好了,回答個問題真是不容易,你自己改也行啊,這么簡單
❽ 【java】幫看一個LinkedList的小代碼。萬分感謝!!
你好,我幫你找到了世斗孝出現的原因。
下面我們分析下你的構造方法:
DuiLie()
{
link = new LinkedList();
li = link.listIterator(); //注意這里。
}
當你對象在創建的時候,li就已經被初始化好了。
後面的add時,link會改變,但是li已經不會在變化了。所以出現了上面提到的異常。
修改辦法就是修改add方法:
public void add(Object obj) {
link.offerFirst(obj);
li = link.listIterator();
}
但是你的邏輯(設計)還是銷悶有問題的,我意思你自搜稿己在想想,那樣才是自己的東西,我就不多說了。
❾ Java使用LinkedList來模擬一個隊列(先進先出的特性)
importjava.util.LinkedList;
publicclassDemo01{
privateLinkedList<Object>linkedList;
publicDemo01(){
linkedList=newLinkedList<Object>();
}
publicvoidput(Objectobject){
linkedList.add(object);
}
publicObjectget(){
Objectobject=null;
if(linkedList.size()!=0){
object=linkedList.get(0);
linkedList.remove(0);
}
returnobject;
}
publicbooleanisEmpty(){
if(linkedList.size()!=0){
returntrue;
}else{
returnfalse;
}
}
publicstaticvoidmain(String[]args){
Demo01demo01=newDemo01();
demo01.put("1");
demo01.put("2");
System.out.println(demo01.get());
System.out.println(demo01.get());
System.out.println(demo01.isEmpty());
}
}
結果:
1
2
false
❿ java語言中用LinkList實現堆棧
棧和隊列是兩種特殊的線性表,它們的邏輯結構和線性表相同,只是其運算規則較線性表有更多的限制,故又稱它們為運算受限的線性表。
LinkedList數據結構是一種雙向的鏈式結構,每一個對象除了數據本身外,還有兩個引用,分別指向前一個元素和後一個元素,和數組的順序存儲結構(如:ArrayList)相比,插入和刪除比較方便,但速度會慢一些。
棧的定義
棧(Stack)是限制僅在表的一端進行插入和刪除運算的線性表。
(1)通常稱插入、刪除的這一端為棧頂(Top),另一端稱為棧底(Bottom)。
(2)當表中沒有元素時稱為空棧。
(3)棧為後進先出(Last In First Out)的線性表,簡稱為LIFO表。
棧的修改是按後進先出的原則進行。每次刪除(退棧)的總是當前棧中"最新"的元素,即最後插入(進棧)的元素,而最先插入的是被放在棧的底部,要到最後才能刪除。
實現代碼:
package com.weisou.dataStruct;
import java.util.LinkedList;
@SuppressWarnings("unchecked")
public class MyStack {
LinkedList linkList = new LinkedList<Object>();
public void push(Object object) {
linkList.addFirst(object);
}
public boolean isEmpty() {
return linkList.isEmpty();
}
public void clear() {
linkList.clear();
}
// 移除並返回此列表的第一個元素
public Object pop() {
if (!linkList.isEmpty())
return linkList.removeFirst();
return "棧內無元素";
}
public int getSize() {
return linkList.size();
}
public static void main(String[] args) {
MyStack myStack = new MyStack();
myStack.push(2);
myStack.push(3);
myStack.push(4);
System.out.println(myStack.pop());
System.out.println(myStack.pop());
}
}
隊列定義
隊列(Queue)是只允許在一端進行插入,而在另一端進行刪除的運算受限的線性表
(1)允許刪除的一端稱為隊頭(Front)。
(2)允許插入的一端稱為隊尾(Rear)。
(3)當隊列中沒有元素時稱為空隊列。
(4)隊列亦稱作先進先出(First In First Out)的線性表,簡稱為FIFO表。
實現代碼:
package com.weisou.dataStruct;
import java.util.LinkedList;
/**
*
* @author gf
* @date 2009-11-13
*/
public class MyQueue {
LinkedList linkedList = new LinkedList();
//隊尾插
public void put(Object o){
linkedList.addLast(o);
//隊頭取 取完並刪除
public Object get(){
if(!linkedList.isEmpty())
return linkedList.removeFirst();
else
return "";
}
public boolean isEmpty(){
return linkedList.isEmpty();
}
public int size(){
return linkedList.size();
}
public void clear(){
linkedList.clear();
}
/**
* @param args
*/
public static void main(String[] args) {
MyQueue myQueue= new MyQueue();
myQueue.put(1);
myQueue.put(2);
myQueue.put(3);
System.out.println(myQueue.get());
}
}