1

我想要一个具有整数键和对象值的 ConcurrentHashMap(地图的一些值是整数,另一个是字符串)。这是初始化和使用我的表的正确方法吗?

ConcurrentHashMap table=new ConcurrentHashMap<Integer, Comparable>();
        table.put(new Integer(1), new String("nodata"));
        table.put(new Integer(2), new Integer(23));
4

6 回答 6

4

几点

  • 您不需要自动装箱int值并且包装字符串文字是没有意义的。
  • 您需要将泛型类型保留在左侧,但首选使用接口。
  • 您只会使用 Comparable 来比较对象。但是,您通常无法比较不同类型的对象,因此这更令人困惑而不是有用。

.

Map<Integer, Object> table = new ConcurrentHashMap<>();
table.put(1, "nodata");
table.put(2, 23);

如果您需要 ConcurrentMap 提供的其他方法,您可能需要以下内容。

ConcurrentMap<Integer, Object> table = new ConcurrentHashMap<>();

这似乎是一个对象拒绝的情况。使用 Object 可能是更好的选择。

class MyData {
    private String text;
    private int number;

    MyData(String text, int number) {
        this.text = text;
        this.number = number;
    }

    public synchronized String getText() {
        return text;
    }

    public synchronized void setText(String text) {
        this.text = text;
    }

    public synchronized int getNumber() {
        return number;
    }

    public synchronized void setNumber(int number) {
        this.number = number;
    }
}

MyData data = new MyData("nodata", 23);

对于相同的并发版本。

class MyData {
    private final AtomicReference<String> text;
    private final AtomicInteger number;

    MyData(String text, int number) {
        this.text = new AtomicReference<String>(text);
        this.number = new AtomicInteger(number);
    }

    public String getText() {
        return text.get();
    }

    public void setText(String text) {
        this.text.set(text);
    }

    public int getNumber() {
        return number.get();
    }

    public void setNumber(int number) {
        this.number.set(number);
    }
}
于 2012-09-10T09:57:25.877 回答
3

您可以使用初始化块自动装箱匿名类很好地做到这一点:

Map table = new ConcurrentHashMap<Integer, Comparable>() {
  {
    this.put(1, "nodata");
    this.put(2, 23);
  }
};
于 2012-09-10T09:54:22.757 回答
1

是的,但不要调用所有这些构造函数(String#new 真的很糟糕,其余的可以自动装箱):

    ConcurrentHashMap<Integer, Comparable> table=
        new ConcurrentHashMap<Integer, Comparable>();
    table.put(1, "nodata");
    table.put(2, 23);

回到你原来的问题,如果你table在这三个语句之后引用另一个线程,它将看到它的最新和最好的版本。在调用两个看跌期权之前不要共享参考。

于 2012-09-10T09:52:22.133 回答
0

您编写的代码是正确的。请注意,您应该使用

    table.put(Integer.valueOf(1), "nodata");
    table.put(Integer.valueOf(2), Integer.valueOf(23));

甚至只是

    table.put(1, "nodata");
    table.put(2, 23);

因为两者Integer.valueOfnew String都有更好的性能,或者至少等于new Integernew String

于 2012-09-10T09:52:58.203 回答
0

您所做的将起作用,但您可能不需要使用所有这些构造函数:

table.put(1, "nodata");
table.put(2, 23);

为了使代码更紧凑(但可能更难理解),您可以这样做:

Map<Integer, Comparable> table=new ConcurrentHashMap<Integer, Comparable>(){{
    put(1, "nodata");
    put(2, 23);
}};

ConcurrentHashMap它创建了一个带有初始化块的匿名子类,该块调用该put方法来初始化地图。

于 2012-09-10T09:53:08.110 回答
0

按照 Thilo 的回答,您可以进一步执行此操作:

ConcurrentHashMap<Integer, Comparable> table=
        new ConcurrentHashMap<Integer, Comparable>() {{
    put(1, "nodata");
    put(2, 23)
  }}

它创建一个派生自您的匿名类HashMap,并从静态初始化程序调用它。它减少了打字,但请注意,它是匿名类的非显而易见的创建。有些人认为这是对匿名类的滥用,以上内容可能应该在有限的场景中使用(例如为单元测试设置数据等)

于 2012-09-10T09:55:27.683 回答