2016-03-27 5 views
1

У меня есть этот кодjava.lang.UnsupportedOperationException ImmutableList.remove, когда я не использовал ImmutableList

final List<String> connectedIds = getConnectedDevices(); 
    final List<Device> allDbDevicesAsList = getAllDbDevicesAsList(); 

    List<Device> connectedDevices = new ArrayList<>(); 
    for (int i = 0; i < allDbDevicesAsList.size(); i++) { 
     int size = connectedIds.size(); 
     for (int j = 0; j < size; j++) { 
      final Device currentDevice = allDbDevicesAsList.get(i); 
      if(currentDevice.uuid == connectedIds.get(j)) 
      { 
       connectedDevices.add(currentDevice); 
       connectedIds.remove(j); 
       break; 
      } 
     } 
    } 

и я получаю это исключение, даже думал, что я не использую ImmutableList

и я вырыл во всех методах вызовы getConnectedDevices()

java.lang.UnsupportedOperationException 
    at com.google.common.collect.ImmutableList.remove(ImmutableList.java:479) 
    at com.waze.automation.client.services.web.lib.devices.DevicesServiceLocal.getDevices(DevicesServiceLocal.java:66) 
    at com.waze.mobileautomation.devices.DevicesServiceLocalTest.testGetAvailableDevices_returnsOnly(DevicesServiceLocalTest.java:194) 

, используя этот код получит ту же логику пересечения, но менее эффективно.

List<Device> connectedDevices = allDbDevicesAsList.stream() 
      .filter(item -> connectedIds.contains(item.uuid)) 
      .collect(Collectors.toList()); 

Как бы вы переписали код пересечения?

Почему я все равно получаю эту ошибку?

+3

Похоже, 'getConnectedDevices()' возвращает 'ImmutableList'. – resueman

+0

, и я выкопал все вызовы методов 'getConnectedDevices()' –

ответ

1

Составьте копию подключенного устройства. List. Эта копия будет изменяться.

List<String> connectedIds = new ArrayList<String>(getConnectedDevices()); 
List<Device> allDbDevicesAsList = getAllDbDevicesAsList(); 

List<Device> connectedDevices = new ArrayList<Device>(); 

for (int i = 0; i < allDbDevicesAsList.size(); i++) { 
    Device currentDevice = allDbDevicesAsList.get(i); 
    boolean removed = connectedIds.remove(currentDevice.uuid); 
    if (removed) { 
     connectedDevices.add(currentDevice); 
    } 
} 

PS: Коллекция идентификатор должен быть Set вместо списка. Например.

Set<String> connectedIds = new HashSet<String>(getConnectedDevices()); 
+0

, но как это может быть неизменным с первого места? так как тогда он должен был бы отбрасывать из неизменяемого списка в изменчивый. и я обыскал все. нет –

+0

@EladBenda Почему вы думаете, 'getConnectedDevices()' не может вернуть 'ImmutableList'? –

+0

Я вижу его подпись 'private List getConnectedDevices() {' –

2

Вы можете передать список идентификаторов устройств из getConnectedDevices (метод) к новому ArrayList:

final List<String> connectedIds = new ArrayList<>(getConnectedDevices()); 

Это будет копировать все значения из ImmutableList в ArrayList, из которого вы можете удалить элементы.

Пример, который вы предоставили с использованием потоков, выглядит гораздо более кратким и понятным. Если это не подтвердило влияние производительности, которое неприемлемо, это будет выглядеть наилучшим образом.

0

Из документа java в нем говорится. это не гарантирует изменчивости.

public static <T> Collector<T,?,List<T>> toList() 

Возвращает коллекционер, который накапливает входные элементы в новый список. Не существует гарантий по типу, изменчивости, сериализуемости или безопасности потоков возвращаемого списка; если требуется больше контроля над возвращенным списком, используйте toCollection (Поставщик). Параметры ввода: T - тип входных элементов Возврат: a Коллектор, который собирает все элементы ввода в список в порядке прихода.

Вы можете попробовать распечатать тип списка, возвращенный функцией getConnectedDevices().

Смежные вопросы