Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (483)
Games in Android Showcase (110)
games submitted by our members
Games in WIP (550)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
  JavaGaming.org - Pastebin



Author: ClickerMonkey (posted 2013-02-15 11:58:10, viewed 250 times)

1   2   3   4   5   6   7   8   9   10   11   12   13   14   15   16   17   18   19   20   21   22   23   24   25   26   27   28   29   30   31   32   33   34   35   36   37   38   39   40   41   42   43   44   45   46   47   48   49   50   51   52   53   54   55   56   57   58   59   60   61   62   63   64   65   66   67   68   69   70   71   72   73   74   75   76   77   78   79   80   81   82   83   84   85   86   87   88   89   90   91   92   93   94   95   96   97   98   99   100   101   102   103   104   105   106   107   108   109   110   111   112   113   114   115   116   117   118   119   120   121   122   123   124   125   126   127   128   129   130   131   132   133   134   135   136   137   138   139   140   141   142   143   144   145   146   147   148   149   150   151   152   153   154   155   156   157   158   159   160   161   162   163   164   165   166   167   168   169   170   171   172   173   174   175   176   177   178   179   180   181   182   183   184   185   186   187   188   189   190   191   192   193   194   195   196   197   198   199   200   201   202   203   204   205   206   207   208   209   210   211   212   213   214   215   216   217   218   219   220   221   222   223   224   225   226   227   228   229   230   231   232   233   234   235   236   237   238   239   240   241   242   243   244   245   246   247   248   249   250   251   252   253   254   255   256   257   258   259   260   261   262   263   264   265   266   267   268   269   270   271   272   273   274   275   276   277   278   279   280   281   282   283   284   285   286   287   288   289   290   291   292   293   294   295   296   297   298   299   300   301   302   303   304   305   306   307   308   309   310   311   312   313   314   315   316   317   318   319   320   321   322   323   324   325   326   327   328   329   330   331   332   333   334   335   336   337   338   339   340   341   342   343   344   345   346   347   348   349   350   351   352   353   354   355   356   357   358   359   360   361   362   363   364   365   366   367   368   369   370   371   372   373   374   375   376   377   378   379   380   381   382   383   384   385   386   387   388   389   390   391   392   393   394   395   396   397   398   399   400   401   402   403   404   405   406   407   408   409   410   411   412   413   414   415   416   417   418   419   420   421   422   423   424   425   426   427   428   429   430   431   432   433   434   435   436   437   438   439   440   441   442   443   444   445   446   447   448   449   450   451   452   453   454   455   456   457   458   459   460   461   462   463   464   465   466   467   468   469   470   471   472   473   474   475   476   477   478   479   480   481   482   483   484   485   486   487   488   489   490   491   492   493   494   495   496   497   498   499   500   501   502   503   504   505   506   507   508   509   510   511   512   513   514   515   516   517   518   519   520   521   522   523   524   525   526   527   528   529   530   531   532   533   534   535   536   537   538   539   540   541   542   543   544   545   546   547   548   549   550   551   552   553   554   555   556   557   558   559   560   561   562   563   564   565   566   567   568   569   570   571   572   573   574   575   576   577   578   579   580   581   582   583   584   585   586   587   588   589   590   591   592   593   594   595   596   597   598   599   600   601   602   603   604   605   606   607   608   609   610   611   612   613   614   615   616   617   618   619   620   621   622   623   624   625   626   627   628   629   630   631   632   633   634   635   636   637   638   639   640   641   642   643   644   645   646   647   648   649   650   651   652   653   654   655   656   657   658   659   660   661   662   663   664   665   666   667   668   669   670   671   672   673   674   675   676   677   678   679   680   681   682   683   684   685   686   687   688   689   690   691   692   693   694   695   696   697   698   699   700   701   702   703   704   705   706   707   708   709   710   711   712   713   714   715   716   717   718   719   720   721   722   723   724   725   726   727   728   729   730   731   732   733   734   735   736   737   738   739   740   741   742   743   744   745   746   747   748   749   750   751   752   753   754   755   756   757   758   759   760   761   762   763   764   765   766   767   768   769   770   771   772   773   774   775   776   777   778   779   780   781   782   783   784   785   786   787   788   789   790   791   792   793   794   795   796   797   798   799   800   801   802   803   804   805   806   807   808   809   810   811   812   813   814   815   816   817   818   819   820   821   822   823   824   825   826   827   828   829   830   831   832   833   834   835   836   837   838   839   840   841   842   843   844   845   846   847   848   849   850   851   852   853   854   855   856   857   858   859   860   861   862   863   864   865   866   867   868   869   870   871   872   873   874   875   876   877   878   879   880   881   882   883   884   885   886   887   888   889   890   891   892   893   894   895   896   897   898   899   900   901   902   903   904   905   906   907   908   909   910   911   912   913   914   915   916   917   918   919   920   921   922   923   924   925   926   927   928   929   930   931   932   933   934   935   936   937   938   939   940   941   942   943   944   945   946   947   948   949   950   951   952   953   954  
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;

