I won't write the syntax part, let's just raise a practical question to see what conveniences these new features of java8 can bring to us.
By the way, some generic programming is used, everything is to simplify the code
Scene:
A data class that records employee information
public class Employee { public String name; public int age; public char sex; public String time; public int salary;}We have a column of this type of data
List<Employee> data = Arrays.asList(e1,e2,e3......)
There is a need now: Group employees Employees by the initial letter of their names (assuming they are all English names):
Then the result we want to get should be a mapping relationship like Map:char -> List<Employee>
public static Map<Character, List<Employee>> groupByFirstChar( List<Employee> data){ Map<Character, List<Employee>> result = new HashMap<>(); for(Employee e : data){ Character c = e.name.charAt(0); List<Employee> l = result.get(c); if(l == null){ l = new ArrayList<>(); result.put(c, l); } l.add(e); } return result;}The code is not complicated and can be completed soon. The boss sees that you are so efficient, so he said that you will divide it into groups according to your salary, for those below 5,000, 5,000~10,000... etc.
It won't be too difficult, just change the key and process it a little logically
public static Map<String, List<Employee>> groupBySalary(List<Employee> data) { Map<String, List<Employee>> result = new HashMap<>(); for (Employee e : data) { String key = separate(e.salary); List<Employee> l = result.get(key); if (l == null) { l = new ArrayList<>(); result.put(key, l); } l.add(e); } return result;<br>}private static String separate(int salary) { if (salary <= 5000) { return "less than 5000"; } if (salary <= 10000) { return "5000~10000"; } if (salary <= 20000) { return "10000~20000"; } return "above 20000"}Then the boss said again, let’s divide the employees into groups according to their year of employment. . .
I won't write the code here. If you compare it, you will find that no matter how you group it, the only change is the way to select the key value.
The first letter of Employee's name is used as the key for the first time:
Employee e -> e.name.charAt(0)
The second time I convert the Employee's salary into String as key according to the method separat:
Employee e -> separate(e.salary):String
And so on
Employee e -> getYear(e.time):String
In fact, the first time you can also write the first letter into a single method.
Employee e -> getFirstChar(e.name):Character
In order to look more beautiful, we can say that the parameters of the three methods are set to Employee. The method body is not written. Only the parameters and return values are listed here.
Employee e -> getFirstChar(e) : CharacterEmployee e -> separate(e) : StringEmployee e -> getYear(e) : String
The left side of -> is the parameter, the right side of: is the return value, and the right side of -> is the signature of the method
Then we will naturally think of extracting the changed part as parameters and other unchanged parts as method bodies, so we can omit the duplicate code. Obviously, the changed part is the method listed above, which converts Employee e into key, but we know that Java cannot pass methods as parameters. However, this is not a problem for programmers with a little experience. We can use interfaces to achieve our goals, and at the same time we will encounter another problem. The return values of the above three methods are different, so we need to use generics:
public static <K> Map<K, List<Employee>> groupByKey(List<Employee> data, GetKey<K> getKey){ Map<K, List<Employee>> result = new HashMap<>(); for(Employee e : data) { K key = getKey.getKey(e); List<Employee> l = result.get(key); if (l == null) { l = new ArrayList<>(); result.put(key, l); } l.add(e); } return result;}interface GetKey<K>{ K getKey(Employee e);}Then the first requirement above can be realized in this way
Map<Character, List<Employee>> result = groupByKey(data, new GetKey<Character>() { @Override public Character getKey(Employee e) { e.name.charAt(0); } });The second requirement
Map<String, List<Employee>> result = groupByKey(list, new GetKey<String>() { @Override public String getKey(Employee e) { separate(e.salary); } });It can be found that we only need to change the generic parameters and the implementation of anonymous internal classes. The only problem is that it is not very realistic, and many routine codes are especially reflected in anonymous internal classes.
In fact, we only care about the parameters and return values of this anonymous inner class, and the rest are just syntax requirements.
java8 just happens to provide us with a good way to avoid complicated routines: lambda expressions, the above implementation can be written as
Map<Character, List<Employee>> resultByFirstChar = groupByKey(list, e -> e.name.charAt(0));Map<String, List<Employee>> resultBySalary = groupByKey(list, e -> separate(e.salary));
Lambda expressions only show what we care about, parameters and return values. At the same time, due to type inference, parameter types can be omitted. The specific syntax will not be introduced here. A lot of information can be found on the Internet
extra:
If you have a good understanding of generics, the method groupByKey can be further abstracted:
public static <K, E> Map<K, List<E>> groupBy(List<? extends E> data, Function<? super E, ? extends K> fun) { Map<K, List<E>> result = new HashMap<>(); for(E e : data) { K k = fun.apply(e);<br> List<E> l = result.get(k); if(l == null) { l = new ArrayList<>(); result.put(k, l); } l.add(e); } return result;<br> }We have also extracted the Employee class, and the benefits are obvious
Function interface is a newly added interface to Java8:
@FunctionalInterfacepublic interface Function<T, R> { R apply(T t);}Enter a T type to return to R type. The combination of generics and functional programming is very good. Although the new features of java8 have been criticized by various kinds of complaints, it is always good to bring benefits, which gives us more choices.
If you have time, I will introduce stream, another great tool for Java8
The above is the application of lambda expressions in Java 8 and some generic related knowledge introduced to you by the editor. I hope it will be helpful to you. If you have any questions, please leave me a message and the editor will reply to you in time. Thank you very much for your support to Wulin.com website!