It is a gloomy Tuesday in the Twin Cities of Minneapolis and St. Paul. It rained last night. It is quite damp. It is a typical fall day in this part of the country. The only difference is that in the past two years the lawns are green instead of being brown. I do not know for sure the cause for the climate change which is a very controversial topic, but for sure something is changing.
I am going to quickly cover some operations with Lists in Java. Will use lists on my next post. I need a refresher given that lately I have been working with C/C++ and after a few weeks (which in this case included a two week holiday) of not working with a programming language I tend to stumble with the syntax. It all gets back after a day or so of concentrating on the specific language.
My parents came from Italy. I was first generation abroad. I recall my great aunt who was born in Italy looking for an Italian dictionary when writing letters to her sisters. I could not comprehend that a native speaker could ever forget the first language they learned.
In my case, my first programming language was FORTRAN IV. I then moved on to PLI/C, BASIC and a little later Pascal. During that time I used to work on and off with assembly language using different CPUs. Shortly after I started on my first job, I was introduced to C. Worked with it for about a decade. Then C++ and C# came along. Today I work using the last two languages in addition to Java. I thought I would never forget the syntax for the C libraries. Today if a few weeks go by and I am not using C, just like my great aunt, I need to check the syntax using the IDE or Google. After a day or so, things seem to come back. They say you never forget to ride a bike. The difference is that riding a bike is muscle memory and programming is done using your brain. Go figure.
In this post I am using Java on the Eclipse IDE. I could well have used Visual Studio Code.
main <<< i: 1 temp: 1 main <<< i: 2 temp: 2 main <<< i: 3 temp: 3 main <<< i: 4 temp: 4 main <<< i: 5 temp: 5 main <<< ali toString: [1, 2, 3, 4, 5] main <<< ali get: [1, 2, 3, 4, 5] main <<< ali iterator: [1, 2, 3, 4, 5] main <<< ali for: [1, 2, 3, 4, 5] main <<< removed: 1 main <<< ali toString: [2, 3, 4, 5] main <<< removed: 2 main <<< ali toString: [3, 4, 5] main <<< removed: 3 main <<< ali toString: [4, 5] main <<< removed: 4 main <<< ali toString: [5] main <<< removed: 5 main <<< ali toString: [] main <<< lli toString: [1, 2, 3, 4, 5] main <<< lli get: [1, 2, 3, 4, 5] main <<< lli iterator: [1, 2, 3, 4, 5] main <<< lli for: [1, 2, 3, 4, 5] main <<< removed: 5 main <<< lli toString: [1, 2, 3, 4] main <<< removed: 4 main <<< lli toString: [1, 2, 3] main <<< removed: 3 main <<< lli toString: [1, 2] main <<< removed: 2 main <<< lli toString: [1] main <<< removed: 1 main <<< lli toString: [] main <<< aList: [0, 1, 2, 3, 4] main <<< listOfLists: [[0, 1, 2, 3, 4]] main <<< aList: [1, 2, 3, 4, 5] main <<< listOfLists: [[0, 1, 2, 3, 4], [1, 2, 3, 4, 5]] main <<< aList: [2, 3, 4, 5, 6] main <<< listOfLists: [[0, 1, 2, 3, 4], [1, 2, 3, 4, 5], [2, 3, 4, 5, 6]]
The idea is to populate an array list and then traverse it in different ways. We then repeat the steps with minor changes using a linked list. In the last part we use a list of lists implemented with array lists.
Let’s take a look at the Java code that I used to experiment with an Array List.
// **** **** final int NUM_ELEMENTS = 5; final int NUM_LISTS = 3; // **** experiment with an array list **** ArrayList<Comparable> ali = new ArrayList<Comparable>(); // **** populate the array list with strings **** for (int i = 1; i <= NUM_ELEMENTS; i++) { String temp = String.valueOf(i); System.out.println("main <<< i: " + i + " temp: " + temp); ali.add(temp); } System.out.println(); // **** display the array list **** System.out.println("main <<< ali toString: " + ali.toString()); // **** traverse the array list (method: 1) **** System.out.print("main <<< ali get: ["); for (int i = 0; i < ali.size(); i++) { if (i + 1 < ali.size()) System.out.print(ali.get(i) + ", "); else System.out.print(ali.get(i)); } System.out.println("]"); // **** traverse the array list (method: 2) **** Iterator<Comparable> it = ali.iterator(); System.out.print("main <<< ali iterator: ["); while (it.hasNext()) { System.out.print(it.next()); if (it.hasNext()) System.out.print(", "); } System.out.println("]"); // **** traverse the array list (method: 3) **** System.out.print("main <<< ali for: ["); int j = 0; for (Object o : ali) { if (j + 1 < ali.size()) System.out.print(o + ", "); else System.out.print(o); j++; } System.out.println("]\n"); // **** remove elements from the list **** while (ali.size() > 0) { System.out.println("main <<< removed: " + ali.remove(0)); System.out.println("main <<< ali toString: " + ali.toString()); } System.out.println();
We start by instantiating an array list. In this case I decided to make a list of type Comparable. We could have used Integer, String or other data type.
We populate the array list with strings. The values are displayed as we populate the list. I could have made this code a lot simpler and declaring the array list of type string. The reason was that while I was experimenting I added some strings and some integers. I also used the get() and the indexOf() methods. When I was done I had removed the use of indexOf(). Please note that get() is used to get an element from the array list by index. The indexOf() method returns the index of the first element in the list that matches the specified value. Depending on the values you use you may think you are retrieving the proper elements from the list but you could just be displaying the values of the indices. Like I have mentioned many times on this post, I like to experiment to make sure the concepts are clear in my mind.
The next step is to display the contents of the array list to make sure all is well.
We now traverse the array list by indexing each element. The output on the console of the IDE shows a match.
Next we traverse the array list using an iterator. In practice one would probably not use an iterator with an array list. The reason is that the array list data structure is backed by an array and it is simpler and faster to just index the elements by offset.
The last traversal on the array list is to iterate it using a foreach loop. Note that we do not have an index. I added an index that I used to match the previous displays. I would just have ignored the last ‘,’ but …
We then remove all elements of the array list. As we do it we display the element removed. Note that we are removing the first element from the array list and stop when the array list is empty. We could also have removed the last element on each loop and use the same stop condition.
// **** experiment with a linked list **** List<Integer> lli = new LinkedList<Integer>(); // **** populate the linked list **** for (int i = 1; i <= NUM_ELEMENTS; i++) lli.add(i); // **** display the list **** System.out.println("main <<< lli toString: " + lli.toString()); // **** traverse the linked list (method: 1) **** System.out.print("main <<< lli get: ["); for (int i = 0; i < lli.size(); i++) { if (i + 1 < lli.size()) System.out.print(lli.get(i) + ", "); else System.out.print(lli.get(i)); } System.out.println("]"); // **** traverse the linked list (method: 2) **** Iterator<Integer> iter = lli.iterator(); System.out.print("main <<< lli iterator: ["); while (iter.hasNext()) { System.out.print(iter.next()); if (iter.hasNext()) System.out.print(", "); } System.out.println("]"); // **** traverse the linked list (method: 3) **** System.out.print("main <<< lli for: ["); int k = 0; for (Object o : lli) { if (k + 1 < lli.size()) System.out.print(o + ", "); else System.out.print(o); k++; } System.out.println("]\n"); // **** remove elements from the list **** while (!lli.isEmpty()) { System.out.println("main <<< removed: " + lli.remove(lli.size() - 1)); System.out.println("main <<< lli toString: " + lli.toString()); } System.out.println();
Another type of list in Java is the Linked List. This class is backed up by a linked list. In a linked list you need to traverse each element starting at the head to get to the desired one. For this reason operations are slightly slower than when using an Array List. The good thing is that memory is allocated as needed. In an Array List the class will allocate a new array when space is needed and will copy all the data to the new array. On the other hand, access to the elements is faster. Keep this in mind when using different types of lists. You need to determine the use case and then select the best class.
This code is similar to the array list. We first allocate a linked list and add some elements. In this case the type is Integer.
After the linked list is populated with some values we display it to make sure all is well.
The first traversal of the linked list is done by index getting each element and displaying it. We have code to make the output look similar to the first case when we display the list as a string.
We then traverse the linked list using an iterator. The display seems to match the previous output strings.
In the third method of displaying the linked list we use the foreach loop approach. Note that we do not have a way to determine when we need to omit the last ‘,’ before the closing bracket. For that we make us of an index. This is similar to what we did with the array list.
To complete this section we now loop removing elements from the linked list. Note that we are removing elements from the tail. This is quite expensive given that we need to traverse the entire list on each loop. An optimization by the class could keep track of the tail in the linked list and with some optimizations delete the last element directly. This could easily be done if the implementation (which I believe it is) makes use of a doubly linked list.
// **** list of lists with ArrayList **** ArrayList<ArrayList<Integer>> listOfLists = new ArrayList<ArrayList<Integer>>(); // **** loop building a list of lists **** for (int i = 0; i < NUM_LISTS; i++) { // **** **** ArrayList<Integer> aList = new ArrayList<Integer>(); // **** populate the list **** for (int l = i; l < NUM_ELEMENTS + i; l++) aList.add(l); // **** display the list **** System.out.println("main <<< aList: " + aList.toString()); // **** add the list to the list of lists **** listOfLists.add(aList); // **** display the list of lists **** System.out.println("main <<< listOfLists: " + listOfLists.toString()); }
In this last section of the post we implement a list of lists using the Array List class.
The code starts by instantiating the list of lists.
We the loop once per list we wish to add to the list of lists. In the inner loop we populate a list, display it and add it to the list of lists. We finally display the contents of the list of lists.
To make it easy to check that all is working we add to each list different values and display the list of lists on each pass.
It seems that all is working as expected.
On the next post we will make use of a list of lists to solve a problem.
The entire code for this project can be found in my GitHub repository.
If you have comments or questions regarding this or any other post in this blog, or if you would like me to help with any phase in the SDLC (Software Development Life Cycle) of a product or service, please do not hesitate and leave me a note below. Requests for help will remain private.
Keep on reading and experimenting. It is the best way to learn and refresh your knowledge!
John
Follow me on Twitter: @john_canessa