/**
 * A map with circular references so that all entries have a next entry and the
 * table is pre-populated with null-key and null-value entries to hold the
 * initial chain of entries. Having circular references enables quick iteration
 * of entries. This map implementation also supports multiple entries with the
 * same key value via the {@link #add(Object, Object)} method.
 * <p>
 * There are supporting methods to handle multiple keys like
 * {@link #entriesWithKey(Object)}, {@link #removeAll(Object)},
 * {@link #countOf(Object)}, {@link #removeAll(Object...)},
 * {@link #getAll(Object, Collection)}, and {@link #removeAll(Iterable)}.
 * </p>
 * <p>
 * There are also supporting methods to handle multiple values like
 * {@link #entriesWithValue(Object)}, {@link #removeAllValue(Iterable)},
 * {@link #removeAllValue(Object...)}, {@link #getAllKeys(Object, Collection)},
 * and {@link #countOfValue(Object)}.
 * </p>
 * <p>
 * This map implementation caches iterators for it's entries, values, keys,
 * entries with a specific key, and entries with a specific value. This is to
 * avoid needless allocation of iterators. The one drawback with this design
 * however is that you must avoid nested iterations over the same iterator -
 * this will not work.
 * </p>
 * <p>
 * This map implementation can also cache entries and reuse them between all
 * instances via the {@link #initPool(int)} method.
 * </p>
 * <p>
 * This map was built with speed and minimizing garbage in mind.
 * </p>
 * <p>
 * The fields of the Entry class are all public, do not modify these values.
 * </p>
 * 
 * @author Philip Diffenderfer
 * 
 * @param <K>
 *            The key type.
 * @param <V>
 *            The value type.
 */
@SuppressWarnings ({"rawtypes","unchecked"})
public class CyclicMap<K, V>
{

   public static final int SIZE_1 = 0;
   public static final int SIZE_2 = 1;
   public static final int SIZE_4 = 2;
   public static final int SIZE_8 = 3;
   public static final int SIZE_16 = 4;
   public static final int SIZE_32 = 5;
   public static final int SIZE_64 = 6;
   public static final int SIZE_128 = 7;
   public static final int SIZE_256 = 8;
   public static final int SIZE_512 = 9;
   public static final int SIZE_1024 = 10;
   public static final int SIZE_2048 = 11;
   public static final int SIZE_4096 = 12;
   
   private final int capacity;
   private final int mod;
   private final Entry<K, V>[] table;
   private int size;

   private final EntryIterable entries;
   private final ValueIterable values;
   private final KeyIterable keys;
   private final MultiKeyIterable multiKey;
   private final MultiValueIterable multiValue;
   
