Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UnsupportedOperationException at java.util.AbstractList.add

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()); } 

}

The error happens from line 42, which is:

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

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) 

Thanks in advance for any help.

like image 698
Erickj92 Avatar asked Feb 16 '12 22:02

Erickj92


People also ask

How do I resolve UnsupportedOperationException in Java?

The UnsupportedOperationException can be resolved by using a mutable collection, such as ArrayList , which can be modified. An unmodifiable collection or data structure should not be attempted to be modified.

How do you add to a List in Java?

There are two methods to add elements to the list. add(E e): appends the element at the end of the list. Since List supports Generics, the type of elements that can be added is determined when the list is created. add(int index, E element): inserts the element at the given index.

What is List of () in Java?

The List interface in Java provides a way to store the ordered collection. It is a child interface of Collection. It is an ordered collection of objects in which duplicate values can be stored. Since List preserves the insertion order, it allows positional access and insertion of elements.

Which of the following operation's are not supported on the List created above using the asList () method?

asList returns a fixed size List backed by an array. Therefore remove and add are not supported.


2 Answers

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

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

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

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())) );  

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.

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.

like image 131
Paul Bellora Avatar answered Sep 24 '22 01:09

Paul Bellora


I think I've worked out your problem. Arrays.asList(item.getStock()) returns a fixed size list based on the Array passed to it.

This means you cannot add more elements to it.

Instead you should do new ArrayList(Arrays.asList(item.getStock())).

This way you are creating a new list that you can add to.

like image 25
Jivings Avatar answered Sep 24 '22 01:09

Jivings