在java.util.abstractList.add上出现不支持的操作异常

iovurdzv  于 2022-12-21  发布在  Java
关注(0)|答案(7)|浏览(267)

我有问题得到一个代码块正常运行。我不完全确定这段代码做什么(我试图得到一个过时的插件,以正常工作与我们的服务器),我只知道每20分钟它运行并抛出一个错误。这里是代码的一部分,其中的问题发生:

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行,即:

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

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

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)
brvekthn

brvekthn1#

您将使用Arrays.asList()Map中创建列表:

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

此方法返回一个由数组支持的不可调整大小的List
返回由指定数组支持的固定大小列表。(对返回列表的更改将"写入"数组。)
要使用可调整大小的List(并实际复制内容),请使用以下代码:

itemStockMap.put(
        item.getInfo(),
        new ArrayList<Integer>(Arrays.asList(item.getStock()))
);
    • 注意:**一般来说,当看到UnsupportedOperationExceptionadd抛出时,这通常表明一些代码试图修改一个不可调整大小或不可修改的集合。

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

ljsrvy3e

ljsrvy3e2#

我想我已经解决了你的问题。Arrays.asList(item.getStock())根据传递给它的Array返回一个**固定大小的列表。
这意味着不能向其中添加更多元素。
相反,您应该执行new ArrayList(Arrays.asList(item.getStock()))
这样,您就创建了一个可以添加内容的新列表。

mefy6pfw

mefy6pfw3#

问题是您正在使用Arrays.asList创建列表。根据提供的javadoc,返回的列表是Fixed Size,因此不支持add。将返回的列表 Package 在arrayList的复制构造函数中,您应该设置。

gdrx4gfi

gdrx4gfi4#

在我的案例中,我使用了:

List<File> removeFilesList= Collections.emptyList();

这使得我的文件数组列表抽象化。

List<File> removeFilesList= new ArrayList<>();

错误已修复。

h7appiyu

h7appiyu5#

List是接口,只有当它是ArrayList的示例时才能在其中添加值(接口应由某个类实现)
例如:

List<Integer> test = new ArrayList<>();
    test.add(new Integer(2));

    ArrayList<Integer> test2 = new ArrayList<>();
    test2.add(new Integer(2));

    List<Integer> test3 = Collections.EMPTY_LIST;
    test3.add(new Integer(2));

这里Objecttesttest2是完美的,因为它们是ArrayList类的对象,所以可以相加
而在test3中,它只是一个空列表,因此您无法在其中添加元素。
我也犯了同样的错误。
这里是我的建议使用数组列表时,你必须做的操作,如添加或删除,使用列表仅供参考。

Map<ItemInfo, ArrayList<Integer>> itemStockMap = Collections.synchronizedMap(new HashMap<ItemInfo, ArrayList<Integer>>());
e5nqia27

e5nqia276#

问题出在get调用返回的list对象的类中,它没有适当地覆盖add方法,因此您的代码使用了AbstractList提供的占位符方法。
如果不知道list类是什么,并且(如果它是定制代码)没有看到源代码,我们就不能说太多。

ibps3vxo

ibps3vxo7#

我用getter来获取列表,但是它返回的是固定大小的列表,你不能添加新元素,所以,
相反你应该

new ArrayList(Arrays.asList(item.getStock()))

相关问题