Resolves checkstyle errors for collection-pipeline, command, commander (#1061)

* Reduces checkstyle errors in collection-pipeline

* Reduces checkstyle errors in command

* Reduces checkstyle errors in commander
This commit is contained in:
Anurag Agarwal
2019-11-10 01:05:15 +05:30
committed by Ilkka Seppälä
parent 31f27a720b
commit 2f49648047
41 changed files with 646 additions and 574 deletions

View File

@ -23,21 +23,18 @@
package com.iluwatar.collectionpipeline;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.Map;
/**
* In imperative-style programming, it is common to use for and while loops for
* most kinds of data processing. Function composition is a simple technique
* that lets you sequence modular functions to create more complex operations.
* When you run data through the sequence, you have a collection pipeline.
* Together, the Function Composition and Collection Pipeline patterns enable
* you to create sophisticated programs where data flow from upstream to
* downstream and is passed through a series of transformations.
*
* In imperative-style programming, it is common to use for and while loops for most kinds of data
* processing. Function composition is a simple technique that lets you sequence modular functions
* to create more complex operations. When you run data through the sequence, you have a collection
* pipeline. Together, the Function Composition and Collection Pipeline patterns enable you to
* create sophisticated programs where data flow from upstream to downstream and is passed through a
* series of transformations.
*/
public class App {
@ -45,32 +42,35 @@ public class App {
/**
* Program entry point.
*
* @param args
* command line args
*
* @param args command line args
*/
public static void main(String[] args) {
List<Car> cars = CarFactory.createCars();
List<String> modelsImperative = ImperativeProgramming.getModelsAfter2000(cars);
LOGGER.info(modelsImperative.toString());
List<String> modelsFunctional = FunctionalProgramming.getModelsAfter2000(cars);
LOGGER.info(modelsFunctional.toString());
Map<Category, List<Car>> groupingByCategoryImperative = ImperativeProgramming.getGroupingOfCarsByCategory(cars);
Map<Category, List<Car>> groupingByCategoryImperative =
ImperativeProgramming.getGroupingOfCarsByCategory(cars);
LOGGER.info(groupingByCategoryImperative.toString());
Map<Category, List<Car>> groupingByCategoryFunctional = FunctionalProgramming.getGroupingOfCarsByCategory(cars);
Map<Category, List<Car>> groupingByCategoryFunctional =
FunctionalProgramming.getGroupingOfCarsByCategory(cars);
LOGGER.info(groupingByCategoryFunctional.toString());
Person john = new Person(cars);
List<Car> sedansOwnedImperative = ImperativeProgramming.getSedanCarsOwnedSortedByDate(List.of(john));
List<Car> sedansOwnedImperative =
ImperativeProgramming.getSedanCarsOwnedSortedByDate(List.of(john));
LOGGER.info(sedansOwnedImperative.toString());
List<Car> sedansOwnedFunctional = FunctionalProgramming.getSedanCarsOwnedSortedByDate(List.of(john));
List<Car> sedansOwnedFunctional =
FunctionalProgramming.getSedanCarsOwnedSortedByDate(List.of(john));
LOGGER.info(sedansOwnedFunctional.toString());
}
}

View File

@ -34,10 +34,11 @@ public class Car {
/**
* Constructor to create an instance of car.
* @param make the make of the car
* @param model the model of the car
*
* @param make the make of the car
* @param model the model of the car
* @param yearOfMake the year of built of the car
* @param category the {@link Category} of the car
* @param category the {@link Category} of the car
*/
public Car(String make, String model, int yearOfMake, Category category) {
this.make = make;
@ -103,7 +104,7 @@ public class Car {
public int getYear() {
return year;
}
public Category getCategory() {
return category;
}

View File

@ -34,6 +34,7 @@ public class CarFactory {
/**
* Factory method to create a {@link List} of {@link Car} instances.
*
* @return {@link List} of {@link Car}
*/
public static List<Car> createCars() {

View File

@ -24,7 +24,7 @@
package com.iluwatar.collectionpipeline;
/**
* Enum for the category of car
* Enum for the category of car.
*/
public enum Category {
JEEP, SEDAN, CONVERTIBLE

View File

@ -30,20 +30,17 @@ import java.util.stream.Collectors;
/**
* Iterating and sorting with a collection pipeline
*
*
* <p>In functional programming, it's common to sequence complex operations through
* a series of smaller modular functions or operations. The series is called a
* composition of functions, or a function composition. When a collection of
* data flows through a function composition, it becomes a collection pipeline.
* Function Composition and Collection Pipeline are two design patterns
* frequently used in functional-style programming.
*
* a series of smaller modular functions or operations. The series is called a composition of
* functions, or a function composition. When a collection of data flows through a function
* composition, it becomes a collection pipeline. Function Composition and Collection Pipeline are
* two design patterns frequently used in functional-style programming.
*
* <p>Instead of passing a lambda expression to the map method, we passed the
* method reference Car::getModel. Likewise, instead of passing the lambda
* expression car -> car.getYear() to the comparing method, we passed the method
* reference Car::getYear. Method references are short, concise, and expressive.
* It is best to use them wherever possible.
*
* method reference Car::getModel. Likewise, instead of passing the lambda expression car ->
* car.getYear() to the comparing method, we passed the method reference Car::getYear. Method
* references are short, concise, and expressive. It is best to use them wherever possible.
*/
public class FunctionalProgramming {
private FunctionalProgramming() {
@ -51,35 +48,35 @@ public class FunctionalProgramming {
/**
* Method to get models using for collection pipeline.
*
*
* @param cars {@link List} of {@link Car} to be used for filtering
* @return {@link List} of {@link String} representing models built after year 2000
*/
public static List<String> getModelsAfter2000(List<Car> cars) {
return cars.stream().filter(car -> car.getYear() > 2000)
.sorted(Comparator.comparing(Car::getYear))
.map(Car::getModel).collect(Collectors.toList());
.sorted(Comparator.comparing(Car::getYear))
.map(Car::getModel).collect(Collectors.toList());
}
/**
* Method to group cars by category using groupingBy
*
* Method to group cars by category using groupingBy.
*
* @param cars {@link List} of {@link Car} to be used for grouping
* @return {@link Map} with category as key and cars belonging to that category as value
*/
public static Map<Category, List<Car>> getGroupingOfCarsByCategory(List<Car> cars) {
return cars.stream().collect(Collectors.groupingBy(Car::getCategory));
}
/**
* Method to get all Sedan cars belonging to a group of persons sorted by year of manufacture
*
* Method to get all Sedan cars belonging to a group of persons sorted by year of manufacture.
*
* @param persons {@link List} of {@link Person} to be used
* @return {@link List} of {@link Car} to belonging to the group
*/
public static List<Car> getSedanCarsOwnedSortedByDate(List<Person> persons) {
return persons.stream().map(Person::getCars).flatMap(List::stream)
.filter(car -> Category.SEDAN.equals(car.getCategory()))
.sorted(Comparator.comparing(Car::getYear)).collect(Collectors.toList());
.filter(car -> Category.SEDAN.equals(car.getCategory()))
.sorted(Comparator.comparing(Car::getYear)).collect(Collectors.toList());
}
}

View File

@ -31,23 +31,20 @@ import java.util.List;
import java.util.Map;
/**
* Imperative-style programming to iterate over the list and get the names of
* cars made later than the year 2000. We then sort the models in ascending
* order by year.
*
* Imperative-style programming to iterate over the list and get the names of cars made later than
* the year 2000. We then sort the models in ascending order by year.
*
* <p>As you can see, there's a lot of looping in this code. First, the
* getModelsAfter2000UsingFor method takes a list of cars as its parameter. It
* extracts or filters out cars made after the year 2000, putting them into a
* new list named carsSortedByYear. Next, it sorts that list in ascending order
* by year-of-make. Finally, it loops through the list carsSortedByYear to get
* the model names and returns them in a list.
*
* getModelsAfter2000UsingFor method takes a list of cars as its parameter. It extracts or filters
* out cars made after the year 2000, putting them into a new list named carsSortedByYear. Next, it
* sorts that list in ascending order by year-of-make. Finally, it loops through the list
* carsSortedByYear to get the model names and returns them in a list.
*
* <p>This short example demonstrates what I call the effect of statements. While
* functions and methods in general can be used as expressions, the {@link Collections}
* sort method doesn't return a result. Because it is used as a statement, it
* mutates the list given as argument. Both of the for loops also mutate lists
* as they iterate. Being statements, that's just how these elements work. As a
* result, the code contains unnecessary garbage variables
* functions and methods in general can be used as expressions, the {@link Collections} sort method
* doesn't return a result. Because it is used as a statement, it mutates the list given as
* argument. Both of the for loops also mutate lists as they iterate. Being statements, that's just
* how these elements work. As a result, the code contains unnecessary garbage variables
*/
public class ImperativeProgramming {
private ImperativeProgramming() {
@ -55,6 +52,7 @@ public class ImperativeProgramming {
/**
* Method to return the car models built after year 2000 using for loops.
*
* @param cars {@link List} of {@link Car} to iterate over
* @return {@link List} of {@link String} of car models built after year 2000
*/
@ -80,16 +78,16 @@ public class ImperativeProgramming {
return models;
}
/**
* Method to group cars by category using for loops
*
* Method to group cars by category using for loops.
*
* @param cars {@link List} of {@link Car} to be used for grouping
* @return {@link Map} with category as key and cars belonging to that category as value
*/
public static Map<Category, List<Car>> getGroupingOfCarsByCategory(List<Car> cars) {
Map<Category, List<Car>> groupingByCategory = new HashMap<>();
for (Car car: cars) {
for (Car car : cars) {
if (groupingByCategory.containsKey(car.getCategory())) {
groupingByCategory.get(car.getCategory()).add(car);
} else {
@ -100,33 +98,34 @@ public class ImperativeProgramming {
}
return groupingByCategory;
}
/**
* Method to get all Sedan cars belonging to a group of persons sorted by year of manufacture using for loops
*
* Method to get all Sedan cars belonging to a group of persons sorted by year of manufacture
* using for loops.
*
* @param persons {@link List} of {@link Person} to be used
* @return {@link List} of {@link Car} to belonging to the group
*/
public static List<Car> getSedanCarsOwnedSortedByDate(List<Person> persons) {
List<Car> cars = new ArrayList<>();
for (Person person: persons) {
for (Person person : persons) {
cars.addAll(person.getCars());
}
List<Car> sedanCars = new ArrayList<>();
for (Car car: cars) {
for (Car car : cars) {
if (Category.SEDAN.equals(car.getCategory())) {
sedanCars.add(car);
}
}
sedanCars.sort(new Comparator<Car>() {
@Override
public int compare(Car o1, Car o2) {
return o1.getYear() - o2.getYear();
}
});
return sedanCars;
}
}

View File

@ -33,6 +33,7 @@ public class Person {
/**
* Constructor to create an instance of person.
*
* @param cars the list of cars owned
*/
public Person(List<Car> cars) {

View File

@ -23,14 +23,13 @@
package com.iluwatar.collectionpipeline;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.List;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Tests that Collection Pipeline methods work as expected.
@ -39,35 +38,35 @@ public class AppTest {
private static final Logger LOGGER = LoggerFactory.getLogger(AppTest.class);
private List<Car> cars = CarFactory.createCars();
@Test
public void testGetModelsAfter2000UsingFor() {
var models = ImperativeProgramming.getModelsAfter2000(cars);
assertEquals(List.of("Avenger", "Wrangler", "Focus", "Cascada"), models);
}
@Test
public void testGetModelsAfter2000UsingPipeline() {
var models = FunctionalProgramming.getModelsAfter2000(cars);
assertEquals(List.of("Avenger", "Wrangler", "Focus", "Cascada"), models);
}
@Test
public void testGetGroupingOfCarsByCategory() {
var modelsExpected = Map.of(
Category.CONVERTIBLE, List.of(new Car("Buick", "Cascada", 2016, Category.CONVERTIBLE),
new Car("Chevrolet", "Geo Metro", 1992, Category.CONVERTIBLE)),
Category.SEDAN, List.of(new Car("Dodge", "Avenger", 2010, Category.SEDAN),
new Car("Ford", "Focus", 2012, Category.SEDAN)),
Category.JEEP, List.of(new Car("Jeep", "Wrangler", 2011, Category.JEEP),
new Car("Jeep", "Comanche", 1990, Category.JEEP)));
Category.CONVERTIBLE, List.of(new Car("Buick", "Cascada", 2016, Category.CONVERTIBLE),
new Car("Chevrolet", "Geo Metro", 1992, Category.CONVERTIBLE)),
Category.SEDAN, List.of(new Car("Dodge", "Avenger", 2010, Category.SEDAN),
new Car("Ford", "Focus", 2012, Category.SEDAN)),
Category.JEEP, List.of(new Car("Jeep", "Wrangler", 2011, Category.JEEP),
new Car("Jeep", "Comanche", 1990, Category.JEEP)));
var modelsFunctional = FunctionalProgramming.getGroupingOfCarsByCategory(cars);
var modelsImperative = ImperativeProgramming.getGroupingOfCarsByCategory(cars);
LOGGER.info("Category " + modelsFunctional);
assertEquals(modelsExpected, modelsFunctional);
assertEquals(modelsExpected, modelsImperative);
}
@Test
public void testGetSedanCarsOwnedSortedByDate() {
var john = new Person(cars);