小编Tra*_*ity的帖子

Java 8 Comparator类型推断非常困惑

我一直在研究Collections.sort和之间的区别list.sort,特别是关于使用Comparator静态方法以及lambda表达式中是否需要param类型.在我们开始之前,我知道我可以使用方法引用,例如Song::getTitle克服我的问题,但我的查询并不是我想修复的东西,而是我想要的答案,即为什么Java编译器以这种方式处理它.

这是我的发现.假设我们有一个ArrayList类型Song,添加了一些歌曲,有3种标准的get方法:

    ArrayList<Song> playlist1 = new ArrayList<Song>();

    //add some new Song objects
    playlist.addSong( new Song("Only Girl (In The World)", 235, "Rhianna") );
    playlist.addSong( new Song("Thinking of Me", 206, "Olly Murs") );
    playlist.addSong( new Song("Raise Your Glass", 202,"P!nk") );
Run Code Online (Sandbox Code Playgroud)

这里调用两种类型的排序方法,没问题:

Collections.sort(playlist1, 
            Comparator.comparing(p1 -> p1.getTitle()));

playlist1.sort(
            Comparator.comparing(p1 -> p1.getTitle()));
Run Code Online (Sandbox Code Playgroud)

一旦我开始连锁thenComparing,就会发生以下情况:

Collections.sort(playlist1,
            Comparator.comparing(p1 -> p1.getTitle())
            .thenComparing(p1 -> p1.getDuration())
            .thenComparing(p1 -> p1.getArtist())
            );