   /**
    * Initializes a CycleMap with a table size of 2<sup>tablePower</sup>.
    */
   public CyclicMap( int tablePower )
   {
      this.capacity = (1 << tablePower);
      this.mod = capacity - 1;
      this.table = new Entry[capacity];
      
      this.entries = new EntryIterable();
      this.values = new ValueIterable();
      this.keys = new KeyIterable();
      this.multiKey = new MultiKeyIterable();
      this.multiValue = new MultiValueIterable();
      
      for (int i = 0; i < capacity; i++) {
         table[i] = newEntry();
         table[i].hash = i;
      }
      
      this.clear( false );
   }
   
   /**
    * Adds an entry to the map with the given key and value, ignoring whether 
    * the key exists in the map already (for opposite behavior see 
    * {@link #put(Object, Object)}).
    */
   public void add(final K key, final V value)
   {
      final int hash = hash( key );
      final int tableIndex = hash & mod;
      final Entry<K, V> first = table[ tableIndex ];
      final Entry<K, V> next = newEntry();
      next.key = key;
      next.value = value;
      next.hash = hash;
      next.next = first.next;
      first.next = next;
      size++;
   }

   /**
    * Adds all entries that exist in the given map to this map.
    * @see #add(Object, Object)
    */
   public void addAll(final Map<K, V> map)
   {
      for (Map.Entry<K, V> entry : map.entrySet())
      {
         add( entry.getKey(), entry.getValue() );
      }
   }

   /**
    * Adds all entries that exist in the given map to this map.
    * @see #add(Object, Object)
    */
   public void addAll(final CyclicMap<K, V> map)
   {
      for (Entry<K, V> entry : map.entries)
      {
         add( entry.key, entry.value );
      }
   }
   
   /**
    * Adds the value to the map if an entry with the given key does not exist
    * already, if it does this method has no affect. Returns true if the
    * value was added, otherwise false.
    */
   public boolean addIfAbsent(final K key, final V value)
   {
      final Entry<K, V> before = beforeKey( key );
      final boolean absent = (before == null);
      
      if (absent)
      {
         add( key, value );
      }
      
      return absent;
   }
   
   /**
    * Adds the value to the map if an entry with the key doesn't exist, 
    * otherwise the old entry with a matching key will have it's value 
    * replaced and the previous value returned. If there are multiple
    * entries in the map with the given key the last added entry will
    * have it's value overridden.
    */
   public V put(final K key, final V value)
   {
      final Entry<K, V> before = beforeKey( key );
      V previousValue = null;
      
      if ( before == null )
      {
         add( key, value );
      }
      else
      {
         Entry<K, V> entry = before.next;
         previousValue = entry.value;
         entry.value = value;
      }
      
      return previousValue;
   }
   
   /**
    * Puts all keys and values from the given map into this map overwriting 
    * any entries with the same keys. If the given map has entries with 
    * duplicate keys the value of the oldest entry will be the one taken. If
    * a destination Collection is given all non-null previous values will
    * be added to it. If the given map has duplicate keys AND a destination is
    * given there is a chance multiple values will be inserted into the 
    * destination that had the same key. Returns the destination passed in.
    */
   public <D extends Collection<V>> D putAll(final CyclicMap<K, V> map, final D destination)
   {
      for (Entry<K, V> entry : map.entries)
      {
         V previous = put( entry.key, entry.value );
         
         if ( previous != null && destination != null )
         {
            destination.add( previous );
         }
      }
      
      return destination;
   }
   
   /**
    * Puts all keys and values from the given map into this map overwriting 
    * any entries with the same keys. If the given map has entries with 
    * duplicate keys the value of the oldest entry will be the one taken. If
    * a destination Collection is given all non-null previous values will
    * be added to it. If the given map has duplicate keys AND a destination is
    * given there is a chance multiple values will be inserted into the 
    * destination that had the same key. Returns the destination passed in.
    */
   public <D extends Collection<V>> D putAll(final Map<K, V> map, final D destination)
   {
      for (Map.Entry<K, V> entry : map.entrySet())
      {
         V previous = put( entry.getKey(), entry.getValue() );
         
         if ( previous != null && destination != null )
         {
            destination.add( previous );
         }
      }
      
      return destination;
   }
   
