标签: java-8

使用lambdas进行惰性字段初始化

我想在没有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>所需的语义.

lambda lazy-initialization java-8

46
推荐指数
5
解决办法
3万
查看次数

java 8,按属性排序对象列表,不带自定义比较器

完成这项工作的最简洁方法是什么?

 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)

sorting lambda list java-8

46
推荐指数
3
解决办法
5万
查看次数

为什么共享可变性不好?

我正在观看关于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 immutability java-8 java-stream

46
推荐指数
3
解决办法
4580
查看次数

有没有人将Lambda表达式向后移植到Java 7?

阅读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 lambda backport java-7 java-8

45
推荐指数
1
解决办法
7090
查看次数

如何在Java 8中为变量分配lambda?

只是在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 lambda java-8

45
推荐指数
1
解决办法
4万
查看次数

Java 8 Unsafe:xxxFence()指令

在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 …

java concurrency unsafe memory-fences java-8

45
推荐指数
3
解决办法
5720
查看次数

条目集上的Java 8流映射

我正在尝试对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)

java lambda dictionary java-8

45
推荐指数
4
解决办法
10万
查看次数

在LocalDate和XMLGregorianCalendar之间转换

什么是LocalDate从Java 8和XMLGregorianCalendar?之间进行转换的最佳方法?

java converter java-8 java-time

45
推荐指数
4
解决办法
5万
查看次数

如何检查Java 8 Streams中是否存在任何重复?

在java 8中,检查List是否包含任何重复的最佳方法是什么?

我的想法是这样的:

list.size() != list.stream().distinct().count()
Run Code Online (Sandbox Code Playgroud)

这是最好的方式吗?

java duplicates java-8 java-stream

45
推荐指数
3
解决办法
4万
查看次数

Iterator与Java的流8

为了利用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 domain-driven-design domain-model java-8 java-stream

45
推荐指数
2
解决办法
2万
查看次数