playlist1.sort(
        Comparator.comparing(p1 -> p1.getTitle())
        .thenComparing(p1 -> p1.getDuration()) …
Run Code Online (Sandbox Code Playgroud)

java sorting lambda comparator java-8

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

Java包含vs anyMatch行为

所以如果我有一个Name对象并且有一个ArrayListtype Name(names),并且我想确定我的名字列表是否包含给定的Name对象(n),我可以用两种方式做到:

boolean exists = names.contains(n);
Run Code Online (Sandbox Code Playgroud)

要么

boolean exists - names.stream().anyMatch(x -> x.equals(n));
Run Code Online (Sandbox Code Playgroud)

我正在考虑这两个是否会表现相同,然后考虑如果分配n会发生什么null

对于contains,据我所知,如果参数是null,则true在列表包含时返回null.我将如何实现这一点anyMatch- 是否可以通过使用Objects.equals(x, n)

如果可行,那么哪种方法更有效 - 是否anyMatch可以利用懒惰和并行性?

java equality java-stream

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

GridPane中Label的JavaFX对齐方式

我很困惑为什么设置Label.setAlignment(Pos.CENTER_RIGHT)不会影响标签的对齐,然后将标签添加到GridPane中?唯一的方法是通过网格(例如ColumnConstraints)或通过例如将Label添加到具有正确对齐的HBox.

为什么将标签的对齐设置为CENTER_RIGHT无效?我可以看到API说:"指定当Labeled中有空的空格时,Labeled中的文本和图形应该如何对齐." 但是如何在标签中获得空白区域?

grid label javafx alignment

12
推荐指数
1
解决办法
3万
查看次数

Java流操作融合和有状态中间操作

我一直试图理解和展示Java流如何在引擎盖下实现一种循环融合,以便将几个操作融合到一个通道中.

这是第一个例子:

Stream.of("The", "cat", "sat", "on", "the", "mat")
        .filter(w -> {
            System.out.println("Filtering: " + w);
            return w.length() == 3;
        })
        .map(w -> {
            System.out.println("Mapping: " + w);
            return w.toUpperCase();
        })
        .forEach(w -> System.out.println("Printing: " + w));
Run Code Online (Sandbox Code Playgroud)

具有以下输出(每个元素的单个传递的融合非常清晰):

Filtering: The
Mapping: The
Printing: THE
Filtering: cat
Mapping: cat
Printing: CAT
Filtering: sat
Mapping: sat
Printing: SAT
Filtering: on
Filtering: the
Mapping: the
Printing: THE
Filtering: mat
Mapping: mat
Printing: MAT
Run Code Online (Sandbox Code Playgroud)

第二个例子是相同的,但我使用filter和map之间的sorted()操作:

Stream.of("The", "cat", "sat", "on", "the", "mat")
        .filter(w -> {
            System.out.println("Filtering: …
Run Code Online (Sandbox Code Playgroud)

java sorted stateful java-8 java-stream

10
推荐指数
1
解决办法
929
查看次数

为什么java lambda表达式不会引入新的范围?

据我所知,在Haskell等语言中,以及作为lambda演算的一部分,每个lambda表达式都有自己的作用域,所以如果我有嵌套的lambda表达式,例如:\x -> (\x -> x)那么第一个\x参数与第二个参数不同\x.

在Java中,如果执行此操作,则会出现编译错误,就像您x再次使用作为参数名称或lambda中的局部变量名称一样,如果它已在封闭范围内使用,例如作为方法参数.

有没有人知道为什么Java以这种方式实现了lambda表达式 - 为什么不让它们引入一个新的作用域级别并且表现得像一个匿名类呢?我假设是因为某些限制或优化,或者可能是因为lambdas必须被黑客入侵现有语言?

java lambda expression function lambda-calculus

8
推荐指数
2
解决办法
4557
查看次数

ConcurrentHashMap与ConcurrentSkipListMap的澄清

我想基于API文档澄清一些关于ConcurrentHashMap和ConcurrentSkipListMap的内容.

从我的理解ConcurrentHashMap gaurantees线程安全插入多个线程.因此,如果您的地图只能由多个线程同时填充,那么就没有问题.然而,API继续建议它不会锁定检索,所以你可能会在这里得到误导性的结果?

相反,对于ConcurrentSkipListMap,它表示:"插入,删除,更新和访问操作安全地由多个线程并行执行".所以我假设这没有哈希映射所具有的上述检索问题,但显然这通常会带来性能成本?

在实践中,有没有人发现需要使用ConcurrentSkipListMap,因为这种特殊的行为,或者通常无关紧要的是检索可能会给出过时的视图?

concurrency multithreading dictionary

7
推荐指数
1
解决办法
3422
查看次数

正确使用在地图中存储对象

假设我需要存储一组Student对象,并且每个学生都有一个唯一的id.一种选择是将所有这些存储在列表中,但是当搜索学生时,我必须执行线性搜索并检查他们的ID.另一种选择是使用提供的地图,是这样的:地图,其中键是学生的ID映射到实际的学生对象.

对于给定的问题,这是一种明智的方法吗?一方面它感觉正确,因为我可以轻松地通过他们的id检索学生,但是,另一方面,感觉我稍微冗余地存储已经存在于学生对象中的id - 所以我是排序的存储它两次,但关键是查找机制.

我的添加将是这样的:

public void add(Student s) {
     lookup.put(s.getId(), s);
}
Run Code Online (Sandbox Code Playgroud)

java collections dictionary

6
推荐指数
1
解决办法
66
查看次数

将文字或变量分配给Char时的Scala行为

在Scala中,如果我有变量声明,例如

var x: Char = 'a'
Run Code Online (Sandbox Code Playgroud)

如果我然后尝试通过添加1来更新此字符,例如

x = x + 1
Run Code Online (Sandbox Code Playgroud)

我收到编译错误:输入不匹配,找到Int必需的Char.但是,我可以在没有编译错误的情况下执行此操作:

x = 'a' + 1
Run Code Online (Sandbox Code Playgroud)

我猜这与文字值和对象有关,但是,我试图弄清楚确切的行为.您可以清楚地为字符整数分配一个字符,例如97,您也可以分配97-32的结果.但是,如果我说97-32 + 5然后我得到类型不匹配错误.编译器在什么时候区分导致文字的表达式与导致对象的表达式?

int scala char variable-assignment

6
推荐指数
1
解决办法
115
查看次数

并行流和CompletableFuture之间的差异

在"Java 8 in action"(Urma,Fusco和Mycroft)一书中,他们强调并行流在内部使用公共fork连接池,虽然这可以全局配置,例如使用System.setProperty(...),不可能为单个并行流指定值.

我已经看到了涉及在自定义ForkJoinPool中运行并行流的解决方法.

在本书的后面,他们有一整章致力于CompletableFuture,在此期间他们有一个案例研究,他们比较使用parallelStream VS和CompletableFuture的各自表现.事实证明它们的性能非常相似 - 它们强调了这一点的原因是它们都是默认使用相同的公共池(因此相同数量的线程).

他们继续展示解决方案并争辩说CompletableFuture在这种情况下更好,因为它可以被设置为使用自定义Executor,其用户选择的线程池大小.当他们更新解决方案以利用它时,性能得到显着改善.

这让我想到 - 如果使用上面强调的变通方法对并行流版本做同样的事情,那么性能优势是否会相似,那么这两种方法在性能方面是否会再次相似?在这种情况下,为什么人们会选择CompletableFuture而不是并行流,因为它显然需要开发人员更多的工作.

java parallel-processing multithreading java-stream completable-future

5
推荐指数
1
解决办法
2820
查看次数

无序和并行时的Java流限制和跳过行为

所以我一直在玩并行运行流,并根据API文档和我读过的其他支持材料监控它们的行为.

我创建了两个并行流并运行distinct(),一个是流的顺序,另一个是无序流.然后我使用打印结果forEachOrdered()(以确保我看到在运行之后生成的流的遇到顺序),并且可以清楚地看到无序版本不保持原始排序,但是使用大型数据集,显然会增强并行性能.

有一些API说明表明,当流是无序的时,limit()skip()操作也应该并行运行,而不是必须检索第一个n元素,你可以得到任何n元素.我试图以与上面相同的方式模拟这个,但是当与有序和无序流并行运行时的结果总是相同的.换句话说,当我在运行限制后打印出结果时,即使对于无序(并行)流,它仍然总是选择前n个元素?

有谁能解释一下?我尝试改变输入数据集的大小和n的值,它没有任何区别.我本以为它会抓住任何n个元素并优化并行性能?有没有人在实践中看到过这种情况,并且可能提供一种能够始终如一地展示这种行为的解决方案?

java parallel-processing java-8 java-stream

5
推荐指数
1
解决办法
556
查看次数