2

So a part of my homework is to get a string of integer numbers and put each one of them in a list, this is what I have done:

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

So what I've done is take the string, split it into an array and then take the items with the for loop and put them into a list. What I am confused with is that I see people using the add command with a "new" inside the parentheses like this:

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

This is confusing me and I'm not totally sure if I'm doing this the right way. By the way, I take the array elements from count + 2 because I do not need the first two elements of the answer but I need to store the first two integers in two separate variables.

Also I've seen some people write this:

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

Is there any difference from that and what I've written?

Andrew Barber
  • 39,603
  • 20
  • 94
  • 123
Aki K
  • 1,222
  • 1
  • 27
  • 49
  • Don't declare variables upfront, before you use them. Keep their scope small. N is used 4 lines later and can be introduced right there (`N=...`), count isn't used outside the loop. – user unknown Apr 29 '12 at 12:04
  • I just thought that it is like a good rule to declare them upfront, that it would make thing better for the eye? As for count I use it in the main program again later – Aki K Apr 29 '12 at 12:05
  • what I mean is I declare them upfront and write a comment next to them so I know where they are used – Aki K Apr 29 '12 at 12:06

4 Answers4

3

The construct

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

is often seen for mainly 2 reasons:

  • a) You aren't sure what the best collection for your purpose is. There are many candidates: Arrays, Sets, Lists, Vector, Map and so on, but you have to use something specific. So on the right hand side it has to be concrete, but on the left hand side, you try to be as wide open as possible.

Very often you just do iterate over the collection, use a for loop, search, sort, put into, take from, delete.

If you find out, that a sibling of your first thought is better suited, you can later change the RHS, without need to rewrite the rest of your program, because, for example, most methods of LinkedList and ArrayList fullfill the same contract, defined in List.

  • b) You get mor compatible to the outside world, if you use the wider object. Of course, you can't use something as vague as Object, since Object has no .add (E) Method.

But for sorting, searching and so on List is well suited. Have a look at the documentation, and compare List, LinkedList and ArrayList. Try to replace the one with another in your code.

Maybe two 'sublist (int fromIndex, int toIndex)' methods, in Linked~ and ArrayList are defined in the base class, and behave identically.

But maybe they are specialized, and implement subList on their own. Here we have a Interface <- Class relationship, so we know, that there is no implementation in the Interface, it is completly abstract. But in the case of (Abstract) base classes <- derived classes the pattern is the same. Derived/implementing classes share the same interface, 'public List sublist (int fromIndex, int toIndex)'. You expect them to produce the same result, but in different ways - maybe.

Only if you need to call a method which is only present in, say LinkedList, you either declare your bookList as LinkedList up front, or you cast it for that purpose:

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

Sidenote: Your code can be simplified with the modern (7 years old) foreach-loop:

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

But if you declare a Scanner, you can take Integers from the Scanner directly:

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

In reaction to the comments, here is a third code: Reading from System.in a line, and then creating a Scanner on that that line:

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

    while (valueLine.hasNextInt ()) {            
        books.add (valueLine.nextInt ());
    }
user unknown
  • 35,537
  • 11
  • 75
  • 121
  • oh I think I get it now, so if I understand correctly when using Arraylist, LinkedList etc I'll have the specific methods of the one I use but if I use List I'll have all the methods together or something along those lines – Aki K Apr 29 '12 at 12:18
  • @SilliconTouch, not necessarily. Check my answer, I went into this a little bit. What methods you call are executed in the data structure you've declared, but the actual operation varies. Just because `get()` is defined in many structures doesn't mean it operates identically. – Jason Apr 29 '12 at 12:21
1

The function Integer.parseInt returns a new Integer so you do not need to use the new keyword.

Keep experimenting and use an IDE such as Eclipse that will highlight compile errors and you will learn the language soon enough. If you still are struggling read online tutorials or ask your professor.

Garrett Hall
  • 29,524
  • 10
  • 61
  • 76
1

Your code is fine.

The following:

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

is not syntactically correct, whereas what you have is.

As to List<Integer> booksList = ... vs LinkedList<Integer> booksList = ..., I consider the former to be slightly better style. However, it is sometimes necessary to use the latter. The difference is largely stylistic and I wouldn't worry about it too much right now.

Finally, I'd like to echo what others have said in the comments: declare variables when they're first used and not before. Also, don't reuse variables.

NPE
  • 486,780
  • 108
  • 951
  • 1,012
0

A List in Java is an interface, from which the methods are defined in specific implementations. For example, LinkedList implements the List interface, and creates its own version of add, delete and other methods. This is pretty important, since other data structures, such as ArrayList also implement the List interface. Add, delete, and other methods operate very differently in LinkedList and ArrayList.

When you write

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

it operates the same as

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

since the new keyword creates a LinkedList object which is bound to the name booksList. booksList just happens to be a List object in the first example, from which LinkedList implements.

Check the docs and see what data structures implement the List interface. You'll be surprised how many ways a List<Integer> newList = new .... is valid code.

One thing that hasn't been mentioned is its a good idea to pass on the generic type in all the angle brackets when declaring a data structure.

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

Jason
  • 11,263
  • 21
  • 87
  • 181
  • `ArrayList` and `LinkedList` methods operate in a different way, but the result is always the same, that's the main idea of this `Interface` thing. They are interchangeable and the only difference is that every implementation has its use case where it shines in performance (or memory usage). – Petr Janeček Apr 29 '12 at 12:23
  • Also, I don't think that it is a good idea to pass the generic type to all the brackets. This `<>` diamond operator is new to Java 7 and is useful as hell. See [this SO question](http://stackoverflow.com/questions/4166966/what-is-the-point-of-the-diamond-operator-in-java-7) or [Java doc](http://docs.oracle.com/javase/tutorial/java/generics/gentypeinference.html#type-inference-instantiation). – Petr Janeček Apr 29 '12 at 12:24
  • @Slanec, thats what I mean. Different ways of doing the same thing and returning identical results. Also, I'm coming from a Java 6 background, where the diamond operator is nonexistent, and haven't had much playtime with 7. – Jason Apr 29 '12 at 12:31