请考虑以下示例:
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) 假设我有一个没有实现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.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再次设置,因为此方法是唯一修改它的地方.
我有一个地图条目列表
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>有效,但这会导致编译器稍后发出“未经检查的方法调用”警告。
看一下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根据它的契约,这个方法在这种情况下总是返回.
我有一个本地存储库,并试图放弃自上次提交以来的所有更改
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 中通配符和通配符有什么区别*?
假设我要创建一个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中的“数组”一章也无法阐明这种情况。