   /**
    * Returns the value of the last added entry with the given key.
    */
   public V get(final K key)
   {
      final Entry<K, V> before = beforeKey( key );
      
      return ( before == null ? null : before.next.value );
   }
   
   /**
    * Adds all values that exist with the given key to the given destination 
    * and returns the reference to that destination.
    */
   public <D extends Collection<V>> D getAll(final K key, final D destination)
   {
      return stripValues( entriesWithKey( key ), destination );
   }
   
   /**
    * Returns the key of the first entry in the map with the given value.
    */
   public K getKey(final V value)
   {
      final Entry<K, V> before = beforeValue( value );
      
      return ( before == null ? null : before.next.key );
   }
   
   /**
    * Adds all keys that exist with the given value to the given destination
    * and returns the reference to that destination.
    */
   public <D extends Collection<K>> D getAllKeys(final V value, final D destination)
   {
      return stripKeys( entriesWithValue( value ), destination );
   }
   
   /**
    * Removes the last added entry from the map with the given key and 
    * returns the associated value.
    */
   public V remove(final K key)
   {
      final Entry<K, V> before = beforeKey( key );
      
      if ( before == null )
      {
         return null;
      }
      
      final Entry<K, V> removing = before.next;
      final V removingValue = removing.value;
      before.next = removing.next;
      free( removing );
      size--;
      
      return removingValue;
   }
   
   /**
    * Removes all entries with the given key.
    */
   public void removeAll(final K key)
   {
      removeAllFromIterator( entriesWithKey( key ) );
   }
   
   /**
    * Removes all entries with the given keys.
    */
   public void removeAll(final K ... keyArray)
   {
      for (K key : keyArray) 
      {
         removeAllFromIterator( entriesWithKey( key ) );
      }
   }
   
   /**
    * Removes all entries with the given keys.
    */
   public void removeAll(final Iterable<K> keyIterable)
   {
      for (K key : keyIterable) 
      {
         removeAllFromIterator( entriesWithKey( key ) );
      }
   }
   
   /**
    * Returns the number of entries with the given key.
    */
   public int countOf(final K key)
   {
      return countIterator( entriesWithKey( key ) );
   }
   
   /**
    * Removes the first entry found in the table with the given value and 
    * returns it's key.
    */
   public K removeValue(final V value)
   {
      final Entry<K, V> before = beforeValue( value );
      
      if ( before == null )
      {
         return null;
      }
      
      final Entry<K, V> removing = before.next;
      final K removingKey = removing.key;
      before.next = removing.next;
      free( removing );
      size--;
      
      return removingKey;
   }

   /**
    * Removes all entries with the given value.
    */
   public void removeAllValue(final V value)
   {
      removeAllFromIterator( entriesWithValue( value ) );
   }
   
   /**
    * Removes all entries with the given values.
    */
   public void removeAllValue(final V ... valueyArray)
   {
      for (V value : valueyArray) 
      {
         removeAllFromIterator( entriesWithValue( value ) );
      }
   }
   
   /**
    * Removes all entries with the given values.
    */
   public void removeAllValue(final Iterable<V> valueIterable)
   {
      for (V value : valueIterable) 
      {
         removeAllFromIterator( entriesWithValue( value ) );
      }
   }
   
   /**
    * Returns the number of entries with the given key.
    */
   public int countOfValue(final V value)
   {
      return countIterator( entriesWithValue( value ) );
   }
   
   /**
    * Returns whether the given key exists in the map at least once.
    */
   public boolean has(final K key)
   {
      return beforeKey( key ) != null;
   }
   
   /**
    * Returns whether the given value exists in the map at least once.
    */
   public boolean hasValue(final V value)
   {
      return beforeValue( value ) != null;
   }
   
