赞
踩
当需要启动一个线程去完成任务时,通常会通过java.lang.Runnable接口来定义任务内容,并使用java.lang.Thread类来启动该线程。
代码如下:
方法一
//自定义一个线程类Thread2
public class TreadT2 implements Runnable {
@Override
public void run() {
for(int i=0;i<10;i++){
//打印当前进程信息
System.out.println(Thread.currentThread().getName()+
" "+i);
}
}
public static void main(String[] args) {
TreadT2 t2 = new TreadT2();
Thread thread = new Thread(t2,“小强”);
Thread thread1 = new Thread(t2,“小李”);
thread.start();
thread1.start();
}
方法二
public static void main(String[] arg){
Runnable runnable = new Runnable() {
@Override
public void run() { System.out.println(Thread.currentThread().getName() + ""); }
};
Thread t=new Thread(runnable);
t.start();
//start()开启线程
}
对于方法二可以用lambda函数简化代码
面向对象的思想:
做一件事,找一个能解决这个事情的对象,调用对象的方法,完成事情
函数式编程的思想:
只要能获得结果,谁去做的,怎么做都不重要,重视的是结果,不重视过程
注意:java中Thread类实现Object类并实现Runnable接口
对于Runnable的匿名内部类用法,可以分析出:
Thread类需要Runnable接口作为参数,其中的抽象run方法是用来指定线程任务内容的核心;
为了省去定义一个RunnableImpl实现类的麻烦,不得不使用匿名内部类;
必须覆盖重写抽象run方法、所有方法名称、方法参数、方法返回值不得再重写一遍;
借助java8的全新语法,匿名内部类写法更简单
public static void main(String[] arg){
new Thread(()->System.out.println(Thread.current.getName()+" ")).satrt();
//启动线程
}
/*
*对比一下
*/
Runnable runnable = new Runnable() {
@Override
public void run() { System.out.println(Thread.currentThread().getName() + ""); }
};
Thread t=new Thread(runnable);
t.start();
//start()开启线程
这段代码和刚才的执行效果是完全一样的,可以在1.8或更高的编译级别下通过。从代码的语义中可以看出:我们启动了一个线程,而线程任务的内容以一种更加简洁的形式被指定。
不再有“不得不创建接口对象”的束缚,不再有“抽象方法覆盖重写”的负担,就是这么简单!
匿名内部类的好处与弊端
一方面,匿名内部类可以帮我们省去实现类的定义;另一方面,匿名内部类的语法——确实太复杂了!
语义分析
仔细分析该代码中的语义,Runnable接口只有一个run方法的定义:
public abstract void run()
;同样的语义体现在Lambda语法中,要更加简单:
() -> System.out.println("**********")
如同Runnable接口还有Comparator(compar抽象方法)和FileFilter(accept抽象方法),
当需要对一个对象数组进行排序时,Arrays.sort方法需要一个java.util.Comparator接口实例来指定排序的规则。假设有一个Person类,含有age、name属性:
public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } }
使用Comparator接口的写法
import java.util.Arrays; import java.util.Comparator; public class MenP { public static void main(String[] args) { // 本来年龄乱序的对象数组 Person[] array = { new Person("古力娜扎", 19), new Person("迪丽热巴", 18), new Person("马尔扎哈", 20) }; // 匿名内部类 Comparator<Person> comp = new Comparator<Person>() { @Override public int compare(Person o1, Person o2) { return o1.getAge() - o2.getAge(); } }; Arrays.sort(array, comp); // 第二个参数为排序规则,即Comparator接口实例 for (Person person : array) { System.out.println(person); } } }
import java.util.Arrays; import java.util.Comparator; public class MenP { public static void main(String[] args) { // 本来年龄乱序的对象数组 Person[] array = { new Person("古力娜扎", 19), new Person("迪丽热巴", 18), new Person("马尔扎哈", 20) }; // 匿名内部类(lambda) Arrays.sort(array, (a,b)->{ return a.getAge()-b.getAge(); }); // 第二个参数为排序规则,即Comparator接口实例 for (Person person : array) { System.out.println(person); } } }
java.io.FilteFilter是个接口,时File的过滤器。该接口的对象可以传递给File类的listFiles(FileFilter)作为参数,接口中只有一个方法boolean accept(File pathname)测试pathname是否应该包含在当前File目录中,符合则返回true。
import java.io.File; import java.io.FileFilter; public class fileFilter { public static void main(String[] args) { File file = new File("E:\\文件\\idea2018\\src"); print(file);//调用自定义方法 } //自定义方法 public static void print(File file){ File[] files = file.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { //判断是Java文件或是目录,是则保存并返回true return pathname.getName().endsWith(".java")||pathname.isDirectory(); } }); //判断如果是文件打印文件路径,否则继续调用print方法 for (File f:files){ if (f.isFile()){ System.out.println("文件名"+f.getAbsolutePath()); }else{ print(f); } } } }
public static void print(File file){ /** * * lambda形式 */ File[] files = file.listFiles(f -> { return f.getName().endsWith(".java") || f.isDirectory(); }); for (File f:files){ if (f.isFile()){ System.out.println("文件名"+f.getAbsolutePath()); }else{ print(f); } } }
在Lambda标准格式的基础上,使用省略写法的规则为:
但是使用时有几个问题需要特别注意:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。