List related rework and cleanup.
This commit is contained in:
@ -19,6 +19,7 @@ package org.l2jmobius.gameserver.model;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@ -414,15 +415,14 @@ public class World
|
||||
final WorldRegion[] surroundingRegions = oldRegion.getSurroundingRegions();
|
||||
for (int i = 0; i < surroundingRegions.length; i++)
|
||||
{
|
||||
final List<WorldObject> visibleObjects = surroundingRegions[i].getVisibleObjects();
|
||||
for (int j = 0; j < visibleObjects.size(); j++)
|
||||
final Collection<WorldObject> visibleObjects = surroundingRegions[i].getVisibleObjects();
|
||||
if (visibleObjects.isEmpty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (WorldObject wo : visibleObjects)
|
||||
{
|
||||
final WorldObject wo = visibleObjects.get(j);
|
||||
if (wo == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove the WorldObject from the WorldObjectHashSet(WorldObject) _knownObjects of the surrounding WorldRegion Creatures
|
||||
// If object is a Player, remove the WorldObject from the WorldObjectHashSet(Player) _knownPlayer of the surrounding WorldRegion Creatures
|
||||
// If object is targeted by one of the surrounding WorldRegion Creatures, cancel ATTACK and cast
|
||||
@ -488,21 +488,20 @@ public class World
|
||||
}
|
||||
|
||||
// Create a list in order to contain all visible WorldObject
|
||||
final List<WorldObject> result = new ArrayList<>();
|
||||
final List<WorldObject> result = new LinkedList<>();
|
||||
|
||||
// Go through the list of region
|
||||
final WorldRegion[] surroundingRegions = region.getSurroundingRegions();
|
||||
for (int i = 0; i < surroundingRegions.length; i++)
|
||||
{
|
||||
final List<WorldObject> visibleObjects = surroundingRegions[i].getVisibleObjects();
|
||||
for (int j = 0; j < visibleObjects.size(); j++)
|
||||
final Collection<WorldObject> visibleObjects = surroundingRegions[i].getVisibleObjects();
|
||||
if (visibleObjects.isEmpty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (WorldObject wo : visibleObjects)
|
||||
{
|
||||
final WorldObject wo = visibleObjects.get(j);
|
||||
if (wo == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (wo.equals(object))
|
||||
{
|
||||
continue; // skip our own character
|
||||
@ -554,22 +553,21 @@ public class World
|
||||
final int sqRadius = radius * radius;
|
||||
|
||||
// Create a list in order to contain all visible WorldObject
|
||||
final List<WorldObject> result = new ArrayList<>();
|
||||
final List<WorldObject> result = new LinkedList<>();
|
||||
|
||||
// Go through the list of region
|
||||
final WorldRegion[] surroundingRegions = region.getSurroundingRegions();
|
||||
for (int i = 0; i < surroundingRegions.length; i++)
|
||||
{
|
||||
// Go through visible objects of the selected region
|
||||
final List<WorldObject> visibleObjects = surroundingRegions[i].getVisibleObjects();
|
||||
for (int j = 0; j < visibleObjects.size(); j++)
|
||||
final Collection<WorldObject> visibleObjects = surroundingRegions[i].getVisibleObjects();
|
||||
if (visibleObjects.isEmpty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (WorldObject wo : visibleObjects)
|
||||
{
|
||||
final WorldObject wo = visibleObjects.get(j);
|
||||
if (wo == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (wo.equals(object))
|
||||
{
|
||||
continue; // skip our own character
|
||||
@ -619,21 +617,20 @@ public class World
|
||||
final int sqRadius = radius * radius;
|
||||
|
||||
// Create a list in order to contain all visible WorldObject
|
||||
final List<WorldObject> result = new ArrayList<>();
|
||||
final List<WorldObject> result = new LinkedList<>();
|
||||
|
||||
// Go through visible object of the selected region
|
||||
final WorldRegion[] surroundingRegions = object.getWorldRegion().getSurroundingRegions();
|
||||
for (int i = 0; i < surroundingRegions.length; i++)
|
||||
{
|
||||
final List<WorldObject> visibleObjects = surroundingRegions[i].getVisibleObjects();
|
||||
for (int j = 0; j < visibleObjects.size(); j++)
|
||||
final Collection<WorldObject> visibleObjects = surroundingRegions[i].getVisibleObjects();
|
||||
if (visibleObjects.isEmpty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (WorldObject wo : visibleObjects)
|
||||
{
|
||||
final WorldObject wo = visibleObjects.get(j);
|
||||
if (wo == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (wo.equals(object))
|
||||
{
|
||||
continue; // skip our own character
|
||||
|
@ -17,8 +17,11 @@
|
||||
package org.l2jmobius.gameserver.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.logging.Logger;
|
||||
@ -39,19 +42,18 @@ import org.l2jmobius.gameserver.model.zone.ZoneManager;
|
||||
import org.l2jmobius.gameserver.model.zone.ZoneType;
|
||||
import org.l2jmobius.gameserver.model.zone.type.PeaceZone;
|
||||
import org.l2jmobius.gameserver.taskmanager.RandomAnimationTaskManager;
|
||||
import org.l2jmobius.gameserver.util.UnboundArrayList;
|
||||
|
||||
public class WorldRegion
|
||||
{
|
||||
private static final Logger LOGGER = Logger.getLogger(WorldRegion.class.getName());
|
||||
|
||||
private final UnboundArrayList<WorldObject> _visibleObjects = new UnboundArrayList<>();
|
||||
private final Set<WorldObject> _visibleObjects = ConcurrentHashMap.newKeySet();
|
||||
private final List<Door> _doors = new ArrayList<>(1);
|
||||
private final List<Fence> _fences = new ArrayList<>(1);
|
||||
private WorldRegion[] _surroundingRegions;
|
||||
private final int _regionX;
|
||||
private final int _regionY;
|
||||
private Boolean _active = Config.GRIDS_ALWAYS_ON;
|
||||
private boolean _active = Config.GRIDS_ALWAYS_ON;
|
||||
private ScheduledFuture<?> _neighborsTask = null;
|
||||
private final AtomicInteger _activeNeighbors = new AtomicInteger();
|
||||
private ZoneManager _zoneManager;
|
||||
@ -125,18 +127,17 @@ public class WorldRegion
|
||||
_zoneManager.onRevive(creature);
|
||||
}
|
||||
|
||||
private void switchAI(Boolean isOn)
|
||||
private void switchAI(boolean isOn)
|
||||
{
|
||||
if (_visibleObjects.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isOn)
|
||||
{
|
||||
for (int i = 0; i < _visibleObjects.size(); i++)
|
||||
for (WorldObject wo : _visibleObjects)
|
||||
{
|
||||
final WorldObject wo = _visibleObjects.get(i);
|
||||
if (wo == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (wo instanceof Attackable)
|
||||
{
|
||||
final Attackable mob = (Attackable) wo;
|
||||
@ -182,14 +183,8 @@ public class WorldRegion
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < _visibleObjects.size(); i++)
|
||||
for (WorldObject wo : _visibleObjects)
|
||||
{
|
||||
final WorldObject wo = _visibleObjects.get(i);
|
||||
if (wo == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (wo instanceof Attackable)
|
||||
{
|
||||
// Start HP/MP/CP Regeneration task
|
||||
@ -231,17 +226,22 @@ public class WorldRegion
|
||||
final WorldRegion worldRegion = _surroundingRegions[i];
|
||||
if (worldRegion.isActive())
|
||||
{
|
||||
final List<WorldObject> regionObjects = worldRegion.getVisibleObjects();
|
||||
for (int j = 0; j < regionObjects.size(); j++)
|
||||
final Collection<WorldObject> regionObjects = worldRegion.getVisibleObjects();
|
||||
if (regionObjects.isEmpty())
|
||||
{
|
||||
final WorldObject wo = regionObjects.get(j);
|
||||
if ((wo != null) && wo.isPlayable())
|
||||
continue;
|
||||
}
|
||||
|
||||
for (WorldObject wo : regionObjects)
|
||||
{
|
||||
if (wo.isPlayable())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -347,7 +347,7 @@ public class WorldRegion
|
||||
return;
|
||||
}
|
||||
|
||||
_visibleObjects.addIfAbsent(object);
|
||||
_visibleObjects.add(object);
|
||||
|
||||
if (object.isDoor())
|
||||
{
|
||||
@ -410,7 +410,7 @@ public class WorldRegion
|
||||
}
|
||||
}
|
||||
|
||||
public List<WorldObject> getVisibleObjects()
|
||||
public Collection<WorldObject> getVisibleObjects()
|
||||
{
|
||||
return _visibleObjects;
|
||||
}
|
||||
@ -478,14 +478,8 @@ public class WorldRegion
|
||||
public synchronized void deleteVisibleNpcSpawns()
|
||||
{
|
||||
LOGGER.info("Deleting all visible NPCs in Region: " + getName());
|
||||
for (int i = 0; i < _visibleObjects.size(); i++)
|
||||
for (WorldObject wo : _visibleObjects)
|
||||
{
|
||||
final WorldObject wo = _visibleObjects.get(i);
|
||||
if (wo == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (wo instanceof Npc)
|
||||
{
|
||||
final Npc target = (Npc) wo;
|
||||
|
@ -16,8 +16,8 @@
|
||||
*/
|
||||
package org.l2jmobius.gameserver.model.itemcontainer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.l2jmobius.gameserver.model.actor.Player;
|
||||
@ -81,7 +81,7 @@ public class PlayerFreight extends ItemContainer
|
||||
@Override
|
||||
public Collection<Item> getItems()
|
||||
{
|
||||
final List<Item> result = new ArrayList<>();
|
||||
final List<Item> result = new LinkedList<>();
|
||||
for (Item item : _items)
|
||||
{
|
||||
if ((item.getEquipSlot() == 0) || (item.getEquipSlot() == _activeLocationId))
|
||||
|
@ -19,18 +19,18 @@ package org.l2jmobius.gameserver.model.itemcontainer;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.l2jmobius.commons.database.DatabaseFactory;
|
||||
import org.l2jmobius.gameserver.model.TradeList;
|
||||
import org.l2jmobius.gameserver.model.TradeList.TradeItem;
|
||||
import org.l2jmobius.gameserver.model.WorldObject;
|
||||
import org.l2jmobius.gameserver.model.actor.Player;
|
||||
import org.l2jmobius.gameserver.model.item.ItemTemplate;
|
||||
import org.l2jmobius.gameserver.model.item.instance.Item;
|
||||
import org.l2jmobius.gameserver.model.item.instance.Item.ItemLocation;
|
||||
import org.l2jmobius.gameserver.model.item.type.EtcItemType;
|
||||
import org.l2jmobius.gameserver.model.WorldObject;
|
||||
|
||||
public class PlayerInventory extends Inventory
|
||||
{
|
||||
@ -99,7 +99,7 @@ public class PlayerInventory extends Inventory
|
||||
|
||||
public List<Item> getUniqueItems(boolean allowAdena, boolean allowAncientAdena, boolean onlyAvailable, boolean allowEquipped)
|
||||
{
|
||||
final List<Item> list = new ArrayList<>();
|
||||
final List<Item> list = new LinkedList<>();
|
||||
for (Item item : _items)
|
||||
{
|
||||
if (!allowAdena && (item.getItemId() == 57))
|
||||
@ -143,7 +143,7 @@ public class PlayerInventory extends Inventory
|
||||
|
||||
public List<Item> getUniqueItemsByEnchantLevel(boolean allowAdena, boolean allowAncientAdena, boolean onlyAvailable, boolean allowEquipped)
|
||||
{
|
||||
final List<Item> list = new ArrayList<>();
|
||||
final List<Item> list = new LinkedList<>();
|
||||
for (Item item : _items)
|
||||
{
|
||||
if (!allowAdena && (item.getItemId() == 57))
|
||||
@ -181,7 +181,7 @@ public class PlayerInventory extends Inventory
|
||||
*/
|
||||
public List<Item> getAllItemsByItemId(int itemId)
|
||||
{
|
||||
final List<Item> list = new ArrayList<>();
|
||||
final List<Item> list = new LinkedList<>();
|
||||
for (Item item : _items)
|
||||
{
|
||||
if (item.getItemId() == itemId)
|
||||
@ -200,7 +200,7 @@ public class PlayerInventory extends Inventory
|
||||
*/
|
||||
public List<Item> getAllItemsByItemId(int itemId, int enchantment)
|
||||
{
|
||||
final List<Item> list = new ArrayList<>();
|
||||
final List<Item> list = new LinkedList<>();
|
||||
for (Item item : _items)
|
||||
{
|
||||
if ((item.getItemId() == itemId) && (item.getEnchantLevel() == enchantment))
|
||||
@ -218,7 +218,7 @@ public class PlayerInventory extends Inventory
|
||||
*/
|
||||
public List<Item> getAvailableItems(boolean allowAdena)
|
||||
{
|
||||
final List<Item> list = new ArrayList<>();
|
||||
final List<Item> list = new LinkedList<>();
|
||||
for (Item item : _items)
|
||||
{
|
||||
if ((item != null) && item.isAvailable(_owner, allowAdena, false))
|
||||
@ -235,7 +235,7 @@ public class PlayerInventory extends Inventory
|
||||
*/
|
||||
public List<Item> getAugmentedItems()
|
||||
{
|
||||
final List<Item> list = new ArrayList<>();
|
||||
final List<Item> list = new LinkedList<>();
|
||||
for (Item item : _items)
|
||||
{
|
||||
if ((item != null) && item.isAugmented())
|
||||
@ -253,7 +253,7 @@ public class PlayerInventory extends Inventory
|
||||
*/
|
||||
public List<TradeItem> getAvailableItems(TradeList tradeList)
|
||||
{
|
||||
final List<TradeItem> list = new ArrayList<>();
|
||||
final List<TradeItem> list = new LinkedList<>();
|
||||
for (Item item : _items)
|
||||
{
|
||||
if (item.isAvailable(_owner, false, false))
|
||||
|
@ -17,9 +17,11 @@
|
||||
package org.l2jmobius.gameserver.taskmanager;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@ -28,7 +30,6 @@ import org.l2jmobius.commons.util.Chronos;
|
||||
import org.l2jmobius.gameserver.ai.CtrlEvent;
|
||||
import org.l2jmobius.gameserver.instancemanager.DayNightSpawnManager;
|
||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
||||
import org.l2jmobius.gameserver.util.UnboundArrayList;
|
||||
|
||||
/**
|
||||
* Game Time task manager class.
|
||||
@ -45,7 +46,7 @@ public class GameTimeTaskManager
|
||||
protected static long _gameStartTime;
|
||||
protected static boolean _isNight = false;
|
||||
|
||||
private static final UnboundArrayList<Creature> _movingObjects = new UnboundArrayList<>();
|
||||
private static final Set<Creature> _movingObjects = ConcurrentHashMap.newKeySet();
|
||||
|
||||
protected static TimerThread _timer;
|
||||
private final ScheduledFuture<?> _timerWatcher;
|
||||
@ -102,7 +103,7 @@ public class GameTimeTaskManager
|
||||
return;
|
||||
}
|
||||
|
||||
_movingObjects.addIfAbsent(creature);
|
||||
_movingObjects.add(creature);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -119,30 +120,20 @@ public class GameTimeTaskManager
|
||||
*/
|
||||
protected void moveObjects()
|
||||
{
|
||||
List<Creature> finished = null;
|
||||
for (int i = 0; i < _movingObjects.size(); i++)
|
||||
final List<Creature> finished = new LinkedList<>();
|
||||
for (Creature creature : _movingObjects)
|
||||
{
|
||||
final Creature creature = _movingObjects.get(i);
|
||||
if (creature == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (creature.updatePosition(_gameTicks))
|
||||
{
|
||||
if (finished == null)
|
||||
{
|
||||
finished = new ArrayList<>();
|
||||
}
|
||||
finished.add(creature);
|
||||
}
|
||||
}
|
||||
|
||||
if (finished != null)
|
||||
if (!finished.isEmpty())
|
||||
{
|
||||
for (int i = 0; i < finished.size(); i++)
|
||||
for (Creature creature : finished)
|
||||
{
|
||||
_movingObjects.remove(finished.get(i));
|
||||
_movingObjects.remove(creature);
|
||||
}
|
||||
ThreadPool.execute(new MovingObjectArrived(finished));
|
||||
}
|
||||
|
@ -1,336 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Pantelis Andrianakis
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
package org.l2jmobius.gameserver.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Unbound and synchronized implementation of the {@code ArrayList} class.<br>
|
||||
* In addition to implementing the {@code ArrayList} class,<br>
|
||||
* this class provides synchronization on adding and removing elements.<br>
|
||||
* Further more, get() does not throw IndexOutOfBoundsException, a {@code null} element is returned instead.<br>
|
||||
* An equivalent Iterator constructor is introduced under the same logic.
|
||||
* @param <E> the type of elements in this list
|
||||
* @version September 4th 2020
|
||||
* @author Pantelis Andrianakis
|
||||
*/
|
||||
public class UnboundArrayList<E>extends ArrayList<E>
|
||||
{
|
||||
/**
|
||||
* Returns the element at the specified position in this list.
|
||||
* @param index index of the element to return
|
||||
* @return the element at the specified position in this list,<br>
|
||||
* or {@code null} if this list does not have this specified position.
|
||||
*/
|
||||
@Override
|
||||
public E get(int index)
|
||||
{
|
||||
E element = null;
|
||||
|
||||
try
|
||||
{
|
||||
// The try performance impact itself is insignificant.
|
||||
// Benchmark test on an i7-2600 machine with a list of 100.000.000 random elements.
|
||||
// get: Execution time was 116 milliseconds.
|
||||
// get with try: Execution time was 124 milliseconds.
|
||||
element = super.get(index);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// Continue with execution.
|
||||
// This impacts performance only if the Exception is created.
|
||||
// Benchmark test on an i7-2600 machine resulted with a 187 millisecond total delay,
|
||||
// in a list of 10.000 elements, with IndexOutOfBoundsException thrown on 5.000 of them.
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the element at the specified position in this list with the specified element.
|
||||
* @param index index of the element to replace
|
||||
* @param element element to be stored at the specified position
|
||||
* @return the element previously at the specified position,<br>
|
||||
* or {@code null} if this list does not have this specified position.
|
||||
*/
|
||||
@Override
|
||||
public E set(int index, E element)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if ((index >= 0) && (index < size()))
|
||||
{
|
||||
return super.set(index, element);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the specified element to the end of this list.
|
||||
* @param e element to be appended to this list
|
||||
* @return {@code true} (as specified by {@link Collection#add})
|
||||
*/
|
||||
@Override
|
||||
public boolean add(E e)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
return super.add(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the specified element at the specified position in this list. Shifts the element currently at that position (if any) and any subsequent elements to the right (adds one to their indices).
|
||||
* @param index index at which the specified element is to be inserted
|
||||
* @param element element to be inserted
|
||||
*/
|
||||
@Override
|
||||
public void add(int index, E element)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if ((index >= 0) && (index < size()))
|
||||
{
|
||||
super.add(index, element);
|
||||
}
|
||||
else
|
||||
{
|
||||
super.add(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the specified element to the end of this list if this list does not contain the specified element.
|
||||
* @param e element to be appended to this list
|
||||
* @return {@code true} (as specified by {@link Collection#add})
|
||||
*/
|
||||
public boolean addIfAbsent(E e)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (!contains(e))
|
||||
{
|
||||
return super.add(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the first occurrence of the specified element from this list, if it is present. If the list does not contain the element, it is unchanged. More formally, removes the element with the lowest index {@code i} such that {@code Objects.equals(o, get(i))} (if such an element exists).
|
||||
* Returns {@code true} if this list contained the specified element (or equivalently, if this list changed as a result of the call).
|
||||
* @param o element to be removed from this list, if present
|
||||
* @return {@code true} if this list contained the specified element
|
||||
*/
|
||||
@Override
|
||||
public boolean remove(Object o)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
return super.remove(o);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the element at the specified position in this list. Shifts any subsequent elements to the left (subtracts one from their indices).
|
||||
* @param index the index of the element to be removed
|
||||
* @return the element that was removed from the list,<br>
|
||||
* or {@code null} if this list does not have this specified position.
|
||||
*/
|
||||
@Override
|
||||
public E remove(int index)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if ((index >= 0) && (index < size()))
|
||||
{
|
||||
return super.remove(index);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all of the elements from this list.<br>
|
||||
* The list will be empty after this call returns.
|
||||
*/
|
||||
@Override
|
||||
public void clear()
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
super.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends all of the elements in the specified collection to the end of this list, in the order that they are returned by the specified collection's Iterator. The behavior of this operation is undefined if the specified collection is modified while the operation is in progress. (This implies
|
||||
* that the behavior of this call is undefined if the specified collection is this list, and this list is nonempty.)
|
||||
* @param c collection containing elements to be added to this list
|
||||
* @return {@code true} if this list changed as a result of the call
|
||||
* @throws NullPointerException if the specified collection is null
|
||||
*/
|
||||
@Override
|
||||
public boolean addAll(Collection<? extends E> c)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
return super.addAll(c);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts all of the elements in the specified collection into this list, starting at the specified position. Shifts the element currently at that position (if any) and any subsequent elements to the right (increases their indices). The new elements will appear in the list in the order that
|
||||
* they are returned by the specified collection's iterator.
|
||||
* @param index index at which to insert the first element from the specified collection
|
||||
* @param c collection containing elements to be added to this list
|
||||
* @return {@code true} if this list changed as a result of the call
|
||||
* @throws NullPointerException if the specified collection is null
|
||||
*/
|
||||
@Override
|
||||
public boolean addAll(int index, Collection<? extends E> c)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if ((index >= 0) && (index < size()))
|
||||
{
|
||||
return super.addAll(index, c);
|
||||
}
|
||||
return super.addAll(c);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes from this list all of the elements whose index is between {@code fromIndex}, inclusive, and {@code toIndex}, exclusive. Shifts any succeeding elements to the left (reduces their index). This call shortens the list by {@code (toIndex - fromIndex)} elements.
|
||||
*/
|
||||
@Override
|
||||
protected void removeRange(int fromIndex, int toIndex)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (fromIndex > size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
super.removeRange(fromIndex < 0 ? 0 : fromIndex, size() < toIndex ? size() - 1 : toIndex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes from this list all of its elements that are contained in the specified collection.
|
||||
* @param c collection containing elements to be removed from this list
|
||||
* @return {@code true} if this list changed as a result of the call
|
||||
* @throws ClassCastException if the class of an element of this list is incompatible with the specified collection (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws NullPointerException if this list contains a null element and the specified collection does not permit null elements (<a href="Collection.html#optional-restrictions">optional</a>), or if the specified collection is null
|
||||
* @see Collection#contains(Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean removeAll(Collection<?> c)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
return super.removeAll(c);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retains only the elements in this list that are contained in the specified collection. In other words, removes from this list all of its elements that are not contained in the specified collection.
|
||||
* @param c collection containing elements to be retained in this list
|
||||
* @return {@code true} if this list changed as a result of the call
|
||||
* @throws ClassCastException if the class of an element of this list is incompatible with the specified collection (<a href="Collection.html#optional-restrictions">optional</a>)
|
||||
* @throws NullPointerException if this list contains a null element and the specified collection does not permit null elements (<a href="Collection.html#optional-restrictions">optional</a>), or if the specified collection is null
|
||||
* @see Collection#contains(Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean retainAll(Collection<?> c)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
return super.retainAll(c);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator over the elements in this list in proper sequence.
|
||||
* @return an iterator over the elements in this list in proper sequence.<br>
|
||||
* Non existing elements are returned as null.
|
||||
*/
|
||||
@Override
|
||||
public Iterator<E> iterator()
|
||||
{
|
||||
return new Itr();
|
||||
}
|
||||
|
||||
/**
|
||||
* An optimized version of AbstractList.Itr
|
||||
*/
|
||||
private class Itr implements Iterator<E>
|
||||
{
|
||||
private int _cursor = 0; // index of next element to return
|
||||
|
||||
// prevent creating a synthetic constructor
|
||||
Itr()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext()
|
||||
{
|
||||
return _cursor < size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E next()
|
||||
{
|
||||
return get(_cursor++);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove()
|
||||
{
|
||||
UnboundArrayList.this.remove(get(_cursor - 1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEachRemaining(Consumer<? super E> action)
|
||||
{
|
||||
if (action == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (int i = _cursor; i < size(); i++)
|
||||
{
|
||||
final E next = get(i);
|
||||
if (next != null)
|
||||
{
|
||||
action.accept(next);
|
||||
}
|
||||
_cursor++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user