   /**
    * Returns the entry directly before the key or null if the key doesn't 
    * exist in the map.
    */
   public Entry<K, V> beforeKey(final K key)
   {
      final int hash = hash( key );
      final int tableIndex = hash & mod;
      final Entry<K, V> ending = table[ (tableIndex + 1) & mod ];
      Entry<K, V> before = table[ tableIndex ];
      Entry<K, V> current = before.next;
      
      while ( current != ending )
      {
         if ( current.hash == hash && (current.key == key || (key.equals( current.key ) ) ) )
         {
            return before;
         }

         before = current;
         current = current.next;
      }
      
      return null;
   }
   
   /**
    * Returns the entry directly before the value or null if the value doesn't
    * exist in the map.
    */
   public Entry<K, V> beforeValue(final V value)
   {
      final Entry<K, V> ending = table[0];
      Entry<K, V> before = ending;
      Entry<K, V> current = before.next;
      
      while (current != ending)
      {
         if ( current.value == value || value.equals( current.value ) )
         {
            return before;
         }
         
         before = current;
         current = current.next;
      }
      
      return null;
   }
   
   /**
    * Hashes the given key. This can he overridden by subclasses to provide
    * better hashes based on Key type.
    */
   public int hash(final K key)
   {
      return key.hashCode();
   }
   
   /**
    * Removes the first key from the map. If no entries exists then null is returned.
    */
   public K removeFirstKey()
   {
      final Entry<K, V> removed = removeFirstEntry();
      K first = null;
      
      if ( removed != null )
      {
         first = removed.key;
         
         free( removed );
      }
      
      return first;
   }
   
   /**
    * Removes the first value from the map. If no entries exists then null is returned.
    */
   public V removeFirstValue()
   {
      final Entry<K, V> removed = removeFirstEntry();
      V first = null;
      
      if ( removed != null )
      {
         first = removed.value;
         
         free( removed );
      }
      
      return first;
   }
   
   /**
    * Removes the first entry from the map. This entry must be freed if you
    * have pooling initialized an expect it to perform properly. If no entries
    * exist then null is returned.
    * @see #free(Entry)
    */
   public Entry<K, V> removeFirstEntry()
   {
      final Entry<K, V> ending = table[0];
      Entry<K, V> before = ending;
      Entry<K, V> current = before.next;
      
      while ( current != ending )
      {
         Entry<K, V> next = current.next;
         
         if ( current.key != null )
         {
            before.next = next;
            size--;
            
            return current;
         }

         before = current;
         current = next;
      }
      
      return null;
   }
   
   /**
    * An Iterable of all entries in the map.
    */
   public Iterable<Entry<K, V>> entries()
   {
      return entries;
   }

   /**
    * An Iterable of all entries in the map with the given key. 
    */
   public Iterable<Entry<K, V>> entriesWithKey(final K key)
   {
      multiKey.reset( key );
      
      return multiKey;
   }
   
   /**
    * An Iterable of all entries in the map with the given value.
    */
   public Iterable<Entry<K, V>> entriesWithValue(final V value)
   {
      multiValue.reset( value );
      
      return multiValue;
   }
   
   /**
    * An Iterable of all values in the map.
    */
   public Iterable<V> values()
   {
      return values;
   }
   
   /**
    * An Iterable of all keys in the map. Keys may be repeated if there are
    * multiple entries in the map with the same key.
    */
   public Iterable<K> keys()
   {
      return keys;
   }

   /**
    * Clears the map of all entries.
    * 
    * @param freeEntries
    *       Whether the entries should be returned to the pool, or ignored.
    */
   public void clear( final boolean freeEntries )
   {
      if ( freeEntries )
      {
         Entry<K, V> entry = table[0].next;
         
         while (entry != table[0])
         {
            Entry<K, V> next = entry.next;
            
            if ( entry.key != null )
            {
               free( entry );
            }
            
            entry = next;
         }         
      }

      for ( int i = 0; i < capacity; i++ )
      {
         table[i].next = table[(i + 1) & mod];
      }
      
      size = 0;
   }
   
