簡體   English   中英

與LinkedList實現混淆

[英]confused with LinkedList implementation

因此,我的家庭作業的一部分是獲取一串整數並將其每個放入列表中,這就是我所做的:

public static void main(String[] args) {
    Scanner input = new Scanner(System.in);

    String N;
    int count;        
    LinkedList<Integer> booksList = new LinkedList<>();


    System.out.printf("Give: ");
    N = input.nextLine();

    String[] arr = N.split(" ");        

    for (count = 0; count < arr.length - 2; count++) {            
        booksList.add(Integer.parseInt(arr[count + 2]));
    }

因此,我要做的是將字符串取為字符串,將其拆分為數組,然后使用for循環獲取項目並將其放入列表中。 我感到困惑的是,我看到人們在使用add命令,並在括號內加上“ new”,例如:

 booksList.add(new Integer.parseInt(arr[count + 2]));

這讓我感到困惑,我不確定自己是否以正確的方式進行操作。 順便說一句,我從count + 2中獲取數組元素,因為我不需要答案的前兩個元素,但是我需要將前兩個整數存儲在兩個單獨的變量中。

我也看到有人寫這個:

List<Integer> booksList = new LinkedList<>();

這和我寫的有什么不同嗎?

構造

List<Integer> booksList = new LinkedList<>();

經常被看到主要有兩個原因:

  • a)您不確定最適合自己的收藏是什么。 有很多候選對象:數組,集合,列表,向量,地圖等,但是您必須使用特定的東西。 因此,在右側必須是混凝土的,但在左側,則應盡量敞開。

通常,您只是遍歷集合,使用for循環,搜索,排序,放入,提取,刪除。

如果您發現您的第一個想法更合適,則可以稍后更改RHS,而無需重寫程序的其余部分,例如,因為大多數LinkedList和ArrayList方法完全滿足定義的相同協定在列表中。

  • b)如果使用更寬的物體,您將與外界兼容。 當然,您不能使用像Object這樣模糊的東西,因為Object沒有.add(E)方法。

但是對於List的排序,搜索等非常適合。 看一下文檔,比較List,LinkedList和ArrayList。 嘗試在您的代碼中用另一個替換一個。

可能在基類中定義了Linked〜和ArrayList中的兩個“子列表(int fromIndex,int toIndex)”方法,它們的行為相同。

但是,也許他們是專門的,並且自己實現subList。 這里我們有一個Interface <-Class關系,所以我們知道,Interface中沒有實現,它是完全抽象的。 但是,在(抽象)基類<-派生類的情況下,模式是相同的。 派生/實現類共享相同的接口“公共列表子列表(int fromIndex,int toIndex)”。 您期望它們產生相同的結果,但是方式不同-也許。

僅當您需要調用僅存在於LinkedList中的方法時,才可以將bookList預先聲明為LinkedList,或者為此而強制轉換:

List<Integer> books = new LinkedList<>();
// ...
LinkedList <Integer> booksLiLi = (LinkedList <Integer>) books <> ();
// do something with booksLiLi which isn't defined on the List interface.

旁注:可以使用現代的(已有7年歷史)foreach循環來簡化您的代碼:

Scanner input = new Scanner (System.in);
LinkedList<Integer> booksList = new LinkedList<>();
System.out.printf ("Give: ");
String N = input.nextLine ();
String[] arr = answer.split (" ");        

for (String num: arr) {            
    booksList.add (Integer.parseInt (num));
}
bookList.remove ();
bookList.remove ();

但是,如果您聲明了掃描程序,則可以直接從掃描程序中獲取整數:

Scanner input = new Scanner (System.in);
LinkedList<Integer> booksList = new LinkedList<>();
System.out.printf ("Give: ");       

while (input.hasNextInt ()) {            
    booksList.add (input.nextInt ());
}
bookList.remove ();
bookList.remove ();

為了回應這些評論,這是第三個代碼:在一行中從System。讀取,然后在該行上創建一個Scanner:

    String line = input.nextLine (); 
    Scanner valueLine = new Scanner (line);
    List<Integer> books = new LinkedList<>();

    while (valueLine.hasNextInt ()) {            
        books.add (valueLine.nextInt ());
    }

函數 Integer.parseInt返回一個new Integer因此您不需要使用new關鍵字。

繼續嘗試並使用諸如Eclipse之類的IDE來突出顯示編譯錯誤,您將很快學習該語言。 如果您仍在掙扎,請閱讀在線教程或咨詢您的教授。

您的代碼很好。

下列:

booksList.add(new Integer.parseInt(arr[count + 2]));

在語法上是不正確的,而您所擁有的卻是正確的。

至於List<Integer> booksList = ... vs LinkedList<Integer> booksList = ... ,我認為前者的風格略好。 但是,有時有必要使用后者。 這種差異在很大程度上是風格上的,我現在不必擔心太多。

最后,我想回應其他人在評論中所說的話:在變量首次使用時而不是之前聲明它們。 另外,請勿重復使用變量。

Java中的List是一個接口,可以在特定的實現中從中定義方法。 例如, LinkedList實現List接口,並創建其自己的add,delete和其他方法版本。 這非常重要,因為其他數據結構(例如ArrayList也實現了List接口。 添加,刪除和其他方法在LinkedListArrayList操作非常不同。

當你寫

List<Integer> booksList = new LinkedList<>()

它的操作與

LinkedList<Integer> booksList = new LinkedList<>()

因為new關鍵字創建了一個LinkedList對象,該對象綁定到名稱booksList 在第一個示例中, booksList恰好是List對象, LinkedList從中實現。

檢查文檔,看看哪些數據結構實現了List接口。 您會驚訝List<Integer> newList = new ....是有效代碼的方式。

尚未提及的一件事是,在聲明數據結構時在所有尖括號中傳遞通用類型是一個好主意。

List<Integer> booksList = new LinkedList<Integer>()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM