Java 8引入了Lambda表达式和Type Annotations.
使用类型注释,可以定义Java注释,如下所示:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE_USE)
public @interface MyTypeAnnotation {
public String value();
}
Run Code Online (Sandbox Code Playgroud)
然后可以在任何类型引用上使用此注释,例如:
Consumer<String> consumer = new @MyTypeAnnotation("Hello ") Consumer<String>() {
@Override
public void accept(String str) {
System.out.println(str);
}
};
Run Code Online (Sandbox Code Playgroud)
这是一个完整的例子,它使用这个注释来打印"Hello World":
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.AnnotatedType;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
public class Java8Example {
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE_USE)
public @interface MyTypeAnnotation {
public String value();
}
public static void main(String[] args) {
List<String> list = Arrays.asList("World!", "Type Annotations!"); …Run Code Online (Sandbox Code Playgroud) 我想用Lambda对列表进行排序:
List<Message> messagesByDeviceType = new ArrayList<Message>();
messagesByDeviceType.sort((Message o1, Message o2)->o1.getTime()-o2.getTime());
Run Code Online (Sandbox Code Playgroud)
但是我得到了这个编译错误:
Multiple markers at this line
- Type mismatch: cannot convert from long to int
- The method sort(Comparator<? super Message>) in the type List<Message> is not applicable for the arguments ((Message o1, Message o2)
-> {})
Run Code Online (Sandbox Code Playgroud) 我想知道lambdas在Java 8中有多大的好处.我同意有时使用lambdas可能更具可读性,但是它对性能方面有多大影响吗?或者主要是作为语法糖?我有时喜欢匿名的内部课程; 当我不经常使用lambda时,我真的会失去很多好处吗?
唯一的?大?在我看来,性能增益是我们实际上并没有创建类加载器必须在程序开始时加载的类 - 例如创建许多线程:
Thread t = new Thread(new Runnable() {
public.....
});
Run Code Online (Sandbox Code Playgroud)
创建类似的类Sample$1.class.
除此之外,除了代码的可读性或可维护性等之外,还有任何性能或其他隐藏的收益吗?隐藏在JVM的某个地方?我已经看到了类似的问题,但大多数都集中在视觉方面; 我对此不感兴趣.在观看使用Venkat Subramaniam的Java 8 Lambdas Hacking之后,问题出于好奇.
我正在阅读《Effective Java》,想知道lambda和之间的区别anonymous class。我知道 lambda 只能与具有单一方法的接口(即功能接口)一起使用,并且在 lambda 中您无法获取对其自身的引用,因此this当在匿名类关键字this与匿名类的主体相关时,关键字与指定 lambda 的类相关。但我不知道 lambda 到底是什么。我猜这只是一个创建实现函数式接口的匿名类实例的表达式,因此与普通匿名类相比,这只是带有一些限制的语法糖,但多亏了它,我们可以摆脱样板文件并使我们的代码更具可读性。另一方面,我们可以在这里阅读有关性能差异的信息,这表明 lambda 实际上不是实现函数接口的匿名类的实例。
我正在阅读Richard Warburton的Java 8 Lambdas一书中的lambdas.他开始在现代CPU中使用并发性进行讨论,并最终将它与lambdas相关联.我不知道我错过了什么,但我肯定没有得到这个概念.考虑以下课程
class A {
private int state;
A(){
state = 0;
}
A(int state){
this.state = state;
}
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
@Override
public String toString() {
return Integer.toString(state);
}
} // end A
public class Main {
public static void main(String[] args) {
List<A> ls = new ArrayList<>();
ls.add(new A(2));
ls.add(new A(3));
ls.forEach( a -> a.setState(a.getState() + 1) );
System.out.println(ls); …Run Code Online (Sandbox Code Playgroud) 当使用下面的匿名类时,我们调用的变量x没有问题
interface Age {
int x = 21;
void getAge();
}
class AnonymousDemo {
public static void main(String[] args) {
Age oj1 = new Age() {
@Override
public void getAge() {
// printing age
System.out.print("Age is "+x);
}
};
oj1.getAge();
}
}
Run Code Online (Sandbox Code Playgroud)
但是当我使用下面的 lambda 表达式相同的代码时,出现了异常:
interface Age {
int x = 21;
void getAge();
}
class AnonymousDemo {
public static void main(String[] args) {
Age oj1 = () -> { System.out.print("Age is "+x); };
oj1.getAge();
}
}
Run Code Online (Sandbox Code Playgroud)
这里会出现什么问题呢?知道lambda表达式只是实现匿名类的缩写。
在关于lambda和匿名类之间差异的一个论点中,在这篇文章中:
我读了一个声称"Lambdas可以拥有状态",就像匿名类实例一样.
据我所知,你不能添加专属于lambda的用户定义状态,因为没有办法在java lambda函数的实现上定义实例成员.
例如:
Runnable r= () -> { int x = 5; }; // defines a local - no way to define instance
Runnable r2 = new Runnable() {
int x; // defines state via instance member
@Override
public void run() {
// TODO Auto-generated method stub
}
};
Run Code Online (Sandbox Code Playgroud)
只是为了澄清,我并不是想将状态引入lambda,因为我认为这违背了意图.我只是想验证或反驳上述堆栈溢出问题上由信誉良好的来源做出的技术性声明.
因此,我中的函数程序员喜欢像python这样的语言,它们将函数视为一等公民。看起来Java 8承受了压力,而诸如lambda表达式和方法引用之类的“已实现的”东西则被淘汰了。
我的问题是,Java是否正在使用一流的函数,或者这真的只是语法糖,以减少实现匿名类/接口(如可运行的接口)所需的代码量?(我的肠子说后者)。
我理想的情况
Map<String,DoubleToDoubleFunc> mymap = new HashMap<String,DoubleToDoubleFunc>();
...
mymap.put("Func 1", (double a, double b) -> a + b);
mymap.put("Func 2", Math::pow);
...
w = mymap.get("Func 1")(y,z);
x = mymap.get("Func 2")(y,z);
Run Code Online (Sandbox Code Playgroud)