Coverage Report - org.apache.commons.collections.primitives.RandomAccessCharList
 
Classes in this File Line Coverage Branch Coverage Complexity
RandomAccessCharList
100%
46/46
100%
22/22
2.071
RandomAccessCharList$ComodChecker
100%
12/12
100%
2/2
2.071
RandomAccessCharList$RandomAccessCharListIterator
100%
52/52
100%
18/18
2.071
RandomAccessCharList$RandomAccessCharSubList
100%
47/47
100%
14/14
2.071
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one or more
 3  
  * contributor license agreements.  See the NOTICE file distributed with
 4  
  * this work for additional information regarding copyright ownership.
 5  
  * The ASF licenses this file to You under the Apache License, Version 2.0
 6  
  * (the "License"); you may not use this file except in compliance with
 7  
  * the License.  You may obtain a copy of the License at
 8  
  *
 9  
  *     http://www.apache.org/licenses/LICENSE-2.0
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 package org.apache.commons.collections.primitives;
 18  
 
 19  
 import java.util.ConcurrentModificationException;
 20  
 import java.util.NoSuchElementException;
 21  
 
 22  
 /**
 23  
  * Abstract base class for {@link CharList}s backed 
 24  
  * by random access structures like arrays.
 25  
  * <p />
 26  
  * Read-only subclasses must override {@link #get}
 27  
  * and {@link #size}.  Mutable subclasses
 28  
  * should also override {@link #set}.  Variably-sized
 29  
  * subclasses should also override {@link #add(char)} 
 30  
  * and {@link #removeElementAt}.  All other methods
 31  
  * have at least some base implementation derived from 
 32  
  * these.  Subclasses may choose to override these methods
 33  
  * to provide a more efficient implementation.
 34  
  * 
 35  
  * @since Commons Primitives 1.0
 36  
  * @version $Revision: 480460 $ $Date: 2006-11-29 03:14:21 -0500 (Wed, 29 Nov 2006) $
 37  
  * 
 38  
  * @author Rodney Waldhoff 
 39  
  */
 40  
 public abstract class RandomAccessCharList extends AbstractCharCollection implements CharList {
 41  
 
 42  
     // constructors
 43  
     //-------------------------------------------------------------------------
 44  
 
 45  
     /** Constructs an empty list. */
 46  802
     protected RandomAccessCharList() { 
 47  802
     }    
 48  
 
 49  
     // fully abstract methods
 50  
     //-------------------------------------------------------------------------
 51  
     
 52  
     public abstract char get(int index);
 53  
     public abstract int size();
 54  
 
 55  
     // unsupported in base
 56  
     //-------------------------------------------------------------------------
 57  
     
 58  
     /** 
 59  
      * Unsupported in this implementation. 
 60  
      * @throws UnsupportedOperationException since this method is not supported
 61  
      */
 62  
     public char removeElementAt(int index) {
 63  1
         throw new UnsupportedOperationException();
 64  
     }
 65  
     
 66  
     /** 
 67  
      * Unsupported in this implementation. 
 68  
      * @throws UnsupportedOperationException since this method is not supported
 69  
      */
 70  
     public char set(int index, char element) {
 71  2
         throw new UnsupportedOperationException();
 72  
     }
 73  
         
 74  
     /** 
 75  
      * Unsupported in this implementation. 
 76  
      * @throws UnsupportedOperationException since this method is not supported
 77  
      */
 78  
     public void add(int index, char element) {
 79  2
         throw new UnsupportedOperationException();
 80  
     }
 81  
 
 82  
     //-------------------------------------------------------------------------
 83  
 
 84  
     // javadocs here are inherited
 85  
     
 86  
     public boolean add(char element) {
 87  2844
         add(size(),element);
 88  2842
         return true;
 89  
     }
 90  
 
 91  
     public boolean addAll(int index, CharCollection collection) {
 92  1
         boolean modified = false;
 93  1
         for(CharIterator iter = collection.iterator(); iter.hasNext(); ) {
 94  7
             add(index++,iter.next());
 95  7
             modified = true;
 96  
         }
 97  1
         return modified;
 98  
     }
 99  
 
 100  
     public int indexOf(char element) {
 101  84
         int i = 0;
 102  84
         for(CharIterator iter = iterator(); iter.hasNext(); ) {
 103  948
             if(iter.next() == element) { 
 104  42
                 return i;
 105  
             } else {
 106  906
                 i++;
 107  
             }
 108  
         }
 109  42
         return -1;
 110  
     }
 111  
 
 112  
     public int lastIndexOf(char element) {
 113  84
         for(CharListIterator iter = listIterator(size()); iter.hasPrevious(); ) {
 114  948
             if(iter.previous() == element) {
 115  42
                 return iter.nextIndex();
 116  
             }
 117  
         }
 118  42
         return -1;
 119  
     }
 120  
 
 121  
     public CharIterator iterator() {
 122  6824
         return listIterator();
 123  
     }
 124  
 
 125  
     public CharListIterator listIterator() {
 126  8093
         return listIterator(0);
 127  
     }
 128  
 
 129  
     public CharListIterator listIterator(int index) {
 130  8323
         return new RandomAccessCharListIterator(this,index);            
 131  
     }
 132  
 
 133  
     public CharList subList(int fromIndex, int toIndex) {
 134  171
         return new RandomAccessCharSubList(this,fromIndex,toIndex);
 135  
     }
 136  
 
 137  
     public boolean equals(Object that) {
 138  32
         if(this == that) { 
 139  3
             return true; 
 140  29
         } else if(that instanceof CharList) {
 141  26
             CharList thatList = (CharList)that;
 142  26
             if(size() != thatList.size()) {
 143  4
                 return false;
 144  
             }
 145  22
             for(CharIterator thatIter = thatList.iterator(), thisIter = iterator(); thisIter.hasNext();) {
 146  120
                 if(thisIter.next() != thatIter.next()) { 
 147  2
                     return false; 
 148  
                 }
 149  
             }
 150  20
             return true;
 151  
         } else {
 152  3
             return false;
 153  
         }        
 154  
     }
 155  
     
 156  
     public int hashCode() {
 157  1165
         int hash = 1;
 158  1165
         for(CharIterator iter = iterator(); iter.hasNext(); ) {
 159  15509
             hash = 31*hash + iter.next();
 160  
         }
 161  1165
         return hash;
 162  
     }
 163  
     
 164  
     public String toString() {
 165  
         // could cache these like StringBuffer does
 166  7
         return new String(toArray());
 167  
     }
 168  
     
 169  
     // protected utilities
 170  
     //-------------------------------------------------------------------------
 171  
     
 172  
     /** Get my count of structural modifications. */
 173  
     protected int getModCount() {
 174  433093
         return _modCount;
 175  
     }
 176  
 
 177  
     /** Increment my count of structural modifications. */
 178  
     protected void incrModCount() {
 179  7718
         _modCount++;
 180  7718
     }
 181  
 
 182  
     // attributes
 183  
     //-------------------------------------------------------------------------
 184  
     
 185  802
     private int _modCount = 0;
 186  
 
 187  
     // inner classes
 188  
     //-------------------------------------------------------------------------
 189  
     
 190  
     private static class ComodChecker {
 191  8490
         ComodChecker(RandomAccessCharList source) {
 192  8490
             _source = source;  
 193  8490
             resyncModCount();             
 194  8490
         }
 195  
         
 196  
         protected RandomAccessCharList getList() {
 197  757175
             return _source;
 198  
         }
 199  
         
 200  
         protected void assertNotComodified() throws ConcurrentModificationException {
 201  415295
             if(_expectedModCount != getList().getModCount()) {
 202  1
                 throw new ConcurrentModificationException();
 203  
             }
 204  415294
         }
 205  
             
 206  
         protected void resyncModCount() {
 207  17798
             _expectedModCount = getList().getModCount();
 208  17798
         }
 209  
         
 210  8490
         private RandomAccessCharList _source = null;
 211  8490
         private int _expectedModCount = -1;
 212  
     }
 213  
     
 214  
     protected static class RandomAccessCharListIterator extends ComodChecker implements CharListIterator {
 215  
         RandomAccessCharListIterator(RandomAccessCharList list, int index) {
 216  8323
             super(list);
 217  8323
             if(index < 0 || index > getList().size()) {
 218  9
                 throw new IndexOutOfBoundsException("Index " + index + " not in [0," + getList().size() + ")");
 219  
             } else {
 220  8314
                 _nextIndex = index;
 221  8314
                 resyncModCount();
 222  
             }
 223  8314
         }
 224  
             
 225  
         public boolean hasNext() {
 226  211018
             assertNotComodified();
 227  211018
             return _nextIndex < getList().size();
 228  
         }
 229  
         
 230  
         public boolean hasPrevious() {
 231  3663
             assertNotComodified();
 232  3663
             return _nextIndex > 0;
 233  
         }
 234  
         
 235  
         public int nextIndex() {
 236  1369
             assertNotComodified();
 237  1369
             return _nextIndex;
 238  
         }
 239  
         
 240  
         public int previousIndex() {
 241  1327
             assertNotComodified();
 242  1327
             return _nextIndex - 1;
 243  
         }
 244  
         
 245  
         public char next() {
 246  102545
             assertNotComodified();
 247  102544
             if(!hasNext()) {
 248  72
                 throw new NoSuchElementException();
 249  
             } else {
 250  102472
                 char val = getList().get(_nextIndex);
 251  102472
                 _lastReturnedIndex = _nextIndex;
 252  102472
                 _nextIndex++;
 253  102472
                 return val;
 254  
             }
 255  
         }
 256  
         
 257  
         public char previous() {
 258  1856
             assertNotComodified();
 259  1856
             if(!hasPrevious()) {
 260  101
                 throw new NoSuchElementException();
 261  
             } else {
 262  1755
                 char val = getList().get(_nextIndex-1);
 263  1755
                 _lastReturnedIndex = _nextIndex-1;
 264  1755
                 _nextIndex--;
 265  1755
                 return val;
 266  
             }
 267  
         }
 268  
         
 269  
         public void add(char value) {
 270  152
             assertNotComodified();
 271  152
             getList().add(_nextIndex,value);
 272  152
             _nextIndex++;
 273  152
             _lastReturnedIndex = -1;
 274  152
             resyncModCount();
 275  152
         }
 276  
     
 277  
         public void remove() {
 278  333
             assertNotComodified();
 279  333
             if (_lastReturnedIndex == -1) {
 280  26
                 throw new IllegalStateException();
 281  
             }
 282  307
             if (_lastReturnedIndex == _nextIndex) {
 283  
                 // remove() following previous()
 284  3
                 getList().removeElementAt(_lastReturnedIndex);
 285  
             } else {
 286  
                 // remove() following next()
 287  304
                 getList().removeElementAt(_lastReturnedIndex);
 288  304
                 _nextIndex--;
 289  
             }
 290  307
             _lastReturnedIndex = -1;
 291  307
             resyncModCount();
 292  307
         }
 293  
         
 294  
         public void set(char value) {
 295  64
             assertNotComodified();
 296  64
             if(-1 == _lastReturnedIndex) {
 297  14
                 throw new IllegalStateException();
 298  
             } else {
 299  50
                 getList().set(_lastReturnedIndex,value);
 300  50
                 resyncModCount();
 301  
             }
 302  50
         }
 303  
         
 304  8323
         private int _nextIndex = 0;
 305  8323
         private int _lastReturnedIndex = -1;        
 306  
     }   
 307  
 
 308  
     protected static class RandomAccessCharSubList extends RandomAccessCharList implements CharList {
 309  171
         RandomAccessCharSubList(RandomAccessCharList list, int fromIndex, int toIndex) {
 310  171
             if(fromIndex < 0 || toIndex > list.size()) {
 311  3
                 throw new IndexOutOfBoundsException();
 312  168
             } else if(fromIndex > toIndex) {
 313  1
                 throw new IllegalArgumentException();                
 314  
             } else {
 315  167
                 _list = list;
 316  167
                 _offset = fromIndex;
 317  167
                 _limit = toIndex - fromIndex;
 318  167
                 _comod = new ComodChecker(list);
 319  167
                 _comod.resyncModCount();
 320  
             }            
 321  167
         }
 322  
     
 323  
         public char get(int index) {
 324  23646
             checkRange(index);
 325  23637
             _comod.assertNotComodified();
 326  23637
             return _list.get(toUnderlyingIndex(index));
 327  
         }
 328  
     
 329  
         public char removeElementAt(int index) {
 330  167
             checkRange(index);
 331  158
             _comod.assertNotComodified();
 332  158
             char val = _list.removeElementAt(toUnderlyingIndex(index));
 333  158
             _limit--;
 334  158
             _comod.resyncModCount();
 335  158
             incrModCount();
 336  158
             return val;
 337  
         }
 338  
     
 339  
         public char set(int index, char element) {
 340  37
             checkRange(index);
 341  28
             _comod.assertNotComodified();
 342  28
             char val = _list.set(toUnderlyingIndex(index),element);
 343  28
             incrModCount();
 344  28
             _comod.resyncModCount();
 345  28
             return val;
 346  
         }
 347  
     
 348  
         public void add(int index, char element) {
 349  140
             checkRangeIncludingEndpoint(index);
 350  132
             _comod.assertNotComodified();
 351  132
              _list.add(toUnderlyingIndex(index),element);
 352  132
             _limit++;
 353  132
             _comod.resyncModCount();
 354  132
             incrModCount();
 355  132
         }
 356  
     
 357  
         public int size() {
 358  69013
             _comod.assertNotComodified();
 359  69013
             return _limit;
 360  
         }
 361  
     
 362  
         private void checkRange(int index) {
 363  23850
             if(index < 0 || index >= size()) {
 364  27
                 throw new IndexOutOfBoundsException("index " + index + " not in [0," + size() + ")");
 365  
             }
 366  23823
         }
 367  
           
 368  
         private void checkRangeIncludingEndpoint(int index) {
 369  140
             if(index < 0 || index > size()) {
 370  8
                 throw new IndexOutOfBoundsException("index " + index + " not in [0," + size() + "]");
 371  
             }
 372  132
         }
 373  
           
 374  
         private int toUnderlyingIndex(int index) {
 375  23955
             return (index + _offset);
 376  
         }
 377  
         
 378  171
         private int _offset = 0;        
 379  171
         private int _limit = 0; 
 380  171
         private RandomAccessCharList _list = null;
 381  171
         private ComodChecker _comod = null;
 382  
     
 383  
     }
 384  
 }
 385