Java Projects
eBook - ePub

Java Projects

Learn the fundamentals of Java 11 programming by building industry grade practical projects, 2nd Edition

Peter Verhas

Share book
  1. 524 pages
  2. English
  3. ePUB (mobile friendly)
  4. Available on iOS & Android
eBook - ePub

Java Projects

Learn the fundamentals of Java 11 programming by building industry grade practical projects, 2nd Edition

Peter Verhas

Book details
Book preview
Table of contents
Citations

About This Book

Learn how to build scalable, resilient, and effective applications in Java that suit your software requirements.

Key Features

  • Explore advanced technologies that Java 11 delivers such as web programming and parallel computing
  • Discover modern programming paradigms such as microservices, cloud computing and enterprise structures
  • Build highly responsive applications with this practical introduction to Reactive programming

Book Description

Java is one of the most commonly used software languages by programmers and developers. In this book, you'll learn the new features of Java 11 quickly and experience a simple and powerful approach to software development. You'll see how to use the Java runtime tools, understand the Java environment, and create a simple namesorting Java application. Further on, you'll learn about advanced technologies that Java delivers, such as web programming and parallel computing, and will develop a mastermind game. Moving on, we provide more simple examples, to build a foundation before diving into some complex data structure problems that will solidify your Java 11 skills. With a special focus on the features of new projects: Project Valhalla, Project Panama, Project Amber, and Project Loom, this book will help you get employed as a top-notch Java developer. By the end of the book, you'll have a firm foundation to continue your journey toward becoming a professional Java developer.

What you will learn

  • Compile, package, and run a program using a build management tool
  • Get to know the principles of test-driven development
  • Separate the wiring of multiple modules from application logic
  • Use Java annotations for configuration
  • Master the scripting API built into the Java language
  • Understand static versus dynamic implementation of code

Who this book is for

This book is for anyone who wants to learn the Java programming language. No programming experience required. If you have prior experience, it will help you through the book more easily.

Frequently asked questions

How do I cancel my subscription?
Simply head over to the account section in settings and click on “Cancel Subscription” - it’s as simple as that. After you cancel, your membership will stay active for the remainder of the time you’ve paid for. Learn more here.
Can/how do I download books?
At the moment all of our mobile-responsive ePub books are available to download via the app. Most of our PDFs are also available to download and we're working on making the final remaining ones downloadable now. Learn more here.
What is the difference between the pricing plans?
Both plans give you full access to the library and all of Perlego’s features. The only differences are the price and subscription period: With the annual plan you’ll save around 30% compared to 12 months on the monthly plan.
What is Perlego?
We are an online textbook subscription service, where you can get access to an entire online library for less than the price of a single book per month. With over 1 million books across 1000+ topics, we’ve got you covered! Learn more here.
Do you support text-to-speech?
Look out for the read-aloud symbol on your next book to see if you can listen to it. The read-aloud tool reads text aloud for you, highlighting the text as it is being read. You can pause it, speed it up and slow it down. Learn more here.
Is Java Projects an online PDF/ePUB?
Yes, you can access Java Projects by Peter Verhas in PDF and/or ePUB format, as well as other popular books in Ciencia de la computación & Programación en Java. We have over one million books available in our catalogue for you to explore.

Information

Year
2018
ISBN
9781789130690

Optimizing the Sort - Making Code Professional

In this chapter, we will develop the sorting code and make it more general. We want to sort something that is more general and not only an array of strings. Essentially, we will write a program that can sort anything that is sortable. That way, we will bring the coding to its full extent toward one of the major strengths of Java—abstraction.
Abstraction, however, does not come without a price tag. When you have a class that sorts strings and you accidentally mix an integer or something else that is not a string into the sortable data, then the compiler will complain about it. Java does not allow you to put an int into an String array. When the code is more abstract, such programming errors may slip in. We will look at how to handle such exceptional cases by catching and throwing exceptions. Later, we will also look at generics, a feature of Java that can help to catch such programming mistakes at compile time.
To identify bugs, we will use unit testing, applying the industry standard JUnit version 4. As JUnit heavily uses annotations, and because annotations are important, we will also learn about annotations a bit.
After that, we will modify the code to use the generics feature of Java that was introduced into the language in version 5. Using that, we will catch coding errors during compilation time. This is much better than handling exceptions during runtime. The earlier a bug is identified, the cheaper it is to fix.
For the build, we will still use Maven, but this time, we will split the code into small modules. Thus, we will have a multi-module project. We will have separate modules for the definition of a sorting module and for the different implementations. That way, we will look at how classes can extend each other and implement interfaces, and generally, we will really start to program in an object-oriented way.
We will also discuss Test-Driven Development (TDD), and at the end of the section, we will start using the brand new feature Java introduced in version 9—module support.
In this chapter, we will cover the following topics:
  • Object-oriented programming principles
  • Unit testing practices
  • Algorithmic complexity and quicksort
  • Exception handling
  • Recursive methods
  • Module support

