content: package com.alibaba.json.bvt.issue_2200.issue2224;
  
  import java.util.Collection;
  import java.util.Iterator;
  import java.util.LinkedHashMap;
  import java.util.Map;
  
  public abstract class KeyedCollection<TKey, TItem> implements CollectionEx<TItem>, Cloneable {
      private transient Map<TKey, TItem> items = new LinkedHashMap<TKey, TItem>();
  
      protected abstract TKey getKeyForItem(TItem item);
  
      public TItem get(TKey key) {
          return this.items.get(key);
      }
  
      //region override
  
      public int size() {
          return this.items.size();
      }
  
      public boolean isEmpty() {
          return this.items.isEmpty();
      }
  
      public boolean contains(Object key) {
          return this.items.containsKey(key);
      }
  
      public Iterator<TItem> iterator() {
          return this.items.values().iterator();
      }
  
      public Object[] toArray() {
          return this.items.values().toArray();
      }
  
      public <T> T[] toArray(T[] a) {
          return this.items.values().toArray(a);
      }
  
      public boolean add(TItem item) {
          if (item == null)
              throw new IllegalArgumentException("item can not be null.");
          TKey key = this.getKeyForItem(item);
          this.items.put(key, item);
          return true;
      }
  
      public boolean remove(Object key) {
          return this.items.remove(key) != null;
      }
  
      public boolean containsAll(Collection<?> keys) {
          return this.items.keySet().containsAll(keys);
      }
  
      public boolean addAll(Collection<? extends TItem> items) {
          boolean modified = false;
          for (TItem item : items)
              modified |= this.add(item);
          return modified;
      }
  
      public boolean removeAll(Collection<?> keys) {
          boolean modified = false;
          for (Object key : keys)
              modified |= this.remove(key);
          return modified;
      }
  
      public boolean retainAll(Collection<?> keys) {
          boolean modified = false;
          for (TKey key : this.items.keySet()) {
              if (!keys.contains(key))
                  modified |= this.remove(key);
          }
          return modified;
      }
  
      public void clear() {
          this.items.clear();
      }
  
      @Override
      public String toString() {
          StringBuilder builder = new StringBuilder();
          builder.append('[');
          TItem item;
          Iterator<TItem> iterator = this.iterator();
          if (iterator.hasNext()) {
              item = iterator.next();
              builder.append(item == this ? "(this Collection)" : item);
          }
          while (iterator.hasNext()) {
              item = iterator.next();
              builder.append(", ").append(item == this ? "(this Collection)" : item);
          }
          builder.append(']');
          return builder.toString();
      }
  
      //endregion
  }
  