最佳结构用于可洗牌的键值(整数,字符串)列表

9
我需要在Java中实现一种键值列表结构(类型为Integer-String),并希望将其洗牌。
基本上,我想要做类似于这样的事情。
    public LinkedHashMap<Integer, String> getQuestionOptionsMap(){

    LinkedHashMap<Integer, String>  shuffle = new LinkedHashMap<Integer, String> ();

    if (answer1 != null)
        shuffle.put(new Integer(1), answer1);
    if (answer2 != null)
        shuffle.put(new Integer(2), answer2);
    if (answer3 != null)
        shuffle.put(new Integer(3), answer3);
    if (answer4 != null) 
        shuffle.put(new Integer(4), answer4);

    Collections.shuffle(shuffle);
    return shuffle;
}

然而,HashMap 无法洗牌。
我可以随机获取哈希表中的键,然后返回链接元素,但我确定这不是解决我的问题的最佳方法。
有更好的方法吗?
提前致谢。

1
你想要整数作为键还是字符串作为键,因为代码中两种方式都有。如果你想要洗牌,你需要一个列表。 - Peter Lawrey
抱歉,我的错,我已经在上面纠正了我的代码。 键是整数,值是字符串(我的答案文本)。 - MDT
请检查以下链接:http://stackoverflow.com/questions/5289222/how-to-shuffle-key-value-pairs - upog
谢谢,我看了那个线程,但我不想修改键和值。我只想随机获取一对(键-值)。 - MDT
5个回答

15
创建一个名为 Pair 的类,它包含一个 Integer 类型和一个 String 类型。然后将多个不同的 Pair 对象添加到一个列表中,并且这些对象将会被随机打乱。
public class Pair {
  private Integer integer;

  private String string;

  //accessors
}

那么:

List<Pair> list = new ArrayList<Pair>();
//...add some Pair objects to the list
Collections.shuffle(list);

7
如果这样做,你将无法获得 HashMap 的 O(1) 查找。 - Kayaman
谢谢,我选择了这个解决方案,将我的Pair类实现为主类内部的一个类。 - MDT

8

你可以保留这个Map,Map是按照键值进行查找设计的,因此建议你准备一个打乱顺序的键列表。

public Map<Integer, String> getQuestionOptionsMap() {
    Map<Integer, String> map = new HashMap<>();
    String[] answers = {null, answer1, answer2, answer3, answer4};
    for (int i = 1; i < answers.length; i++)
        if (answers[i] != null)
            map.put(i, answers[i]);
    List<Integer> order = new ArrayList<>(map.keySet());
    Collections.shuffle(order);
    Map<Integer, String> shuffled = new LinkedHashMap<>();
    for (Integer key : order)
        shuffled.put(key, map.get(key));
    return shuffled;
}

2
你可以保留一个独立的键值对列表,对其进行洗牌并使用它来访问HashMap。
List<Integer> keys = new ArrayList<Integer>(map.keySet());
Collections.shuffle(keys);
for(Integer i : keys)
    map.get(i);     // Gets the values in the shuffled order

是的,那就是我在问题结尾写的,但我不确定那是否是最佳选项。谢谢。 - MDT

0
Hashtable<Integer, String>

作为不那么方便和有效的替代,可以使用List<SomePairClass<Integer, String>>

1
也许一些解释会有帮助? - olinox14

0

您可以使用枚举来实现这一点,例如:

package device.packet.data;

public enum TLVList {
    
    SpeedingAlarm(0x1001, 3, Short.class),
    LowVoltageAlarm(0x1002, 3, Short.class),
    OBDCommunicationError(0x1015, 3, Short.class),
    IgnitionOn(0x1016, 3, Short.class),
    IgnitionOff(0x1017, 3, Short.class),
    MILAlarm(0x1018, 3, Short.class),
    UnlockAlarm(0x1019, 3, Short.class),
    NoCardPresented(0x101A, 3, Short.class),
    HiddenCommand(0x101B, 3, Short.class),
    Vibration(0x101C, 3, Short.class),
    DoorOpened(0x101D, 3, Short.class);
    
    private int tagFlagHex;
    private int length;
    private Class aClass;

    public int gettagFlagHex() {
        return tagFlagHex;
    }

    public int getLength() {
        return length;
    }

    public Class getClassType() {
        return aClass;
    }

    TLVList(int tagFlagHex, int length, Class aClass) {

        this.tagFlagHex = tagFlagHex;
        this.length = length;
        this.aClass = aClass;
    }

    public static TLVList of(Integer tagFlagHex) {
        for (TLVList tagFlag : TLVList.values()) {
            if(tagFlag.tagFlagHex == tagFlagHex) return tagFlag;
        }
        return null;
    }
}

希望它有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接