HashMap Keys 和 Value 比较
HashMap Keys and Value comparison
我正在将 HashMap 值与键进行比较,如果键较大则进行替换。目的是更新和弦系统模拟的手指Table。
我有 HashMap 数据:
Key 0 with Values: [1,2,4,8,16]
Key 3 with Values: [4,5,7,11,19]
Key 7 with Values: [8,9,11,15,23]
期望的结果是,对于每个键 0、3 和 7,其值将与下一个键值进行比较。
Example:
For key 0, compare its values with next key value which is 3.
3 compare with [1,2,4,8,16] and replace 1,2 with 3 because 3 > 1 and 2
For key 3, compare its values with next key value which is 7.
7 compare with [4,5,7,11,19] and replace 4,5 with 7 because 7 > 4 and 5
下面编写的代码执行以下操作:
For the first set of values [1,2,4,8,16]
1 compare with [0]
2 compare with [0]
4 compare with [0]
etc.. and it moves on to another set of values
[4,5,7,11, 19]
4 compare with [3]
5 compare with [3]
7 compare with [3]
如何修改代码以达到上述预期结果?
public void updateFingerTable() {
chordSize = chord.initChordSize;
for (Map.Entry<Integer, node> m : peerList.entrySet()) {
for (int i=0; i<chordSize; i++) {
System.out.println("Successor i: " + m.getValue().successor[i]);
System.out.println ("Key: " + m.getKey());
if (m.getValue().successor[i] < m.getKey()) {
m.getValue().successor[i] = m.getKey();
//System.out.println(m.getValue().successor[i]);
}
}
首先,您似乎做出了(错误的!)假设 HashMap
是 有序的 。
不是这样的!
如果您想要一个按其键值排序的映射,则必须使用 TreeMap
。 (或者,您可以从地图中收集所有条目,并将它们放入一个列表中,然后您可以根据它们的键对列表进行排序)。
除此之外,确定映射中的 "next" 键并不是那么简单。 (事实上 ,对于 TreeMap
,您可以使用 higherKey
method,但这在这里不是必需的)。
您可以简单地遍历条目,并始终参考更新列表的 previous 条目(基于 current条目)。
import java.util.Arrays;
import java.util.Map;
import java.util.TreeMap;
public class KeyValueListTest
{
public static void main(String[] args)
{
Map<Integer, IntArrayNode> map = new TreeMap<Integer, IntArrayNode>();
map.put(0, new IntArrayNode(new int[]{1,2,4,8,16}));
map.put(3, new IntArrayNode(new int[]{4,5,7,11,19}));
map.put(7, new IntArrayNode(new int[]{8,9,11,15,23}));
System.out.println("Before update:");
for (Map.Entry<Integer, IntArrayNode> e : map.entrySet())
{
System.out.println(e);
}
update(map);
System.out.println("After update:");
for (Map.Entry<Integer, IntArrayNode> e : map.entrySet())
{
System.out.println(e);
}
}
private static void update(IntArrayNode node, int minValue)
{
for (int i=0; i<node.getNumElements(); i++)
{
node.setElement(i, Math.max(minValue, node.getElement(i)));
}
}
public static void update(Map<Integer, IntArrayNode> map)
{
Map.Entry<Integer, IntArrayNode> previous = null;
for (Map.Entry<Integer, IntArrayNode> e : map.entrySet())
{
if (previous != null)
{
update(previous.getValue(), e.getKey());
}
previous = e;
}
}
}
class IntArrayNode
{
private final int elements[];
IntArrayNode(int elements[])
{
this.elements = elements.clone();
}
int getNumElements()
{
return elements.length;
}
int getElement(int index)
{
return elements[index];
}
void setElement(int index, int value)
{
elements[index] = value;
}
@Override
public String toString()
{
return Arrays.toString(elements);
}
}
对于您的示例输入,这将打印
Before update:
0=[1, 2, 4, 8, 16]
3=[4, 5, 7, 11, 19]
7=[8, 9, 11, 15, 23]
After update:
0=[3, 3, 4, 8, 16]
3=[7, 7, 7, 11, 19]
7=[8, 9, 11, 15, 23]
我看到两个问题,乍一看似乎违反了您示例的逻辑。
根据您的示例,当前元素的映射值必须与 下一个 元素的映射键进行比较,而不是 当前。
首先,与 for (int i=0; i<chordSize; i++) {
一致:我期待您会遍历 m.getValue().length() 以便您可以迭代与 [= 关联的值11=],而不是 chordSize
,它似乎与此地图有关,但我不确定为什么。
其次,符合 if (m.getValue().successor[i] < m.getKey()) {
我认为您需要将 m.getValue().successor[i]
与 next 元素的键进行比较,而不是 当前元素的键。
考虑到这一点,您需要将所有地图项放入另一个数据结构中,该数据结构为您提供基于索引的访问(数组似乎没问题,因为您已经知道地图的大小)到其组件,以便您将能够获取下一个地图项,同时还可以使用当前地图项。这将使比较变得更加容易。
希望对您有所帮助。
您可以将 value 视为可以使用 ArrayList 和 key 实现的 Integer 动态数组,因为 Integer.You 可以针对您的目的编写如下代码:
List<Integer> value=new ArrayList<>();
for (Map.Entry pair : map.entrySet())
{
Integer key=(Integer)pair.getKey();
for(Integer x:(ArrayList<Integer>)(pair.getValue()))
{
if(key>x)
{
value.add(key);
}
else
{
value.add(x);
}
}
map.put(key, (ArrayList<Integer>) value);
System.out.println(value);
value=new ArrayList<>();
}
恐怕你的例子还是有点不清楚。以下是您想执行的操作:
3 keys [0,3,7]
Three sets of values: [1,2,4,8,16], [4,5,7,11,19], [8,9,11,15,23]
Step 1):
You take the 0 from the keys and compare it with the values:
0 > 1? No ... 0>16? No.
Step 2):
Compare the 3 from the keys with the values:
3>1? Yes -> Replace 1 with 3 ... 3>16? No ...
Step 3):
Compare the 7 from the keys with the values:
7>1 Yes -> Replace 1 with 7, 7>2? Yes -> Replace...
如果是,为什么还要比较小的键呢?键 7 将 "override" 0 和 3 之前所做的所有更改,因此只需找到最大的键并将其与值进行比较即可。
int keyArray[] = new int[]{0,3,7};
int largest = keyArray[0];
for(int i=1; i< keyArray.length; i++)
{
if(keyArray[i] > largest)
largest = keyArray[i];
}
然后您可以查看您的值集并将它们与 largest.equals()
与 HashMap 进行比较。
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Map<Integer, List<Integer>> hash = new HashMap<Integer,List<Integer>>();
List<Integer> list1 = new ArrayList<Integer>();
list1.add(1);list1.add(2);list1.add(4);list1.add(8);list1.add(16);
List<Integer> list2 = new ArrayList<Integer>();
list2.add(4);list2.add(5);list2.add(7);list2.add(11);list2.add(19);
List<Integer> list3 = new ArrayList<Integer>();
list3.add(8);list3.add(9);list3.add(11);list3.add(15);list3.add(23);
hash.put(0,list1);
hash.put(3,list2);
hash.put(7,list3);
System.out.println("Input:");
for (Map.Entry<Integer, List<Integer>> m1 : hash.entrySet()) {
System.out.println("Successor i: " + m1.getValue());
System.out.println ("Key: " + m1.getKey());
}
Map<Integer, List<Integer>> out = hash;
List<Integer> list = new ArrayList<Integer>();
int keyValue = 0;
int count=0;
for (Entry<Integer, List<Integer>> m : hash.entrySet()) {
if(count==0){
list = m.getValue();
keyValue = m.getKey();
count++;
continue;
}
else{
for(int i=0;i<list.size();i++){
if(m.getKey()>list.get(i)){
list.set(i, m.getKey());
}
}
out.put(keyValue,list);
list = m.getValue();
keyValue = m.getKey();
}
}
System.out.println("Output:----------------");
for (Map.Entry<Integer, List<Integer>> m1 : out.entrySet()) {
System.out.println("Successor i: " + m1.getValue());
System.out.println ("Key: " + m1.getKey());
}
}
}
我正在将 HashMap 值与键进行比较,如果键较大则进行替换。目的是更新和弦系统模拟的手指Table。
我有 HashMap 数据:
Key 0 with Values: [1,2,4,8,16]
Key 3 with Values: [4,5,7,11,19]
Key 7 with Values: [8,9,11,15,23]
期望的结果是,对于每个键 0、3 和 7,其值将与下一个键值进行比较。
Example:
For key 0, compare its values with next key value which is 3.
3 compare with [1,2,4,8,16] and replace 1,2 with 3 because 3 > 1 and 2
For key 3, compare its values with next key value which is 7.
7 compare with [4,5,7,11,19] and replace 4,5 with 7 because 7 > 4 and 5
下面编写的代码执行以下操作:
For the first set of values [1,2,4,8,16]
1 compare with [0]
2 compare with [0]
4 compare with [0]
etc.. and it moves on to another set of values
[4,5,7,11, 19]
4 compare with [3]
5 compare with [3]
7 compare with [3]
如何修改代码以达到上述预期结果?
public void updateFingerTable() {
chordSize = chord.initChordSize;
for (Map.Entry<Integer, node> m : peerList.entrySet()) {
for (int i=0; i<chordSize; i++) {
System.out.println("Successor i: " + m.getValue().successor[i]);
System.out.println ("Key: " + m.getKey());
if (m.getValue().successor[i] < m.getKey()) {
m.getValue().successor[i] = m.getKey();
//System.out.println(m.getValue().successor[i]);
}
}
首先,您似乎做出了(错误的!)假设 HashMap
是 有序的 。
不是这样的!
如果您想要一个按其键值排序的映射,则必须使用 TreeMap
。 (或者,您可以从地图中收集所有条目,并将它们放入一个列表中,然后您可以根据它们的键对列表进行排序)。
除此之外,确定映射中的 "next" 键并不是那么简单。 (事实上 ,对于 TreeMap
,您可以使用 higherKey
method,但这在这里不是必需的)。
您可以简单地遍历条目,并始终参考更新列表的 previous 条目(基于 current条目)。
import java.util.Arrays;
import java.util.Map;
import java.util.TreeMap;
public class KeyValueListTest
{
public static void main(String[] args)
{
Map<Integer, IntArrayNode> map = new TreeMap<Integer, IntArrayNode>();
map.put(0, new IntArrayNode(new int[]{1,2,4,8,16}));
map.put(3, new IntArrayNode(new int[]{4,5,7,11,19}));
map.put(7, new IntArrayNode(new int[]{8,9,11,15,23}));
System.out.println("Before update:");
for (Map.Entry<Integer, IntArrayNode> e : map.entrySet())
{
System.out.println(e);
}
update(map);
System.out.println("After update:");
for (Map.Entry<Integer, IntArrayNode> e : map.entrySet())
{
System.out.println(e);
}
}
private static void update(IntArrayNode node, int minValue)
{
for (int i=0; i<node.getNumElements(); i++)
{
node.setElement(i, Math.max(minValue, node.getElement(i)));
}
}
public static void update(Map<Integer, IntArrayNode> map)
{
Map.Entry<Integer, IntArrayNode> previous = null;
for (Map.Entry<Integer, IntArrayNode> e : map.entrySet())
{
if (previous != null)
{
update(previous.getValue(), e.getKey());
}
previous = e;
}
}
}
class IntArrayNode
{
private final int elements[];
IntArrayNode(int elements[])
{
this.elements = elements.clone();
}
int getNumElements()
{
return elements.length;
}
int getElement(int index)
{
return elements[index];
}
void setElement(int index, int value)
{
elements[index] = value;
}
@Override
public String toString()
{
return Arrays.toString(elements);
}
}
对于您的示例输入,这将打印
Before update:
0=[1, 2, 4, 8, 16]
3=[4, 5, 7, 11, 19]
7=[8, 9, 11, 15, 23]
After update:
0=[3, 3, 4, 8, 16]
3=[7, 7, 7, 11, 19]
7=[8, 9, 11, 15, 23]
我看到两个问题,乍一看似乎违反了您示例的逻辑。
根据您的示例,当前元素的映射值必须与 下一个 元素的映射键进行比较,而不是 当前。
首先,与
for (int i=0; i<chordSize; i++) {
一致:我期待您会遍历 m.getValue().length() 以便您可以迭代与 [= 关联的值11=],而不是chordSize
,它似乎与此地图有关,但我不确定为什么。其次,符合
if (m.getValue().successor[i] < m.getKey()) {
我认为您需要将m.getValue().successor[i]
与 next 元素的键进行比较,而不是 当前元素的键。
考虑到这一点,您需要将所有地图项放入另一个数据结构中,该数据结构为您提供基于索引的访问(数组似乎没问题,因为您已经知道地图的大小)到其组件,以便您将能够获取下一个地图项,同时还可以使用当前地图项。这将使比较变得更加容易。
希望对您有所帮助。
您可以将 value 视为可以使用 ArrayList 和 key 实现的 Integer 动态数组,因为 Integer.You 可以针对您的目的编写如下代码:
List<Integer> value=new ArrayList<>();
for (Map.Entry pair : map.entrySet())
{
Integer key=(Integer)pair.getKey();
for(Integer x:(ArrayList<Integer>)(pair.getValue()))
{
if(key>x)
{
value.add(key);
}
else
{
value.add(x);
}
}
map.put(key, (ArrayList<Integer>) value);
System.out.println(value);
value=new ArrayList<>();
}
恐怕你的例子还是有点不清楚。以下是您想执行的操作:
3 keys [0,3,7]
Three sets of values: [1,2,4,8,16], [4,5,7,11,19], [8,9,11,15,23]
Step 1):
You take the 0 from the keys and compare it with the values:
0 > 1? No ... 0>16? No.
Step 2):
Compare the 3 from the keys with the values:
3>1? Yes -> Replace 1 with 3 ... 3>16? No ...
Step 3):
Compare the 7 from the keys with the values:
7>1 Yes -> Replace 1 with 7, 7>2? Yes -> Replace...
如果是,为什么还要比较小的键呢?键 7 将 "override" 0 和 3 之前所做的所有更改,因此只需找到最大的键并将其与值进行比较即可。
int keyArray[] = new int[]{0,3,7};
int largest = keyArray[0];
for(int i=1; i< keyArray.length; i++)
{
if(keyArray[i] > largest)
largest = keyArray[i];
}
然后您可以查看您的值集并将它们与 largest.equals()
与 HashMap 进行比较。
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Map<Integer, List<Integer>> hash = new HashMap<Integer,List<Integer>>();
List<Integer> list1 = new ArrayList<Integer>();
list1.add(1);list1.add(2);list1.add(4);list1.add(8);list1.add(16);
List<Integer> list2 = new ArrayList<Integer>();
list2.add(4);list2.add(5);list2.add(7);list2.add(11);list2.add(19);
List<Integer> list3 = new ArrayList<Integer>();
list3.add(8);list3.add(9);list3.add(11);list3.add(15);list3.add(23);
hash.put(0,list1);
hash.put(3,list2);
hash.put(7,list3);
System.out.println("Input:");
for (Map.Entry<Integer, List<Integer>> m1 : hash.entrySet()) {
System.out.println("Successor i: " + m1.getValue());
System.out.println ("Key: " + m1.getKey());
}
Map<Integer, List<Integer>> out = hash;
List<Integer> list = new ArrayList<Integer>();
int keyValue = 0;
int count=0;
for (Entry<Integer, List<Integer>> m : hash.entrySet()) {
if(count==0){
list = m.getValue();
keyValue = m.getKey();
count++;
continue;
}
else{
for(int i=0;i<list.size();i++){
if(m.getKey()>list.get(i)){
list.set(i, m.getKey());
}
}
out.put(keyValue,list);
list = m.getValue();
keyValue = m.getKey();
}
}
System.out.println("Output:----------------");
for (Map.Entry<Integer, List<Integer>> m1 : out.entrySet()) {
System.out.println("Successor i: " + m1.getValue());
System.out.println ("Key: " + m1.getKey());
}
}
}