The general sorting program

In the previous chapter, we implemented a simple sorting algorithm. The code can sort elements of a String array. We did this to learn. For practical use, there is a ready-cooked sort solution in the JDK that can sort members of Collection objects that are comparable.
The JDK contains a utility class called Collections, which itself contains a static method, Collections.sort. This method can sort any List that has members that are Comparable (more precisely, members that are instances of a class that implements the Comparable interface). List and Comparable are interfaces defined in the JDK. Thus, if we want to sort a list of Strings, the simplest solution is as follows:
public class SimplestStringListSortTest { @Test public void canSortStrings() { var actualNames = new ArrayList(Arrays.asList( "Johnson", "Wilson", "Wilkinson", "Abraham", "Dagobert" )); Collections.sort(actualNames); Assert.assertEquals(new ArrayList<>(Arrays.asList( "Abraham", "Dagobert", "Johnson", "Wilkinson", "Wilson")), actualNames); } }
This code fragment is from a sample JUnit test, which is the reason we have the @Test annotation in front of the method. We will discuss that in detail later. To execute that test, we can issue the following command:
$ mvn -Dtest=SimplestStringListSortTest test
This sort implementation, however, does not meet our needs. The main reason is that we want to learn something new. Using the JDK's sort() method does not teach you anything new, except, perhaps the @Test annotation that stands in front of the method.
If there is something that you cannot follow in the previous code, then you can turn some pages back in this book and consult the Oracle online documentation of the JDK (https://docs.oracle.com/javase/9/docs/api/), but that is all. You already know these things.
You may wonder why I wrote the URL for the Java version 9 API to the link. Well, then this is the moment of honesty and truth—when I wrote this book, the Java 11 JDK was not available in its final form. As a matter of fact, even the Java 10 JDK was only pre-release. I created most of the examples on my MacBook using Java 8 in the first edition and I only tested the features that are Java 9, 10, or 11-specific later. When you read this book, Java 11 will be available, so you can try and change that one single digit from 9 to 11 in the URL and get the documentation for version 11. At the moment, I get HTTP ERROR 404. Sometimes, you may need the documentation of older versions. You can use 3, 4, 5, 6, 7, 8, or 9 instead of 11 in the URL. Documentation for 3 and 4 is not available to read online, but it can be downloaded. Hopefully, you will never need that. Version 5, perhaps. Version 6 was still widely used at large corporations when the first edition of this book was published and it has not changed too much since then.
Although you can learn a lot from reading code that was written by other programmers, I do not recommend trying to learn from the JDK source code at this early stage of your studies. These blocks of code are heavily optimized, not meant to be tutorial code, and they are old. They do not rust, but they were not refactored to follow the newer coding styles of Java as it matured. In some places, you can find some really ugly code in the JDK.
Okay, saying that we need to develop a new sort() because we can learn from it is a bit contrived. The real reason why we need a sort implementation is that we want something that can sort not only List data types and a List of something that implements the Comparable interface; we want to sort a bunch of objects. All we require is that the bunch containing the objects provides simple methods that are just enough to sort them and have a sorted bunch.
Originally I wanted to use the word collection instead of bunch, but there is a Collection interface in Java and I wanted to emphasize that we are not talking about a java.util.Collection of objects.
We also do not want the objects to implement the Comparable interface. If we require the object to implement the Comparable interface, it may violate the Single Responsibility Principle (SRP).
When we design a class, it should model some object class in the real world. We will model the problem space with classes. The class should implement features that represent the behavior of the objects it models. If we look at the example of students from the second chapter, then a Student class should represent the features that all students share and are important from the modeling point of view. A Student object should be able to tell the name of the student, the age, the average scores over the last year, and so on. We should, however, focus on the features that are relevant for our programming needs. For example, all students have feet, and certainly, each of those feet has a size, so we may think that a Student class should also implement a method that returns the size of the student's feet. To make it extremely ridiculous just to highlight the absurdity, we could implement the data structure and the API to register a size for the left foot and a different size for the right foot. We do not because the size of feet is irrelevant from the model point of view.
However, if we want to sort a list containing Student objects, the Student class has to implement the Comparable interface. But wait! How do you compare two students? By names, by age, or by their average scores?
Comparing one student to another is not an essential feature of the Student class. Every class, or for that matter, package, library, or programming unit, should have one responsibility and it should implement only that and nothing else. It is not exact. This is not mathematics. Sometimes, it is hard to tell whether a feature fits that responsibility or not. Comparability can be an inherent feature of some data types, such as Integer or Double. Other classes do not have such an inherent comparison feature.
There are simple techniques to be sure whether a feature should or should not be part of a class. For example, in the case of a student, you can ask the real person about their name and age, and they can probably also tell you their average score. If you ask one of them to compareTo (another student), as the Comparable interface requires this method, they will probably ask back by what attribute or how? If they are not the polite type, they may reply by simply saying what? (Not to mention the abbreviation WTF, which stands for the last three working days of the week and is popular in situations like this.) In such a case, you may suspect that implementing the feature is probably not in the area of that class and its concerns; the comparison should be segregated from the implementation of the original class. This is also called segregation of concerns, which is closely related to the SRP.
JDK developers are aware of this. Collections.sort, which sorts a List of Comparable elements, is not the only sorting method in this class. There is another that just sorts any List if you pass a second argument, which should be an object that implements the Comparator interface and is capable of comparing two elements of the List. This is a clean pattern to separate concerns. In some cases, separating the comparison is not needed. In other cases, it is desirable. The Comparator interface declares one single method that the implementing classes have to provide—compare. If the two arguments are equal, the method returns 0. If they are different, it should return a negative or a positive int, depending on which argument precedes the other.
There are also sort methods in the JDK class, java.util.Arrays. They sort arrays or only a slice of an array. The method is a good example of method overloading. There are methods with the same name, but with different arguments, to sort a whole array for each primitive type, for a slice of each, and also two for object arrays implementing the Comparable interface, and also for object arrays to be sorted using Comparator. As you see, there is a whole range of sort implementations available in the JDK, and in 99% of cases, you will not need to implement a sort yourself. Sorts use the same algorithm, a stable merge sort with some optimization.
What we will implement is a general approach that can be used to sort lists, arrays, or just anything that has elements we can compare with the help of a comparator, and where it is possible to swap any two elements. We will implement different sorting algorithms that can be used with these interfaces.

A brief overview of various sorting algorithms

There are many different sorting algorithms. As I said, there are simpler and more complex algorithms and, in many cases, the more complex algorithms are the ones that run faster. (After all, what would be the benefit of higher complexity algorithm if it runs even slower?) In this chapter, we will implement a bubble sort and a quicksort. We have already implemented a bubble sort for strings in the previous chapter, so in this case, the implementation will mainly focus on the coding for general sortable object sorting. Implementing a quicksort will involve a bit of algorithmic interest.
Be warned that this section is here to give you only a taste of algorithmic complexity. It is far from precise and I am in the vain hope that no mathematician reads this and puts a curse on me. Some of the explanations are vague. If you want to learn computer science in depth, then after reading this book, find some other books or visit online courses.
When we talk about the general sorting problem, we think about some general ordered collection of objects where any two can be compared and swapped while we sort. We also assume that this is an in-place sort. This means that we do not create another list or array to collect the original objects in sorted order. When we talk about the speed of an algorithm, we are talking about some abstract thing and not milliseconds. When we want to talk about milliseconds, actual real-world duration, we should already have an implementation in some programming language running on a real computer.
Algorithms, in their abstract form without implementation, don't do that. Still, it is worth talking about the time and memory needs of an algorithm. When we do that, we usually investigate how the algorithm behaves for a large set of data. For a small set of data, most algorithms are just fast. Sorting two numbers is usually not an issue, is it?
In the case of sorting, we usually examine how many comparisons are needed to sort a collection of n elements. Bubble sort needs approximately n2 (n times n) comparisons. We cannot say that this is exactly n2 because, in the case of n=2, the result is 1, for n=3 it is 3, for n=4 it is 6, and so on. However, as n starts to get larger, the actual number of comparisons needed and n2 will asymptotically be of the same value. We say that the algorithmic complexity of the bubble sort is O(n2). This is also called big-O notation. If you have an algorithm that is O(n2) and it works just fine for 1,000 elements, finishing in a second, then you should expect the same algorithm to finish 1 million elements in around ten days to a month. If the algorithm is linear, say O(n), then finishing 1,000 elements in one second should lead you to expect 1 million to be finished in 1,000 seconds. That is a bit longer than a coffee break, but too short for lunch.
This makes it feasible that if we want some serious business sorting objects, we will need something better than bubble sort. The many unnecessary comparisons are not only wasting our time, but also wasting CPU power, consuming energy, and polluting the environment.
The question, however, is how fast can a sort be? Is there a provable minimum that we cannot reduce?
The answer is...

Table of contents