相关疑难解决方法(0)

HashMap调整方法实现细节

正如标题所示,这是一个关于实现细节的问题HashMap#resize- 当内部数组的大小加倍时.这有点罗嗦,但我真的试图证明我对此有了最好的理解......

这发生在这个特定桶/箱中的条目以某种方式存储的时刻Linked- 因此具有确切的顺序并且在问题的上下文中这是重要的.

一般来说,resize也可以从其他地方调用,但我们只看这个案例.

假设你将这些字符串作为键放在一个HashMap(右边是hashcode 后面 HashMap#hash - 那是内部重新散列.)是的,这些都是精心生成的,而不是随机的.

 DFHXR - 11111
 YSXFJ - 01111 
 TUDDY - 11111 
 AXVUH - 01111 
 RUTWZ - 11111
 DEDUC - 01111
 WFCVW - 11111
 ZETCU - 01111
 GCVUR - 11111 
Run Code Online (Sandbox Code Playgroud)

这里有一个简单的模式 - 最后4位对于所有这些都是相同的 - 这意味着当我们插入这些键中的8个(总共9个)时,它们最终会在同一个桶中; 并在9个HashMap#put时,resize将被调用.

因此,如果当前有8个条目(上面有一个键)HashMap- 这意味着在这个映射中有16个桶,它们的最后4个位决定了条目最终的位置.

我们把第九个键.此时TREEIFY_THRESHOLD被击中并被resize召唤.这些容器加倍,32并且键的另一位决定了该条目的位置(因此,现在为5位).

最终到达这段代码(当resize发生时):

 Node<K,V> loHead = null, loTail = null;
 Node<K,V> …
Run Code Online (Sandbox Code Playgroud)

java hashmap hashcode java-8

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

ImmutableCollections SetN实现细节

我很难理解java-9中的实现细节ImmutableCollections.SetN; 具体为什么需要两次增加内部数组.

假设你这样做:

Set.of(1,2,3,4) // 4 elements, but internal array is 8
Run Code Online (Sandbox Code Playgroud)

更准确地说,我完全理解为什么这样做(双重扩展)以防万一HashMap- 你从来没有(几乎)想要load_factor成为一个.例如,!=1当条目更好地分散到存储桶时,值可以改善搜索时间.

但是在一个不可变的集合的情况下- 我无法真正说出来.特别是因为选择了内部数组的索引.

让我提供一些细节.首先如何搜索索引:

 int idx = Math.floorMod(pe.hashCode() ^ SALT, elements.length);
Run Code Online (Sandbox Code Playgroud)

pe是我们放在集合中的实际值.SALT在启动时只生成32位,每次生成一次JVM(如果需要,这是实际的随机化).elements.length我们的例子是8(4个元素,但这里有8个 - 大小加倍).

这个表达式就像一个负安全的模运算.请注意,选择存储桶时HashMap,例如((n - 1) & hash)中会执行相同的逻辑操作.

因此,如果elements.length is 8对于我们的情况,则此表达式将返回任何小于8的正值(0, 1, 2, 3, 4, 5, 6, 7).

现在剩下的方法:

 while (true) {
        E ee = elements[idx];
        if …
Run Code Online (Sandbox Code Playgroud)

java collections java-9

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

BinaryOperator的标识

我在Java8的UnaryOperator接口中看到了一段代码,它对参数没有任何作用并返回相同的值.

static <T> UnaryOperator<T> identity() {
    return t -> t;
}
Run Code Online (Sandbox Code Playgroud)

BinaryOperator有什么东西可以接受samekind的两个参数并返回一个值

static <T> BinaryOperator<T> identity() {
    return (t,t) -> t;
}
Run Code Online (Sandbox Code Playgroud)

为什么我问这个问题是针对以下要求,

List<String> list = Arrays.asList("Abcd","Abcd");
Map<String,Integer> map = list.stream().collect(Collectors.toMap(str->str, 
str->(Integer)str.length(),(t1,t2)->t1));
System.out.println(map.size());
Run Code Online (Sandbox Code Playgroud)

在上面的代码我不想为同一个键的两个值做任何事情,我只想返回一个值,因为在我的情况下肯定值将是相同的.由于我没有使用t2值声纳投掷错误,所以我发现在java8中也存在像BinaryOpertor的UnaryOperator.identity()这样的东西

java lambda functional-programming java-8

7
推荐指数
2
解决办法
338
查看次数

Java8 Stream超过了订单的集合一致性

据我所知,Set in java是一个无序集合,迭代器将按照其选择的某个顺序处理项目(我可能在这里错了),但确保它处理集合中的所有元素.

在Java8中,集合中的stream()API已经引入了跳过和限制功能.所以我想知道从流处理的项目的顺序是否保持相同,无论我开始流的次数或每次都是随机的?如果在流之间修改集合,订单会改变吗?

可能是无关紧要但我在这里提出问题:现在遇到问题,我有一套2000或者其他什么东西在创建后不会被修改,我正在进行50个批量操作,涉及每个批次的网络调用.我有一个启动参数,每次调用后增加50.如果我在我的Set上使用一个带有"start"的流作为每个批处理的skip参数,那么它对于每个批处理都是一个新流吗?因此,流程的顺序保持不变.显然,我不会多次相同的条目,更重要的是我不会错过任何条目.最简单的事情对我来说是一个Arraylist但我想知道我是否真的需要创建一个集合.

collections lambda hashset java-8

4
推荐指数
2
解决办法
202
查看次数