Lamda由便一起推断并帮你转换包装为常规的代码,因此可以用更少的代码实现相同的功能,简洁、难懂、难调试。
Lamdba通过表达式代替功能接口,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以使一个表达式,也可以是代码块)。
Java8 se添加了2个对集合数据进行批量操作的包,Java.util.function包以及java.util.stream包,流(stream)就如同迭代器(Iterator)但是附加了许多额外的功能,总的来说,lamada表达式和stream是自java语言添加泛型(Generics)和注解(annotation)以来最大的变化。
关于List结合的Lamdb表达:
public static void main(String[] args) {
String[] atp = {"Rafael Nadal", "Novak Djokovic",
"Stanislas Wawrinka",
"David Ferrer","Roger Federer",
"Andy Murray","Tomas Berdych",
"Juan Martin Del Potro"};
List<String> players = Arrays.asList(atp);
System.out.println();
// 以前的循环方式
for (String player : players) {
System.out.print(player + "; ");
}
// 使用 lambda 表达式以及函数操作(functional operation)
players.forEach((player) -> System.out.println(player+" ;"));
// 在 Java 8 中使用双冒号操作符(double colon operator)
players.forEach(System.out::println);
}
使用lambda表达式实现Runnable接口:
public static void main(String[] args) {
//原始版本,实现Runnable接口
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Hello world !");
}
}).start();
//1.2使用lamdba expression
new Thread(() -> System.out.println("Hello World")).start();
//2.1使用匿名内部类
Runnable racel=new Runnable() {
@Override
public void run() {
System.out.println("Hello World!");
}
};
//2.2使用Lambda expression
Runnable race2=() ->System.out.println("Hello worls");
//直接调用run方法(没开新线程)
racel.run();
race2.run();
}
Runnable的lambda表达式,使用块格式,将五行代码转换为单行语句,接下来用lambda对集合进行排序。
使用Lambds排序集合:
在Java中。Comparator类被用来排序集合,下面根据球员name,surname,name长度以及最后一个字母,和前面的示例一样,先使用匿名内部类进行排序,在使用lambda表达式精简代码。
//原始版本,实现Runnable接口,Comparator类被用来排序集合:
String[] players = {"Rafael Nadal", "Novak Djokovic",
"Stanislas Wawrinka", "David Ferrer",
"Roger Federer", "Andy Murray",
"Tomas Berdych", "Juan Martin Del Potro",
"Richard Gasquet", "John Isner"};
// 1.1 使用匿名内部类根据 name 排序 players
Arrays.sort(players, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
});
//输出为List集合
List<String> s= Arrays.asList(players);
//两种输出方法
s.forEach(System.out::println);
s.forEach((p)-> System.out.println(p));
//使用lamdba,实现相同功能
//1.2使用lambda expression 排序players
Comparator<String> sortByName=(String s1,String s2) ->(s1.compareTo(s2));
Arrays.sort(players,sortByName);
//1.3也可以采用一下形式
Arrays.sort(players,(String s1,String s2)->(s1.compareTo(s2)));
//Lamdba一些排序
// 1.1 使用匿名内部surname排序players
Arrays.sort(players, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return (s1.substring(s1.indexOf(" ")).compareTo(s2.substring(s2.indexOf(" "))));
}
});
//1.2使用lambda expression排序,根据surname
Comparator<String> sortBySurname=(String s1,String s2) ->(s1.substring(s1.indexOf(" ")).compareTo(s1.substring(s2.indexOf(" "))));
Arrays.sort(players,sortBySurname);
//1.3或者
Arrays.sort(players,(String s1,String s2)->
(s1.substring(s1.indexOf(" ")).compareTo(s2.substring(s2.indexOf(" ")))));
//2.1使用匿名内部类根据name length进行排序players
Arrays.sort(players, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return (o1.length()-o2.length());
}
});
//使用lambda expression排序 name length
Comparator<String> sortByNameLength=(String s1,String s2)->(s1.length()-s2.length());
Arrays.sort(players,sortByNameLength);
//2.3 or this
Arrays.sort(players,(String s1,String s2)-> (s1.length()-s2.length()));
//使用匿名内部类排序surname,根据最后一个字母
Arrays.sort(players, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return (o1.charAt(o1.length()-1)- o2.charAt(o2.length()-1));
}
});
//3.2使用lamdba expression 表达式,根据最后一个字母
Comparator<String > sortByLastLetter=
(String s1,String s2)->
(s1.charAt(s1.length()-1)-s2.charAt(s2.length()-1);
Arrays.sort(players,sortByLastLetter);
//or this
Arrays.sort(players,(String s1,String s2)->(s1.charAt(s1.length()-1)-s2.charAt(s2.length()-1)));
}
使用Lambda 和Streams
Stream是对集合的包装,通常和lambda一起使用。使用lambda表达式支持许多操作,如:map、filter、limit、sorted、count、min、max、sum、collect,同样stream使用懒运算,并不会真正的读取所有数据,遇到像getFirest()这样的方法就会结束链式语法,stream配合lambda进行流操作。
List<User> userList=new ArrayList<User>(){
{
add(new User("1", "1584011@qq.com", "123123"));
add(new User("2", "1584011@qq.com", "123123"));
add(new User("3", "1584011@qq.com", "123123"));
add(new User("4", "1584011@qq.com", "123123"));
add(new User("5", "1584011@qq.com", "123123"));
add(new User("6", "1584011@qq.com", "123123"));
}
};
System.out.println("所有程序员姓名:");
userList.forEach((p)->System.out.printf("%s ",p.getName()));
Consumer<User> giveRaise=e->e.setPhone("121");
userList.forEach(giveRaise);
userList.forEach(System.out::println);
另一个有用的方法是过滤器filter(),以下是杂七杂八的demo,看不懂没关系,可以用逻辑关系推测。
public static void main(String[] args) {
//原始版本,实现Runnable接口,Comparator类被用来排序集合
String[] players = {"Rafael Nadal", "Novak Djokovic",
"Stanislas Wawrinka", "David Ferrer",
"Roger Federer", "Andy Murray",
"Tomas Berdych", "Juan Martin Del Potro",
"Richard Gasquet", "John Isner"};
List<User> userList=new ArrayList<User>(){
{
add(new User("名字1", "1584011@qq.com", "123123"));
add(new User("下例子", "1584011@qq.com", "123123"));
add(new User("数", "1584011@qq.com", "123123"));
add(new User("", "1584011@qq.com", "123123"));
add(new User("名字1", "1584011@qq.com", "123123"));
add(new User("名字1", "1584011@qq.com", "123123"));
}
};
System.out.println("所有程序员姓名:");
userList.forEach((p)->System.out.printf("%s ",p.getName()));
Consumer<User> giveRaise=e->e.setPhone("18372828323");//设置phone
userList.forEach(giveRaise);
userList.forEach(System.out::println);
//定义过滤器:
Predicate<User> ageFilter=(p) ->(!p.getName().equals("小张"));//姓名过滤器
Predicate<User> emailFilter=(p) ->(!p.getEmail().equals("1212.qq.com"));//邮件过滤器
Predicate<User> phoneFilter=(p) ->(!p.getPhone().equals("123123"));//手机号过滤器
System.out.println("name等于1的:");
userList.stream()
.filter(ageFilter)
.filter(emailFilter)
.filter(phoneFilter)
.forEach((p1)-> System.out.printf("%s %s", p1.getEmail(),p1.getPhone()));
//重用filters
System.out.println("年龄过滤加性别过滤");
userList.stream()
.filter(ageFilter)
.filter(phoneFilter)
.forEach((p)-> System.out.printf("%s %s",p.getEmail(),p.getName()));
//limit方法,可以限制结果集的个数
//最前面的3个
userList.stream()
.limit(3)
.forEach((p)-> System.out.printf("%s %s",p.getPhone(),p.getName()));
System.out.println("按年龄划分,最前面的三个");
userList.stream()
.filter(ageFilter)
.limit(3)
.forEach((p)-> System.out.printf("%s %s",p.getName(),p.getPhone()));
System.out.println("name排序,并显示前5个");
List<User> sortedProgrammer=userList.stream()
.sorted((p,p2)->(p.getName().compareTo(p2.getName())))
.limit(5)
.collect(Collectors.toList());
sortedProgrammer.forEach((p)-> System.out.printf("%s %s",p.getName(),p.getPhone()));
System.out.println("根据name排序");
sortedProgrammer=userList.stream()
.sorted((p1,p2)->(p1.getName().compareTo(p2.getName())))
.collect(Collectors.toList());
sortedProgrammer.forEach((p)-> System.out.printf("%s %s",p.getName(),p.getEmail()));
//对最高最低感兴趣
User user=userList.stream()
.min((p1,p2)->((int) (p1.getId()-p2.getId())))
.get();
System.out.printf("Name: %s %s",user.getEmail(),user.getName());
//上面例子看到collect是如何工作的。结合map方法,我们可以使用collect方法将我们的结果集放到放到一个字符串、set、TreesSet中
System.out.println("");
//最低最高薪水
//工资最低的Java programmer
User user1=userList.stream()
.min((p1,p2)->((int)(p1.getId()-p2.getId())))
.get();
System.out.printf("%s %s",user1.getName(),user1.getEmail());
//工资最高
User user2=userList.stream()
.max((p1,p2)->((int)(p1.getId()-p2.getId())))
.get();
//将PHP programmer的name 拼接成字符串
String developer=userList.stream()
.map(User::getName)
.collect(Collectors.joining(" ;"));
//Java programers 的firstname存放到Set集合
Set<String> javaDevFirstName=userList.stream()
.map(User::getEmail)
.collect(Collectors.toSet());
//将Java programers的first name 存放到Treeset
TreeSet<String> javaDevLastName=userList.stream()
.map(User::getEmail)
.collect(Collectors.toCollection(TreeSet::new));
//Streams可以做并行(parallel)
int totalSalary=userList.parallelStream()
.mapToInt(p->(int)p.getId())
.sum();
//使用summaryStatistics 方法获得stream中元素的各个汇总数据。计算count min max sum and average
List<Integer> numbers=Arrays.asList(1,23,234,234,23,423,4,32);
IntSummaryStatistics stats=numbers
.stream()
.mapToInt((x)->x)
.summaryStatistics();
System.out.println("最小数字:"+stats.getMin());
System.out.println("最大数字:"+stats.getMax());
System.out.println("平均数字:"+stats.getAverage());
System.out.println("总和:"+stats.getSum());
File mydir=new File("/home/user/files");
if (mydir.isDirectory()){
File[] files=mydir.listFiles(
new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.isFile();
}
}
);
}
//lamdba实现
if (mydir.isDirectory()){
File[] files=mydir.listFiles(
(File f)->{return f.isFile();}
);
}
File[] files=mydir.listFiles(File::isFile);
}