我将HashMap值与密钥进行比较,并在密钥较大时替换。目的是更新和弦系统模拟手指表。
我有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]);
}
}
答案 0 :(得分:1)
首先,您似乎(错误!)假设HashMap
已订购。
事实并非如此!
如果您想要按其键值排序的地图,则必须使用TreeMap
。 (或者,您可以从地图中收集所有条目,并将它们放入列表中,然后您可以根据其键对其进行排序。)
除此之外,确定一个&#34; next&#34;地图中的关键不是那么简单。 (事实上,对于TreeMap
,您可以使用higherKey
method,但这不是必需的。)
您可以简单地浏览条目,并始终参考您为其更新列表的上一个条目(基于当前条目的键)。< / p>
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]
答案 1 :(得分:1)
你可以将value视为Integer的动态数组,可以使用ArrayList和key作为Integer实现。你可以为此目的编写这样的代码:
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<>();
}
答案 2 :(得分:0)
我从第一眼就看到两个问题似乎违反了你的例子的逻辑。
根据您的示例,必须将当前元素的地图值与下一个元素的地图键进行比较,而不是当前。
首先,与for (int i=0; i<chordSize; i++) {
对齐:我希望你会遍历m.getValue()。length(),这样你就可以迭代与m
相关联的值,而不是chordSize
似乎与此地图有关,但我不确定原因。
其次,与if (m.getValue().successor[i] < m.getKey()) {
对齐我认为您需要将m.getValue().successor[i]
与下一个元素的键进行比较,而不是当前元素键。
考虑到这一点,您需要将所有地图项目放入另一个数据结构中,该数据结构为您提供基于索引的访问(数组似乎没问题,因为您已经知道地图的大小),因此您将会能够获得下一个地图项目,同时也使用当前的地图项目。这将使比较更容易。
希望有所帮助。
答案 3 :(得分:0)
我担心你的例子仍然有点不清楚。以下是您想要做的事情:
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将“覆盖”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。
答案 4 :(得分:0)
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());
}
}
}