Published: October 15, 2016
Introduction
In this tutorial, we’ll build a simple Java application that demonstrates how to leverage various Java 8 features such as Lambda expressions, Streams, Optional, and the new Date-Time API. The application will manage a list of contacts, allowing users to add, remove, and display contacts.
We will use the following Java 8 features in this application:
- Lambda Expressions: For concise and functional code.
- Streams API: For filtering, sorting, and processing the contact list.
- Optional: To handle potential null values.
- Date-Time API: To handle dates for when the contact was added.
This small project will help you understand how Java 8 features can improve code readability and efficiency.
Application Overview
Our application will perform the following tasks:
- Add a new contact: Each contact will have a name, phone number, and the date they were added.
- Remove a contact: Based on the name of the contact.
- Display all contacts: Sorted alphabetically by name.
- Search for contacts by phone number: Using streams and filters.
We’ll implement each feature step by step.
Step 1: Defining the Contact Class
First, we need to define a Contact
class that will store the contact’s information.
import java.time.LocalDate;
public class Contact {
private String name;
private String phoneNumber;
private LocalDate dateAdded;
public Contact(String name, String phoneNumber, LocalDate dateAdded) {
this.name = name;
this.phoneNumber = phoneNumber;
this.dateAdded = dateAdded;
}
// Getters
public String getName() {
return name;
}
public String getPhoneNumber() {
return phoneNumber;
}
public LocalDate getDateAdded() {
return dateAdded;
}
@Override
public String toString() {
return "Name: " + name + ", Phone: " + phoneNumber + ", Added on: " + dateAdded;
}
}
The Contact
class has three fields:
name
for the contact’s name.phoneNumber
for the contact’s phone number.dateAdded
to record when the contact was added, using the newLocalDate
class from the Date-Time API.
Step 2: Creating the Contact Manager
Now we’ll create a ContactManager
class that will manage the contact list. We will use a List<Contact>
to store contacts and define methods to add, remove, and display contacts.
import java.util.*;
import java.util.stream.*;
public class ContactManager {
private List<Contact> contactList;
public ContactManager() {
this.contactList = new ArrayList<>();
}
// Add a new contact
public void addContact(Contact contact) {
contactList.add(contact);
}
// Remove a contact by name
public boolean removeContactByName(String name) {
return contactList.removeIf(contact -> contact.getName().equalsIgnoreCase(name));
}
// Display all contacts sorted by name
public void displayAllContacts() {
contactList.stream()
.sorted(Comparator.comparing(Contact::getName)) // Sort by name
.forEach(System.out::println); // Print each contact
}
// Search for contacts by phone number
public void searchByPhoneNumber(String phoneNumber) {
contactList.stream()
.filter(contact -> contact.getPhoneNumber().equals(phoneNumber)) // Filter by phone number
.forEach(System.out::println); // Print the matching contact(s)
}
}
The ContactManager
class includes the following methods:
addContact(Contact contact)
: Adds a contact to the list.removeContactByName(String name)
: Removes a contact by its name.displayAllContacts()
: Displays all contacts sorted by their name.searchByPhoneNumber(String phoneNumber)
: Searches for contacts with a specific phone number.
Step 3: Main Application Logic
Now let’s put everything together in the Main
class. We’ll create instances of the Contact
class, add them to the ContactManager
, and perform some actions like adding, removing, and displaying contacts.
import java.time.LocalDate;
public class Main {
public static void main(String[] args) {
// Create a ContactManager instance
ContactManager manager = new ContactManager();
// Adding contacts
manager.addContact(new Contact("Alice", "123-456-7890", LocalDate.of(2016, 5, 10)));
manager.addContact(new Contact("Bob", "987-654-3210", LocalDate.of(2016, 7, 20)));
manager.addContact(new Contact("Charlie", "555-123-4567", LocalDate.of(2016, 8, 15)));
// Display all contacts
System.out.println("All Contacts:");
manager.displayAllContacts();
// Remove a contact by name
System.out.println("\nRemoving contact Bob...");
manager.removeContactByName("Bob");
// Display all contacts after removal
System.out.println("\nAll Contacts After Removal:");
manager.displayAllContacts();
// Search for contacts by phone number
System.out.println("\nSearching for contact with phone number 123-456-7890:");
manager.searchByPhoneNumber("123-456-7890");
}
}
Step 4: Explanation of Java 8 Features Used
Let’s break down how Java 8 features were applied in this project:
- Lambda Expressions:
- We used lambda expressions in
removeContactByName()
to remove a contact based on its name:return contactList.removeIf(contact -> contact.getName().equalsIgnoreCase(name));
- We also used lambdas in the
displayAllContacts()
andsearchByPhoneNumber()
methods to print contact details and filter contacts.
- We used lambda expressions in
- Streams API:
- We used the Streams API to perform various tasks like filtering, sorting, and printing contacts:
contactList.stream() .sorted(Comparator.comparing(Contact::getName)) // Sorting contacts .forEach(System.out::println); // Printing contacts
- We used the Streams API to perform various tasks like filtering, sorting, and printing contacts:
- Optional:
- While we didn’t explicitly use
Optional
in this example, you could use it to handle cases where the phone number or name might be missing.
- While we didn’t explicitly use
- Date-Time API:
- We used
LocalDate
to store and display the date when each contact was added:LocalDate.of(2016, 5, 10)
- We used
Conclusion
In this tutorial, we built a simple contact management application using Java 8 features. We utilized Lambda expressions, Streams, Optional, and the Date-Time API to perform basic operations like adding, removing, and searching for contacts. This example demonstrates how Java 8’s functional programming features can simplify code and make it more readable.
In future tutorials, we’ll dive deeper into these features and explore even more advanced use cases.