我想在没有if语句的情况下实现惰性字段初始化(或延迟初始化)并利用lambdas.所以,我想具有以下Foo属性的相同行为,但没有if:
class A<T>{
private T fooField;
public T getFoo(){
if( fooField == null ) fooField = expensiveInit();
return fooField;
}
}
Run Code Online (Sandbox Code Playgroud)
忽略这个解决方案不能保证安全使用的事实:1)多线程; 2)null作为有效值T.
因此,为了表达初始化fooField被推迟到第一次使用的意图,我想声明fooField类型Supplier<T>如下:
class A<T>{
private Supplier<T> fooField = () -> expensiveInit();
public T getFoo(){
return fooField.get();
}
}
Run Code Online (Sandbox Code Playgroud)
然后在getFoo财产中我会回来fooField.get().但是现在我想要对getFoo属性的下一次调用避免expensiveInit()并且只返回前一个T实例.
如何在不使用的情况下实现这一目标if?
尽管命名约定并替换了->by =>,但是这个例子也可以在C#中考虑.但是,.NET Framework版本4已经提供了Lazy<T>所需的语义.
完成这项工作的最简洁方法是什么?
class AnObject{
Long attr;
}
List<AnObject> list;
Run Code Online (Sandbox Code Playgroud)
我知道可以使用AnObject的自定义比较器来完成.对于这种情况,是不是有一些现成的东西?的种类
Collections.sort(list, X.attr ) ;
Run Code Online (Sandbox Code Playgroud) 我正在观看关于Java的演讲,有一次,讲师说:
"可变性是可以的,分享是好的,共享的可变性是魔鬼的工作."
他所指的是以下一段代码,他认为这是一种"极其糟糕的习惯":
//double the even values and put that into a list.
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 1, 2, 3, 4, 5);
List<Integer> doubleOfEven = new ArrayList<>();
numbers.stream()
.filter(e -> e % 2 == 0)
.map(e -> e * 2)
.forEach(e -> doubleOfEven.add(e));
Run Code Online (Sandbox Code Playgroud)
然后他继续编写应该使用的代码,即:
List<Integer> doubleOfEven2 =
numbers.stream()
.filter(e -> e % 2 == 0)
.map(e -> e * 2)
.collect(toList());
Run Code Online (Sandbox Code Playgroud)
我不明白为什么第一段代码是"坏习惯".对我而言,他们都达到了同样的目标.
阅读Java 8从lambdas中产生的字节码类型,我想起了Java 5发布的时候.当时有Retroweaver和其他工具用于转换用JDK 5编译的字节码以在JRE 1.4上运行.
还有人为Java 8 lambdas创建了这样一个后向移植工具吗?它将让Java开发人员今天开始在生产质量的Java 7 JRE上使用lambdas,而不必等待6到12个月的Java 8 GA版本.
以下是我对后向传递器应该相对容易实现的原因的分析:
Java 8 lambdas似乎没有使用Java 7不具备的任何JVM功能(例如invokedynamic),并且java.lang.invoke.LambdaMetafactory该类及其依赖项看起来像纯Java,因此应该可以在第三方库中实现它们.因此,使用JDK 8编译的字节码可以通过添加带有LambdaMetafactory副本的第三方库(在不同的包下)并通过转换字节码来使用该元数据来在JRE 7上运行.也许还会生成一些合成类和方法来绕过可访问性检查,这java.lang.invoke.MagicLambdaImpl似乎意味着.或者为所有lambdas生成匿名内部类,就像一些支持lambda的早期访问JDK一样.
只是在Java 8中使用新的lambda和功能特性,我不知道如何做到这一点.
例如,以下内容有效:
Map<String, Integer> map = new HashMap<>();
map.put("A", 1);
map.put("B", 2);
map.put("C", 3);
map.compute("A", (k, v) -> v == null ? 42 : v + 41));
Run Code Online (Sandbox Code Playgroud)
但以下给出了语法错误:
BiFunction x = (k, v) -> v == null ? 42 : v + 41;
map.compute("A", x);
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
在Java 8中,三个内存屏障指令被添加到Unsafe类(源):
/**
* Ensures lack of reordering of loads before the fence
* with loads or stores after the fence.
*/
void loadFence();
/**
* Ensures lack of reordering of stores before the fence
* with loads or stores after the fence.
*/
void storeFence();
/**
* Ensures lack of reordering of loads or stores before the fence
* with loads or stores after the fence.
*/
void fullFence();
Run Code Online (Sandbox Code Playgroud)
如果我们用以下方式定义内存屏障(我认为或多或少容易理解):
考虑X和Y是要重新排序的操作类型/类,
X_YFence()是一个内存屏障指令,它确保在屏障启动之后,在屏障完成任何操作之前,屏障之前的所有类型X操作都已完成.
我们现在可以将障碍名称"映射" Unsafe …
我正在尝试对Map对象中的每个条目执行映射操作.
我需要从键中取一个前缀并将值从一种类型转换为另一种类型.我的代码从a获取配置条目Map<String, String>并转换为a Map<String, AttributeType>(AttributeType只是一个包含一些信息的类.进一步的解释与此问题无关.)
我能够使用Java 8 Streams获得的最佳结果如下:
private Map<String, AttributeType> mapConfig(Map<String, String> input, String prefix) {
int subLength = prefix.length();
return input.entrySet().stream().flatMap((Map.Entry<String, Object> e) -> {
HashMap<String, AttributeType> r = new HashMap<>();
r.put(e.getKey().substring(subLength), AttributeType.GetByName(e.getValue()));
return r.entrySet().stream();
}).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
Run Code Online (Sandbox Code Playgroud)
Map.Entry由于它是一个接口而无法构造,导致单个条目Map实例的创建和使用flatMap(),这看起来很难看.
还有更好的选择吗?使用for循环似乎更好:
private Map<String, AttributeType> mapConfig(Map<String, String> input, String prefix) {
Map<String, AttributeType> result = new HashMap<>();
int subLength = prefix.length();
for(Map.Entry<String, String> entry : input.entrySet()) {
result.put(entry.getKey().substring(subLength), …Run Code Online (Sandbox Code Playgroud) 什么是LocalDate从Java 8和XMLGregorianCalendar?之间进行转换的最佳方法?
在java 8中,检查List是否包含任何重复的最佳方法是什么?
我的想法是这样的:
list.size() != list.stream().distinct().count()
Run Code Online (Sandbox Code Playgroud)
这是最好的方式吗?
为了利用java.util.streamJdk 8中包含的各种查询方法,我尝试设计域模型,其中具有*多重性(具有零个或多个实例)的关系的getter 返回a Stream<T>而不是Iterable<T>or Iterator<T>.
我怀疑的是,与此Stream<T>相比,Iterator<T>是否会产生任何额外的开销?
那么,使用Stream<T>?来破坏我的域模型是否有任何不利之处?
或者,我应该总是返回一个Iterator<T>或者Iterable<T>,并通过将该迭代器转换为StreamUtils?来让最终用户决定是否使用流.
请注意,返回a Collection不是有效选项,因为在这种情况下,大多数关系都是惰性且大小未知.
java-8 ×10
java ×8
lambda ×5
java-stream ×3
backport ×1
concurrency ×1
converter ×1
dictionary ×1
domain-model ×1
duplicates ×1
immutability ×1
java-7 ×1
java-time ×1
list ×1
sorting ×1
unsafe ×1