   /**
    * The number of entries in the map.
    */
   public int size()
   {
      return size;
   }
   
   /**
    * Whether the map is empty or not.
    */
   public boolean isEmpty()
   {
      return (size == 0);
   }
   
   /**
    * Frees a removed Entry.
    * 
    * @param entry
    *       The removed Entry to free.
    */
   public void free( final Entry<K, V> entry )
   {
      entry.value = null;
      entry.next = null;
      entry.key = null;
      freeEntry( entry );
   }
   
   /*
    * UTILITY METHODS
    */
   
   /**
    * Removes all elements in the given Iterable.
    */
   public static void removeAllFromIterator( final Iterable<?> iterable )
   {
      final Iterator<?> iterator = iterable.iterator();
      
      while (iterator.hasNext())
      {
         iterator.next();
         iterator.remove();
      }
   }
   
   /**
    * Removes all elements in the given Iterable and adds them to the destination.
    */
   public static <E, C extends Collection<E>> C removeAllFromIterator( final Iterable<E> iterable, final C destination )
   {
      final Iterator<E> iterator = iterable.iterator();
      
      while (iterator.hasNext())
      {
         destination.add( iterator.next() );
         
         iterator.remove();
      }
      
      return destination;
   }
   
   /**
    * Returns the number of elements in the Iterable.
    */
   public static int countIterator( final Iterable<?> iterable ) 
   {
      final Iterator<?> iterator = iterable.iterator();
      int count = 0;

      while (iterator.hasNext())
      {
         iterator.next();
         count++;
      }
      
      return count;
   }
   
   /**
    * Adds all values from the entries in the Iterable to the given 
    * destination collection.
    */
   public static <K, V, D extends Collection<V>> D stripValues( final Iterable<Entry<K, V>> entries, final D destination )
   {
      for ( Entry<K, V> entry : entries )
      {
         destination.add( entry.value );
      }
      
      return destination;
   }
   
   /**
    * Adds all keys from the entries in the Iterable to the given 
    * destination collection.
    */
   public static <K, V, D extends Collection<K>> D stripKeys( final Iterable<Entry<K, V>> entries, final D destination )
   {
      for ( Entry<K, V> entry : entries )
      {
         destination.add( entry.key );
      }
      
      return destination;
   }
   
   /*
    * ENTRY POOLING (optional)
    */
   
   private static Entry[] pool = {};
   
   private static int poolSize;
   
   private static <K, V> Entry<K, V> newEntry()
   {
      return (poolSize == 0 ? new Entry<K, V>() : pool[--poolSize] );
   }
   
   private static void freeEntry( final Entry entry )
   {
      if (poolSize < pool.length)
      {
         pool[poolSize++] = entry;
      }
   }
   
   /**
    * Initializes the pool of entries to some maximum size. By default the
    * pool has a size of zero so no entries are cached.
    */
   public static void initPool(final int size)
   {
      pool = Arrays.copyOf( pool, size );
   }
   
   /*
    * ENTRY
    */
   
   public static class Entry<K, V> 
   {
      public int hash;
      public K key;
      public V value;
      public Entry<K, V> next;
   }
   
   /*
    * ITERABLES
    */
   
   private abstract class AbstractIterable<E> implements Iterable<E>, Iterator<E>
   {
      protected Entry<K, V> prev0;
      protected Entry<K, V> curr0;
      protected Entry<K, V> prev1;
      protected Entry<K, V> curr1;
      protected Entry<K, V> end;
      
      @Override
      public final Iterator<E> iterator() 
      {
         end = end();
         curr1 = (prev1 = findPrev( start() )).next;
         
         return this;
      }
      
      @Override
      public final boolean hasNext()
      {
         return (curr1 != end);
      }
      
