It is Monday morning. The cleaning lady who could not make it last Friday due to the snow storm in the area, called to reschedule for this upcoming Friday. Her car is in need to new tires. She will wait for the local side roads in Minneapolis to be cleared before venturing on roads and highways which typically are cleared hours after a snow storm fades. In general roads in Minneapolis and St. Paul are cleaned a day or more after a storm. They typically clean in two consecutive days in order for residents to move their cars from one side of the road to the other.
I had scheduled a video call today at 12:00 PM CST. At least that is what I recall. This morning around 07:00 AM I was down in my home office working. At some point I checked my Gmail and I had received a message to reschedule. Apparently I had missed the call.
I was able to connect, apologize, and reschedule for later this the week. The new appointment showed with the proper day and time.
Later in the morning the original message at 08:30 AM CST showed up on my Google calendar. Not sure what went on. I have been using Gmail and Google calendar for years. I have not experienced a problem like this before. That said; a different appointment that allegedly was set for this week on a different day appears to have moved to a later time on the same day.
The main subject for this post is Vectors in Java. Most programming languages seem to have a data structure with the same name and as expected works in similar ways.
Vectors store the data in a linear fashion, but unlike arrays, they do not have a fixed size. Instead, their size can be increased as needed. To use vectors in Java, we have to import the Vector class from java.util package.
When we need to change the size of an array data structure in the middle of a program, vectors as to oppose to arrays, allow us to do so. In addition, vectors are synchronized, which gives them an advantage over array lists when dealing with multithreaded programs, because of the risks of data corruption. That said; in most (never generalize) of the problems we coven in this blog, there is typically no need to be concerned with side effects regarding multithreaded programs. Our programs /solutions tend to be single threaded.
If you are like me, I like to always hear the requirements and facts straight from the horse’s mouth. In this case, depending on your JDK version, you should get the associated vector information from Oracle.
5,9,1,11,7,2,13,1 main <<< arr: [5, 9, 1, 11, 7, 2, 13, 1] main <<< size: 0 capacity: 10 main <<< v1: [5, 9, 1, 11, 7, 2, 13, 1] main <<< size: 8 capacity: 10 main <<< v1: [] main <<< size: 0 capacity: 10 main <<< v1: [5, 9, 1, 11, 7, 2, 13, 1] main <<< size: 8 capacity: 10 main <<< v1: [5, 9, 17, 1, 11, 7, 2, 13, 1] main <<< size: 9 capacity: 10 main <<< v1: [5, 9, 17, 1, 11, 7, 2, 13, 1, 19, 23] main <<< size: 11 capacity: 20 main <<< v1: [5, 9, 17, 1, 11, 7, 2, 13, 1, 19, 23] main <<< removed: e: 5 main <<< removed: e: 17 main <<< removed: e: 11 main <<< removed: e: 2 main <<< removed: e: 1 main <<< removed: e: 23 main <<< EXCEPTION e: java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 6 i: 6 main <<< v1: [9, 1, 7, 13, 19] main <<< size: 5 capacity: 20 main <<< v1: [9, 1, 7, 13, 19, null, null, null, null, null] main <<< size: 10 capacity: 20 main <<< v1: [9, 1, 7, 13, 19] main <<< size: 5 capacity: 20 main <<< v1: [9, 1, 7, 13, 19] main <<< size: 5 capacity: 5 main <<< v1: [1, 5, 7, 9, 13, 19] main <<< size: 6 capacity: 10
Since we do not have a problem at hand to solve, the test scaffolding is just a set of operations in no specific order. For it to make sense we need to look at the source code.
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.Arrays; import java.util.Collections; import java.util.Vector; import java.util.stream.Collectors; /** * */ public class VectorsInJava { /** * Test scaffolding. */ public static void main(String[] args) throws IOException { // **** initialization **** int[] arr = null; // **** open a buffered reader **** BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // **** create and read arr[] values used to populate a vector **** arr = Arrays.stream(br.readLine().trim().split(",")) .mapToInt(Integer::parseInt). toArray(); // **** close the buffered reader **** br.close(); // **** display the contents of the array **** System.out.println("main <<< arr: " + Arrays.toString(arr)); // **** create and populate a vector **** Vector<Integer> v1 = new Vector<Integer>(); // **** display size and capacity **** System.out.println("main <<< size: " + v1.size() + " capacity: " + v1.capacity()); // **** populate vector **** for(int a : arr) v1.add(a); // **** display vector **** System.out.println("main <<< v1: " + v1.toString()); System.out.println("main <<< size: " + v1.size() + " capacity: " + v1.capacity()); // **** clear vector **** v1.clear(); // **** display vector **** System.out.println("main <<< v1: " + v1.toString()); System.out.println("main <<< size: " + v1.size() + " capacity: " + v1.capacity()); // **** populate vector with arr[] **** v1.addAll(Arrays.stream(arr).boxed().collect(Collectors.toList())); // **** display vector **** System.out.println("main <<< v1: " + v1.toString()); System.out.println("main <<< size: " + v1.size() + " capacity: " + v1.capacity()); // **** insert value at specified position **** v1.add(2, 17); // **** display vector **** System.out.println("main <<< v1: " + v1.toString()); System.out.println("main <<< size: " + v1.size() + " capacity: " + v1.capacity()); // **** add a couple more values **** v1.add(19); v1.add(23); // **** display vector **** System.out.println("main <<< v1: " + v1.toString()); System.out.println("main <<< size: " + v1.size() + " capacity: " + v1.capacity()); // **** traverse the vector **** System.out.print("main <<< v1: ["); for (int i = 0; i < v1.size(); i++) { System.out.print(v1.get(i)); if (i < v1.size() - 1) System.out.print(", "); else System.out.print("]"); } System.out.println(); // **** remove some entries from the vector **** for (int i = 0; i < 10 && !v1.isEmpty(); i++) { // **** remove entry i from vector **** try { int e = v1.remove(i); System.out.println("main <<< removed: e: " + e); } catch (Exception e) { System.out.println("main <<< EXCEPTION e: " + e.toString() + " i: " + i); break; } } // **** display vector **** System.out.println("main <<< v1: " + v1.toString()); System.out.println("main <<< size: " + v1.size() + " capacity: " + v1.capacity()); // **** double the size of the vector (will add null elements) **** v1.setSize(v1.size() * 2); // **** display vector **** System.out.println("main <<< v1: " + v1.toString()); System.out.println("main <<< size: " + v1.size() + " capacity: " + v1.capacity()); // **** remove all null elements from the vector **** while (v1.contains(null)) v1.remove(null); // **** display vector **** System.out.println("main <<< v1: " + v1.toString()); System.out.println("main <<< size: " + v1.size() + " capacity: " + v1.capacity()); // **** trim capacity to current size **** v1.trimToSize(); // **** display vector **** System.out.println("main <<< v1: " + v1.toString()); System.out.println("main <<< size: " + v1.size() + " capacity: " + v1.capacity()); // **** add element to the vector **** v1.add(5); // **** sort the vector contents **** Collections.sort(v1); // **** display vector **** System.out.println("main <<< v1: " + v1.toString()); System.out.println("main <<< size: " + v1.size() + " capacity: " + v1.capacity()); } }
We start as usual importing some libraries. Please note, that I never import libraries in advanced. I have my IDE (in this case VSCode) to suggest the set of libraries that I might use when I specify an operation in a statement. You could always copy and paste the imports when you start writing some code.
The next steps are associated with reading an input line from the console. The data is use to populate an array. In this example we could have just declared the array with the same values. At the time I did not choose to do so because I was planning on reading different data for different operations. After my fiasco with the call I missed earlier today, I decided to read data once and experiment with it. Note that if this example were production code, I would have made the necessary changes. It seems that using a stream would be like, using a cannon to kill a mosquito.
We read and display the contents of our arr[].
Next we create an empty Integer vector. We could have specified a collection to load the vector and some behaviors which you can read in the Class Vector<E> page.
We display the size and capacity of our vector.
We are ready to load the vector with the values in the arr[]. We do so by entering a loop and adding the elements one by one. The contents are then displayed. Note that we read 8 items and the capacity is 10. We can add a couple more elements and the capacity will remain at 10. As soon as we add the 11th element, the capacity will increase by 10 to a total of 20. We will see that shortly.
We decided to clear all the elements from our vector. This is confirmed by the following two statements.
In the next statement we load the vector with a list generated from the arr[]. This is just showing us that we may populate a vector with the contents of a list.
We will now add two more elements to our vector and display the contents. Note that the size and capacity are both 10.
We add a new element at a specified position and two more at the end of the vector. At some point the capacity of the vector increases to 20. This was automatically accomplished by the vector class. If you are wondering if we can shrink the capacity, the answer is yes and will see how shortly.
We now enter a loop and display the contents of the vector. We are doing so to demonstrate how individual elements in a vector are accessed.
The next loop is used to demonstrate that we can remove elements from the vector. We decided to remove them by location so at some point our loop throws an exception. Note that we can always remove an element at the start or end of a vector in a loop until the vectors is empty.
We display the vector to get an idea of which elements remain and their positions in the array. Note that the size if now 5 but the capacity remains at 20.
We can double the size from 5 to 10. As you can see we have added 5 null entries in the vector. The capacity remains at 20. We then remove the null entries and the size goes down to 5 and the capacity remains at 20.
We now trim the vector to its size. As you can see the size of 5 now matches the capacity of 5.
Finally we add element 5 to our vector. The size goes up to 6 but the capacity went up to 10. This is the default behavior of the capacity. We could have specified a different capacity increment when we declared the vector, but we did not.
As you can see there are many more ways we can experiment with vectors in order to better get to know their behavior. Becoming familiar with a class / library will help us solve future problems applying the best possible data structure for the problem at hand.
Hope you enjoyed solving this problem as much as I did. 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 for me to help out with any phase in the SDLC (Software Development Life Cycle) of a project associated with a product or service, please do not hesitate and leave me a note below. If you prefer, send me a private e-mail message. I will reply as soon as possible.
Keep on reading and experimenting. It is the best way to learn, become proficient, refresh your knowledge and enhance your developer toolset.
One last thing, many thanks to all 5,938 subscribers to this blog!!!
Keep safe during the COVID-19 pandemic and help restart the world economy. I believe we can all see the light at the end of the tunnel.
Regards;
John
john.canessa@gmail.com