java.util.AbstractList.add 处的 UnsupportedOperationException [英] UnsupportedOperationException at java.util.AbstractList.add

查看:27
本文介绍了java.util.AbstractList.add 处的 UnsupportedOperationException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在让代码块正常运行时遇到问题.我不完全确定这段代码是做什么的(我试图让一个过时的插件与我们的服务器一起正常工作),我只知道它每运行 20 分钟就会抛出一个错误.这是发生问题的代码部分:

I'm having issues getting a block of code to run properly. I'm not entirely sure WHAT this code does (I'm trying to get a plugin that's out of date to work properly with our server), I just know every 20 minutes it runs and throws out an error. Here's the section of code where the issue is happening:

public class DynamicThread extends Thread {
private LocalShops plugin = null;


public DynamicThread(ThreadGroup tgroup, String tname, LocalShops plugin) {
    super(tgroup, tname);
    this.plugin = plugin;
}

public void run() {
    Map<ItemInfo, List<Integer>> itemStockMap = Collections.synchronizedMap(new HashMap<ItemInfo, List<Integer>>());

    //Dump all the shop stock data into the map.
    for ( Shop shop : plugin.getShopManager().getAllShops() ) {
        for ( InventoryItem item : shop.getItems() ) {
            if (itemStockMap.containsKey(item.getInfo()))
                itemStockMap.get(item.getInfo()).add(item.getStock()); //Where error happens
            else
                itemStockMap.put(item.getInfo(), Arrays.asList(item.getStock()));     
        }
    }
    for(ItemInfo item : itemStockMap.keySet()) {
        List<Integer> stockList = GenericFunctions.limitOutliers(itemStockMap.get(item));
        //remove the map before re-adding it
        if (DynamicManager.getPriceAdjMap().containsKey(item)) 
            DynamicManager.getPriceAdjMap().remove(item);

        //Get the overall stock change for a given item and then calculate the adjustment given the volatility
        int deltaStock = GenericFunctions.getSum(stockList) - Config.getGlobalBaseStock();
        DynamicManager.getPriceAdjMap().put(item, GenericFunctions.getAdjustment(Config.getGlobalVolatility(), deltaStock)); 
    }

    Bukkit.getServer().getScheduler().callSyncMethod(plugin, plugin.getShopManager().updateSigns());
}

}

错误发生在第 42 行,即:

The error happens from line 42, which is:

                itemStockMap.get(item.getInfo()).add(item.getStock());

它输出的错误每 20 分钟发生两次,中间间隔 2 秒.

The error it outputs happens every 20 minutes twice with 2 seconds in between.

2012-02-16 16:53:25 [INFO] Launch Dynamic Thread
2012-02-16 16:53:25 [SEVERE] Exception in thread "dynamic" 
2012-02-16 16:53:25 [SEVERE] java.lang.UnsupportedOperationException
2012-02-16 16:53:25 [SEVERE] at java.util.AbstractList.add(AbstractList.java:131)
2012-02-16 16:53:25 [SEVERE] at java.util.AbstractList.add(AbstractList.java:91)
2012-02-16 16:53:25 [SEVERE] at       com.milkbukkit.localshops.threads.DynamicThread.run(DynamicThread.java:42)

2012-02-16 16:53:27 [INFO] Launch Dynamic Thread
2012-02-16 16:53:27 [SEVERE] Exception in thread "dynamic" 
2012-02-16 16:53:27 [SEVERE] java.lang.UnsupportedOperationException
2012-02-16 16:53:27 [SEVERE] at java.util.AbstractList.add(AbstractList.java:131)
2012-02-16 16:53:27 [SEVERE] at java.util.AbstractList.add(AbstractList.java:91)
2012-02-16 16:53:27 [SEVERE] at     com.milkbukkit.localshops.threads.DynamicThread.run(DynamicThread.java:42)

在此先感谢您的帮助.

推荐答案

您正在使用 Arrays.asList() 在此处创建 Map 中的列表:

You're using Arrays.asList() to create the lists in the Map here:

itemStockMap.put(item.getInfo(), Arrays.asList(item.getStock()));  

此方法返回由数组支持的不可调整大小的 List.来自该方法的文档:

This method returns a non-resizable List backed by the array. From that method's documentation:

返回由指定数组支持的固定大小列表.(更改为返回的列表直写"到数组中.)

Returns a fixed-size list backed by the specified array. (Changes to the returned list "write through" to the array.)

为了使用可调整大小的 List(并实际复制内容),请使用以下内容:

In order to use a resizable List (and actually copy the contents), use the following:

itemStockMap.put(
        item.getInfo(),
        new ArrayList<Integer>(Arrays.asList(item.getStock()))
); 

<小时>

注意:一般来说,当看到 UnsupportedOperationExceptionadd 等抛出时,通常表明某些代码正在尝试修改不可调整大小或不可修改的集合.


Note: in general, when seeing that UnsupportedOperationException is being thrown by add, etc. it's typically an indication that some code is trying to modify a non-resizable or unmodifiable collection.

例如,Collections.emptyListCollections.singletonList(返回不可修改的集合)可能被用作优化,但意外地被传递到尝试修改它们的方法中.出于这个原因,方法在修改集合之前制作防御性副本是一种很好的做法(除非修改集合是方法的预期副作用) - 这样调用者可以自由地使用最合适的集合实现,而不必担心它是否需要可以修改.

For example, Collections.emptyList or Collections.singletonList (which return unmodifiable collections) may be used as optimizations but accidentally be passed into methods that try to modify them. For this reason it's good practice for methods to make defensive copies of collections before modifying them (unless of course modifying the collection is a method's intended side effect) - that way callers are free to use the most appropriate collection implementation without worrying about whether it needs to be modifiable.

这篇关于java.util.AbstractList.add 处的 UnsupportedOperationException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