      @Override
      public final void remove()
      {
         prev0.next = curr0.next;
         
         free( curr0 );
      }
      
      public final Entry<K, V> nextEntry()
      {
         prev0 = prev1;
         curr0 = curr1;
         curr1 = (prev1 = findPrev( curr1 )).next;
         
         return curr0;
      }
      
      protected abstract Entry<K, V> findPrev( Entry<K, V> prev );
      protected abstract Entry<K, V> start();
      protected abstract Entry<K, V> end();
   }
   
   private class MultiKeyIterable extends AbstractIterable<Entry<K, V>>
   {
      private K key;
      private int hash;
      
      public void reset(final K key)
      {
         this.key = key;
         this.hash = hash( key );
      }
      
      @Override
      public Entry<K, V> next()
      {
         return nextEntry();
      }

      @Override
      protected Entry<K, V> findPrev(Entry<K, V> start)
      {
         Entry<K, V> next;
         
         while (((next = start.next).hash != hash || !key.equals(next.key)) && next != end)
         {
            start = next;
         }
         
         return start;
      }

      @Override
      protected Entry<K, V> start()
      {
         return table[ (hash & mod) ];
      }

      @Override
      protected Entry<K, V> end()
      {
         return table[ ((hash & mod) + 1) & mod ];
      }
   }
   
   private class MultiValueIterable extends AbstractIterable<Entry<K, V>>
   {
      private V value;
      
      public void reset(final V value)
      {
         this.value = value;
      }
      
      @Override
      public Entry<K, V> next()
      {
         return nextEntry();
      }

      @Override
      protected Entry<K, V> findPrev(Entry<K, V> prev)
      {
         Entry<K, V> next;
         
         while ( ((next = prev.next).value == null || !value.equals( next.value )) && next != end )
         {
            prev = next;
         }
         
         return prev;
      }

      @Override
      protected Entry<K, V> start()
      {
         return table[0];
      }

      @Override
      protected Entry<K, V> end()
      {
         return table[0];
      }
   }
   
   private abstract class CyclicIterable<E> extends AbstractIterable<E>
   {
      @Override
      protected Entry<K, V> findPrev(Entry<K, V> prev)
      {
         Entry<K, V> next;
         
         while ((next = prev.next).key == null && next != end )
         {
            prev = next;
         }
         
         return prev;
      }

      @Override
      protected Entry<K, V> start()
      {
         return table[0];
      }

      @Override
      protected Entry<K, V> end()
      {
         return table[0];
      }
   }
   
   private class EntryIterable extends CyclicIterable<Entry<K, V>> 
   {
      @Override
      public Entry<K, V> next() 
      {
         return nextEntry();
      }
   }
   
   private class ValueIterable extends CyclicIterable<V> 
   {
      @Override
      public V next() 
      {
         return nextEntry().value;
      }
   }
   
   private class KeyIterable extends CyclicIterable<K> 
   {
      @Override
      public K next() 
      {
         return nextEntry().key;
      }
   }
   
}





Dump your java code here :



Special syntax:
  • To highlight a line (yellow background), prefix it with '@@'
  • To indicate that a line should be removed (red background), prefix it with '-'
  • To indicate that a line should be added (green background), prefix it with '+'
  • To post multiple snippets, seperate them by '~~~~'
  EOF
 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

CopyableCougar4 (15 views)
2014-08-22 19:31:30

atombrot (28 views)
2014-08-19 09:29:53

Tekkerue (25 views)
2014-08-16 06:45:27

Tekkerue (23 views)
2014-08-16 06:22:17

Tekkerue (15 views)
2014-08-16 06:20:21

Tekkerue (22 views)
2014-08-16 06:12:11

Rayexar (61 views)
2014-08-11 02:49:23

BurntPizza (39 views)
2014-08-09 21:09:32

BurntPizza (31 views)
2014-08-08 02:01:56

Norakomi (38 views)
2014-08-06 19:49:38
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!