2012-04-29 3 views
2

Так часть моей домашней работы, чтобы получить строку из целых чисел и поместить каждую из них в списке, это то, что я сделал:путать с реализацией LinkedList

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])); 
    } 

Так что я done - взять строку, разбить ее на массив и затем взять элементы с циклом for и поместить их в список. То, что я запутался с в том, что я вижу людей, с помощью команды надстройку с «новым» в скобках, как это:

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

Это сбивает с толку меня, и я не совсем уверен, если я делаю этого правильно. Кстати, я беру элементы массива из count + 2, потому что мне не нужны первые два элемента ответа, но мне нужно сохранить первые два целых числа в двух отдельных переменных.

Кроме того, я видел, что некоторые люди пишут это:

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

Есть ли разница от того и того, что я написал?

+0

Не объявлять переменные заранее, прежде чем использовать их. Держите их область малой. N используется 4 строки позже и может быть введена прямо там ('N = ...'), счетчик не используется вне цикла. –

+0

Я просто подумал, что это как хорошее правило объявить их заранее, что это будет лучше для глаз? Что касается подсчета, я снова использую его в основной программе –

+0

, я имею в виду, что я объявляю их заранее и пишу комментарий рядом с ними, чтобы я знал, где они используются. –

ответ

3

Конструкт

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

часто рассматривается в основном 2 причины:

  • а) Вы не уверены, что лучшая коллекция для вашей цели есть. Есть много кандидатов: массивы, наборы, списки, вектор, карта и т. Д., Но вы должны использовать что-то конкретное. Итак, с правой стороны это должно быть конкретным, но с левой стороны вы стараетесь быть как можно более широким.

Очень часто вы просто выполняете итерацию по коллекции, используете цикл for, выполняете поиск, сортируете, вставляете, извлекаете, удаляете.

Если вы узнали, что родной брат вашей первой мысли лучше подходит, вы можете позже изменить RHS, не переписывая остальную часть своей программы, потому что, например, большинство методов LinkedList и ArrayList заполняют тот же контракт, определенный в Списке.

  • b) Вы получаете совместимость с внешним миром, если используете более широкий объект. Конечно, вы не можете использовать что-то неопределенное, как Object, поскольку Object не имеет метода .add (E).

Но для сортировки, поиска и т. Д. Список хорошо подходит. Посмотрите документацию и сравните List, LinkedList и ArrayList. Попробуйте заменить один на другой в коде.

Возможно, в базовом классе определены два метода 'sublist (int fromIndex, int toIndex)' в Linked ~ и ArrayList и ведут себя одинаково.

Но, возможно, они специализированы и реализуют сублист самостоятельно. Здесь у нас есть интерфейс < - отношение класса, поэтому мы знаем, что в интерфейсе нет реализации, оно полностью абстрактно. Но в случае (абстрактных) базовых классов < - производные классы одинаковы. . Производные/реализующие классы используют один и тот же интерфейс, 'public List sublist (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. 

Sidenote: Ваш код может быть упрощен с современным (7 лет) Еогеасп петлей:

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(); 

Но если вы объявляете сканер, вы можете взять Inte юрт от сканера непосредственно:

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.in линии, а затем создать сканер на том, что линии:

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

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

oh Я думаю, что я понял это сейчас, поэтому, если я правильно понимаю, когда используя Arraylist, LinkedList и т. д. У меня будут конкретные методы того, который я использую, но если я использую List, у меня будут все методы вместе или что-то в этом роде –

+0

@SilliconTouch, не обязательно. Проверьте мой ответ, я немного поучаствовал в этом. Какие методы вы вызываете, выполняются в структуре данных, которую вы объявили, но фактическая операция меняется. Просто потому, что 'get()' определяется во многих структурах, не означает, что он работает одинаково. – Jason

1

В функцияInteger.parseInt возвращает new Integer так что вам не нужно использовать нового ключевого слова.

Продолжайте экспериментировать и использовать среду IDE, такую ​​как Eclipse, которая выделит ошибки компиляции, и вы скоро узнаете язык. Если вы все еще пытаетесь читать онлайн-уроки или спрашиваете своего профессора.

1

Ваш код в порядке.

Следующая:

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

не синтаксически правильно, а что у вас есть.

Что касается List<Integer> booksList = ... vs LinkedList<Integer> booksList = ..., я считаю, что первое было немного лучше. Однако иногда бывает необходимо использовать последнее. Разница в значительной степени стилистична, и я бы не стал слишком беспокоиться об этом сейчас.

Наконец, я хотел бы повторить то, что другие сказали в комментариях: объявлять переменные, когда они впервые используются, а не раньше. Кроме того, не используйте повторно переменные.

0

A List в Java - это интерфейс, из которого методы определены в конкретных реализациях. Например, LinkedList реализует интерфейс List и создает свою собственную версию add, delete и других методов. Это очень важно, поскольку другие структуры данных, такие как ArrayList, также реализуют интерфейс List. Добавить, удалить и другие методы работают по-разному в LinkedList и ArrayList.

Когда вы пишете

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>()

+0

Методы 'ArrayList' и' LinkedList' работают по-другому, но результат всегда один и тот же, это основная идея этой вещи «Интерфейс». Они взаимозаменяемы, и единственное отличие состоит в том, что каждая реализация имеет свой прецедент, где она сияет в производительности (или использовании памяти). –

+0

Кроме того, я не думаю, что это хорошая идея передать общий тип ко всем скобкам. Этот алмазный оператор '<>' является новым для Java 7 и полезен как ад. См. [Этот вопрос SO] (http://stackoverflow.com/questions/4166966/what-is-the-point-of-the-diamond-operator-in-java-7) или [Java doc] (http://docs.oracle.com/javase/tutorial/java/generics/gentypeinference.html#type-inference-instantiation). –

+0

@Slanec, вот что я имею в виду. Различные способы сделать то же самое и вернуть одинаковые результаты. Кроме того, я исхожу из фона Java 6, где алмазный оператор отсутствует, и у него не было много времени на воспроизведение с 7. – Jason

Смежные вопросы