table of Contents
-
- table of Contents
- Preface
- Test chopper: Screening of green apple
- And then show their skills: the color as a parameter
- Third try: For each property you want to do screening
- Parameterized behavior
- According to the abstract screening conditions
- Anonymous inner classes
- Use Lambda Expressions
- The List abstract type
- summary
Preface
Java8 contact with for some time, found that this stuff is really good, many large companies are using cattle, I bought a book "Java8 combat", read some of the contents of the book do some study notes.
Test chopper: Screening of green apple
The first problem may be solved like this:
public static List<Apple> filterGreenApples(List<Apple> inventory){
List<Apple> result = new ArrayList<Apple>();
for(Apple apple: inventory){
if("greeen".equals(apple.getColour())){
result.add(apple);
}
}
return result;
}
The above is for us to filter out Green Apple program, demand is constantly changing thing! Farmers now changed my mind, Apple wants to filter out other colors such as light green, dark red, yellow and so on. Our first thought is that it is abstract.
And then show their skills: the color as a parameter
When requirements change, our first thought is to color as a parameter, then the flexibility to adapt to change:
public static List<Apple> filterGreenApples(List<Apple> inventory, String colour){
List<Apple> result = new ArrayList<Apple>();
for(Apple apple: inventory){
if(colour.equals(apple.getColour())){
result.add(apple);
}
}
return result;
}
This time can be screened by the color of it to meet the requirements of Apple, now the farmers need to filter out the apple weighing more than 150g, which is how to achieve it? You might think this is implemented:
public static List<Apple> filterGreenApples(List<Apple> inventory, long weight){
List<Apple> result = new ArrayList<Apple>();
for(Apple apple: inventory){
if(apple.getWeight() > weight){
result.add(apple);
}
}
return result;
}
Such indeed meet the demand, but copied a lot of code, does not meet the principles of software engineering, then you can increase the way a flag to distinguish color and weight of the inquiry. So you think this in the following way:
Third try: For each property you want to do screening
public static List<Apple> filterGreenApples(List<Apple> inventory, String colour, long weight, boolean flag){
List<Apple> result = new ArrayList<Apple>();
for(Apple apple: inventory){
if((flag&&apple.getWeight() > weight)||
(!flag&&apple.getColour().equals(colour))){
result.add(apple);
}
}
return result;
}
So you can control the screening of two properties by a method that is not feeling very witty? But it makes the program look very clumsy, if farmers need to filter out the size, shape, origin. How to do it? In the next section, we will use parameterized behavior to achieve this flexibility.
Parameterized behavior
Our first thought is given to the selection of an interface standard for modeling:
interface ApplePredicate{
boolean test(Apple apple);
}
class AppleHeavyWeightPredicate implements ApplePredicate{
public boolean test(Apple apple) {
return apple.getWeight() >150;
}
}
class AppleGreenColorPredicate implements ApplePredicate{
public boolean test(Apple apple) {
return "green".equals(apple.getColour());
}
}
Operation and above "strategy design pattern" relevant done, so that a method of receiving a variety of behavior as a parameter, and is used internally to perform different actions.
According to the abstract screening conditions
public class GreenApple {
public static List<Apple> filterApples(List<Apple> inventory, ApplePredicate p){
ArrayList<Apple> result = new ArrayList<>();
for(Apple apple: inventory){
if(p.test(apple)){
result.add(apple);
}
}
return result;
}
public static class AppleRedAndHeavyPredicate implements ApplePredicate{
@Override
public boolean test(Apple apple) {
return "red".equals(apple.getColour())&&apple.getWeight() > 150;
}
}
public static void main(String[] args) {
Apple apple = new Apple();
apple.setColour("green");
apple.setWeight(12);
Apple apple2 = new Apple();
apple2.setColour("red");
apple2.setWeight(288);
ArrayList<Apple> inventory = new ArrayList<Apple>();
inventory.add(apple);
inventory.add(apple2);
List<Apple> apples = GreenApple.filterApples(inventory, new AppleRedAndHeavyPredicate());
}
}
In this way, farmers simply create a class that implements the interface ApplePredicate on the line, you can define the rules you want to filter in this class there, so that you can conduct a parametric method filterApples.
Anonymous inner classes
List<Apple> redApples = filterApples(inventory, new ApplePredicate() {
@Override
public boolean test(Apple apple) {
return "red".equals(apple.getColour());
}
});
While this can be, but the program will significantly awkward
Use Lambda Expressions
Lambda expressions make use of the program looks very clean and tidy
List<Apple> result=filterApples(inventory,(Apple apple1) ->"red".equals(apple1.getColour()));
Apple may even omit the type, because it is only one way
List<Apple> result=filterApples(inventory,apple1 ->"red".equals(apple1.getColour()));
The List abstract type
On your way to the abstract, in fact, we can do better! You can List abstract type, which go beyond the issue you want to deal with the current
List<Apple> redApple = filter(inventory, (Apple apple) -> "red".equals(apple.getColour()));
List<String> str = filter(numbers, (Integer i) -> i % 2 == 0);
public static <T>List<T> filter(List<T> list, Predicate<T> p){
List<T> result = new ArrayList<>();
for(T e:list){
if(p.test(e)){
result.add(e);
}
}
return result;
}
summary
Behavioral parameters of: is a method of receiving a plurality of different behaviors as a parameter, and use them internally, the ability to perform different behaviors
transmission codes : a new behavior is to a method to pass parameters