之前技术博客都是在CSDN上发表的,好久没用了,登录上去居然有人给我以前的博客点赞评论,尽管很少但发现还是有人看的。看了一下之前写的博客,发现不是一般的烂,不知道对于他们是不是一种浪费时间的行为🤣。
最近查询问题/解决bug,发现CSDN很多博客质量不太高(包括我的),有好的博客但是真的要筛选看过几篇后才能看到好的,而且前面浪费时间浏览的几篇有些基本是抄袭的。所以还是下定决心好好写博客,不必高产,但每一篇应该认真写。自己总结学习,也尽力让有缘看到自己博客的同学有所得,而不是内心想着:这又是一篇垃圾博客🌚。
Lambda表达式
使用
Runnable接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
// Runnable接口的匿名内部类
// Use in Java 7 or earlier:
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("inside runnable using anonymous inner class");
}
}).start();
// Thread构造函数中使用lambda表达式
new Thread(() -> System.out.println("inside runnable using a lambda")).start();
// 将lambda表达式赋给变量
Runnable r = () -> System.out.println("using a lambda as a variable");
new Thread(r).start();
|
FilenameFilter接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
File dir = new File("src/main/java");
String[] names = dir.list();
System.out.println(Arrays.asList(names));
// FilenameFilter的匿名内部类实现
// Using anonymous inner class
names = dir.list(new FilenameFilter() {
@Override
public boolean accept(File directory, String name) {
return name.endsWith(".java");
}
});
System.out.println(Arrays.asList(names));
// FilenameFilter接口的lambda表达式实现
// Use a lambda expression
names = dir.list((dr, name) -> name.endsWith(".java"));
System.out.println(Arrays.asList(names));
// 具有显式数据类型的lambda表达式
names = dir.list((File dr, String name) -> name.endsWith(".java"));
System.out.println(Arrays.asList(names));
// lambda代码块(block lambda)
// Notice:不能省略return关键字
names = dir.list((File dr, String name) -> {
return name.endsWith(".java");
});
System.out.println(Arrays.asList(names));
Arrays.asList(names).forEach(System.out::println);
names = dir.list(new MyFilter());
System.out.println(Arrays.asList(names));
|
MyFilter.java
1
2
3
4
5
6
|
public class MyFilter implements FilenameFilter {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".java");
}
}
|
lambda 表达式在任何情况下都不能脱离上下文存在,上下文指定了将表达式赋给哪个函数式接口。
lambda 表达式可以是:
1、方法的参数
2、方法的返回类型
3、引用
无论哪种情况,赋值类型必须为函数式接口。
函数式接口:
Runnable.java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
package java.lang;
/**
* The {@code Runnable} interface should be implemented by any
* class whose instances are intended to be executed by a thread. The
* class must define a method of no arguments called {@code run}.
* <p>
* This interface is designed to provide a common protocol for objects that
* wish to execute code while they are active. For example,
* {@code Runnable} is implemented by class {@code Thread}.
* Being active simply means that a thread has been started and has not
* yet been stopped.
* <p>
* In addition, {@code Runnable} provides the means for a class to be
* active while not subclassing {@code Thread}. A class that implements
* {@code Runnable} can run without subclassing {@code Thread}
* by instantiating a {@code Thread} instance and passing itself in
* as the target. In most cases, the {@code Runnable} interface should
* be used if you are only planning to override the {@code run()}
* method and no other {@code Thread} methods.
* This is important because classes should not be subclassed
* unless the programmer intends on modifying or enhancing the fundamental
* behavior of the class.
*
* @author Arthur van Hoff
* @see java.lang.Thread
* @see java.util.concurrent.Callable
* @since 1.0
*/
@FunctionalInterface
public interface Runnable {
/**
* When an object implementing interface {@code Runnable} is used
* to create a thread, starting the thread causes the object's
* {@code run} method to be called in that separately executing
* thread.
* <p>
* The general contract of the method {@code run} is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
*/
public abstract void run();
}
|
从源码中可以看到:
In most cases, the {@code Runnable} interface should be used if you are only planning to override the {@code run()} method and no other {@code Thread} methods. This is important because classes should not be subclassed unless the programmer intends on modifying or enhancing the fundamental behavior of the class.
这也说明了应该面向接口编程,多用接口,而不是继承。
Callable.java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
package java.util.concurrent;
/**
* A task that returns a result and may throw an exception.
* Implementors define a single method with no arguments called
* {@code call}.
*
* <p>The {@code Callable} interface is similar to {@link
* java.lang.Runnable}, in that both are designed for classes whose
* instances are potentially executed by another thread. A
* {@code Runnable}, however, does not return a result and cannot
* throw a checked exception.
*
* <p>The {@link Executors} class contains utility methods to
* convert from other common forms to {@code Callable} classes.
*
* @see Executor
* @since 1.5
* @author Doug Lea
* @param <V> the result type of method {@code call}
*/
@FunctionalInterface
public interface Callable<V> {
/**
* Computes a result, or throws an exception if unable to do so.
*
* @return computed result
* @throws Exception if unable to compute a result
*/
V call() throws Exception;
}
|
可以看到:
The {@code Callable} interface is similar to {@link java.lang.Runnable}, in that both are designed for classes whose instances are potentially executed by another thread. A {@code Runnable}, however, does not return a result and cannot throw a checked exception.
说明了Runnable和Callable的异同点。
Runnable是在package java.lang中,Callable是在package java.util.concurrent中;
Java中只有java.lang
包下的类可以直接使用,不需要导入。
同时,从Runnable.java
和Callable.java
都可以看到@FunctionalInterface
注解。
FunctionalInterface.java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
package java.lang;
import java.lang.annotation.*;
/**
* An informative annotation type used to indicate that an interface
* type declaration is intended to be a <i>functional interface</i> as
* defined by the Java Language Specification.
*
* Conceptually, a functional interface has exactly one abstract
* method. Since {@linkplain java.lang.reflect.Method#isDefault()
* default methods} have an implementation, they are not abstract. If
* an interface declares an abstract method overriding one of the
* public methods of {@code java.lang.Object}, that also does
* <em>not</em> count toward the interface's abstract method count
* since any implementation of the interface will have an
* implementation from {@code java.lang.Object} or elsewhere.
*
* <p>Note that instances of functional interfaces can be created with
* lambda expressions, method references, or constructor references.
*
* <p>If a type is annotated with this annotation type, compilers are
* required to generate an error message unless:
*
* <ul>
* <li> The type is an interface type and not an annotation type, enum, or class.
* <li> The annotated type satisfies the requirements of a functional interface.
* </ul>
*
* <p>However, the compiler will treat any interface meeting the
* definition of a functional interface as a functional interface
* regardless of whether or not a {@code FunctionalInterface}
* annotation is present on the interface declaration.
*
* @jls 4.3.2 The Class Object
* @jls 9.8 Functional Interfaces
* @jls 9.4.3 Interface Method Body
* @jls 9.6.4.9 @FunctionalInterface
* @since 1.8
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface {}
|
可以看到:
Note that instances of functional interfaces can be created with lambda expressions, method references, or constructor references.
函数式接口的实例可以使用lambda表达式,方法引用或构造函数引用创建。
从源码中也可以看到Java文档注释(doc comment)
相关内容。
1、用于编写代码API的文档。
2、是普通的多行注释,以/**
开头,以*/
结尾。(通常使用的多行注释是以/*
开头,以*/
结尾)
3、通过阅读就可以明白:
- @author显示为Author
- @see显示为See Also
- @since显示为Since
标签太多一次记不过来,每次学几个就会轻松很多。
4、可以包含简单的HTML标签:
1
2
3
4
5
6
|
<i> 强调
<code> 显示类、方法和字段的名称
<p> 将说明分成很多段落
<ul> <li> 显示无序列表
但是不能包含HTML主结构标签,例如<h2> <hr>
(因为编写的内容会被嵌入复杂的大型HTML文档,以免影响大型HTML文档的结构)
|
发现源码就是最可靠的文档,从源码中还可以学习代码书写、注释书写。
Author
Anjana
LastMod
2022-03-12
License
原创文章,如需转载请注明作者和出处。谢谢!