小编Joh*_*ane的帖子

为什么x ==(x = y)与(x = y)== x不相同?

请考虑以下示例:

class Quirky {
    public static void main(String[] args) {
        int x = 1;
        int y = 3;

        System.out.println(x == (x = y)); // false
        x = 1; // reset
        System.out.println((x = y) == x); // true
     }
}
Run Code Online (Sandbox Code Playgroud)

我不确定Java语言规范中是否有一个项目要求加载变量的先前值以与右侧(x = y)进行比较,右侧()按括号隐含的顺序首先计算.

为什么第一个表达式评估false,但第二个表达式评估为true?我本来期望(x = y)先评估,然后它会x与自己(3)进行比较并返回true.


这个问题与Java表达式中子表达式的评估顺序不同,这x绝对不是这里的"子表达式".需要加载它以进行比较而不是"评估".这个问题是特定于Java的,而且这个表达式x == (x = y)不同于通常为棘手的面试问题精心设计的不切实际的结构,而是来自一个真实的项目.它应该是比较和替换成语的单行替代品

int oldX = x;
x = y;
return …
Run Code Online (Sandbox Code Playgroud)

java equality variable-assignment operator-precedence jls

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

当没有区别字段时,比较器适用于TreeSet

假设我有一个没有实现Comparable接口的类

class Dummy {
}
Run Code Online (Sandbox Code Playgroud)

以及该类的一个实例的集合以及该类外部的一些函数,它们允许部分地比较这些实例(下面将使用一个映射):

Collection<Dummy> col = new ArrayList<>();
Map<Dummy, Integer> map = new HashMap<>();
for (int i = 0; i < 12; i++) {
    Dummy d = new Dummy();
    col.add(d);
    map.put(d, i % 4);
}
Run Code Online (Sandbox Code Playgroud)

现在我想使用TreeSet带有自定义比较器的类对此集合进行排序:

TreeSet<Dummy> sorted = new TreeSet<>(new Comparator<Dummy>() {
    @Override
    public int compare(Dummy o1, Dummy o2) {
        return map.get(o1) - map.get(o2);
    }
});
sorted.addAll(col);
Run Code Online (Sandbox Code Playgroud)

结果显然不令人满意(包含的元素少于初始集合).这是因为这样的比较器equals0不相等的元素不一致,即有时返回.我的下一次尝试是compare将比较器的方法改为

@Override
public int compare(Dummy o1, Dummy …
Run Code Online (Sandbox Code Playgroud)

java comparator treeset

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

初始化静态变量时使用局部变量

java.util.Scanner我找到这些静态实用程序方法的源代码中:

private static Pattern separatorPattern() {
    Pattern sp = separatorPattern;
    if (sp == null)
        separatorPattern = sp = Pattern.compile(LINE_SEPARATOR_PATTERN);
    return sp;
}

private static Pattern linePattern() {
    Pattern lp = linePattern;
    if (lp == null)
        linePattern = lp = Pattern.compile(LINE_PATTERN);
    return lp;
}
Run Code Online (Sandbox Code Playgroud)

为什么它以如此复杂的方式完成而不仅仅是,比方说,

private static Pattern linePattern() {
    if (linePattern == null)
        linePattern = Pattern.compile(LINE_PATTERN);
    return linePattern;
}
Run Code Online (Sandbox Code Playgroud)

lp在这里使用局部变量()有什么意义?这是某种优化技术吗?或者可能是针对并发修改的预防措施?但linePattern不能null再次设置,因为此方法是唯一修改它的地方.

java variables static initialization

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

Map.Entry.comparingByValue().reversed() 的类型是什么?

我有一个地图条目列表

Map<String, Integer> map = new HashMap<>();
...(fill the map)...
List<Entry<String, Integer>> entries = new ArrayList<>(map.entrySet());
Run Code Online (Sandbox Code Playgroud)

我想根据这个答案按值对其进行排序,但顺序相反。当我做

Comparator<Entry<String, Integer>> cmp = Entry.comparingByValue();
entries.sort(cmp.reversed());
Run Code Online (Sandbox Code Playgroud)

一切正常。但是当我尝试将上述两行缩短为

entries.sort(Entry.comparingByValue().reversed());
Run Code Online (Sandbox Code Playgroud)

编译器返回

error: incompatible types: Comparator<Entry<Object,V>> cannot be converted to Comparator<? super Entry<String,Integer>>
        entries.sort(Entry.comparingByValue().reversed());
  where V is a type-variable:
    V extends Comparable<? super V>
Run Code Online (Sandbox Code Playgroud)

这看起来很奇怪,因为 Comparator 的reversed()默认方法的实现只是将它转移到Collections.reverseOrder(),我可以将上面的行更改为

entries.sort(Collections.reverseOrder(Entry.comparingByValue()));
Run Code Online (Sandbox Code Playgroud)

上班。但是什么是正确的类型Entry.comparingByValue().reversed()

Comparator<Entry<String, Integer>> cmp = Entry.comparingByValue().reversed();
Run Code Online (Sandbox Code Playgroud)

似乎不起作用。省略类型参数Entry<String, Integer>有效,但这会导致编译器稍后发出“未经检查的方法调用”警告。

java generics comparator

5
推荐指数
2
解决办法
6608
查看次数

Map的putIfAbsent实现中的冗余分配

看一下putIfAbsent界面中默认方法的实现Map,

default V putIfAbsent(K key, V value) {
    V v = get(key);
    if (v == null) {
        v = put(key, value);
    }

    return v;
}
Run Code Online (Sandbox Code Playgroud)

我想知道为什么这个任务

v = put(key, value);
Run Code Online (Sandbox Code Playgroud)

在那里完成而不是简单地丢弃返回的值?这个赋值似乎是不必要的,因为v已经存在null,put根据它的契约,这个方法在这种情况下总是返回.

java

2
推荐指数
1
解决办法
72
查看次数

之间的区别。git 中的 (点) 和 * (星号) 通配符

我有一个本地存储库,并试图放弃自上次提交以来的所有更改

git checkout HEAD -- *
Run Code Online (Sandbox Code Playgroud)

命令。一切工作正常,即使更改是在某个子目录中。但是,当我添加一些未跟踪的文件(满足中的掩码.gitignore)时,将“Ignored.txt”添加到存储库的根目录中,上述命令失败并显示消息

error: pathspec 'Ignored.txt' did not match any file(s) known to git
Run Code Online (Sandbox Code Playgroud)

相比之下,

git checkout HEAD -- .
Run Code Online (Sandbox Code Playgroud)

按预期工作。所以我想知道:

.git 中通配符和通配符有什么区别*

git wildcard

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

数组是否具有固有的hashCode()?

假设我要创建一个HashSet或,HashMap其键是原始类型的数组,如下所示:

Set<int[]> setOfIntArrays = new HashSet<>();
Map<char[], String> mapOfCharArrays = new HashMap<>();
Run Code Online (Sandbox Code Playgroud)

这些结构将对数组使用哪些哈希码?

我知道根类Object包含hashCode(),因此它可用于任何继承类的实例(在其中可以重写或不重写)。本Arrays类有一堆的静态hashCode(...)所有基本类型数组的方法。这些方法是否也作为“原始”类型数组的(重写)实例方法“内置”?由于数组在集合和映射中充当普通类,因此这样做似乎合乎逻辑。但是,没有用于类的javadoc,int[]并且JLS中的“数组”一章也无法阐明这种情况。

java arrays hashcode

0
推荐指数
1
解决办法
49
查看次数