Adding Vincent Ricard's patch to CharRange.java providing an iterator that lets you walk the chars in the range. LANG-454
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/lang/trunk@905919 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
643302af8c
commit
23f5080950
|
@ -17,6 +17,8 @@
|
||||||
package org.apache.commons.lang3;
|
package org.apache.commons.lang3;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>A contiguous range of characters, optionally negated.</p>
|
* <p>A contiguous range of characters, optionally negated.</p>
|
||||||
|
@ -241,5 +243,96 @@ public String toString() {
|
||||||
}
|
}
|
||||||
return iToString;
|
return iToString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Expansions
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* <p>Returns an iterator which can be used to walk through the characters described by this range.</p>
|
||||||
|
*
|
||||||
|
* @return an iterator to the chars represented by this range
|
||||||
|
*/
|
||||||
|
public Iterator iterator() {
|
||||||
|
return new CharacterIterator(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
static class CharacterIterator implements Iterator {
|
||||||
|
/** The currect character */
|
||||||
|
private char current;
|
||||||
|
|
||||||
|
private CharRange range;
|
||||||
|
private boolean hasNext;
|
||||||
|
|
||||||
|
public CharacterIterator(CharRange r) {
|
||||||
|
range = r;
|
||||||
|
hasNext = true;
|
||||||
|
|
||||||
|
if (range.negated) {
|
||||||
|
if (range.start == 0) {
|
||||||
|
if (range.end == Character.MAX_VALUE) {
|
||||||
|
// This range is an empty set
|
||||||
|
hasNext = false;
|
||||||
|
} else {
|
||||||
|
current = (char) (range.end + 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
current = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
current = range.start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void prepareNext() {
|
||||||
|
if (range.negated) {
|
||||||
|
if (current == Character.MAX_VALUE) {
|
||||||
|
hasNext = false;
|
||||||
|
} else if (current + 1 == range.start) {
|
||||||
|
if (range.end == Character.MAX_VALUE) {
|
||||||
|
hasNext = false;
|
||||||
|
} else {
|
||||||
|
current = (char) (range.end + 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
current = (char) (current + 1);
|
||||||
|
}
|
||||||
|
} else if (current < range.end) {
|
||||||
|
current = (char) (current + 1);
|
||||||
|
} else {
|
||||||
|
hasNext = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Has the iterator not reached the end character yet?
|
||||||
|
*
|
||||||
|
* @return <code>true</code> if the iterator has yet to reach the character date
|
||||||
|
*/
|
||||||
|
public boolean hasNext() {
|
||||||
|
return hasNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the next character in the iteration
|
||||||
|
*
|
||||||
|
* @return <code>Character</code> for the next character
|
||||||
|
*/
|
||||||
|
public Object next() {
|
||||||
|
if (hasNext == false) {
|
||||||
|
throw new NoSuchElementException();
|
||||||
|
}
|
||||||
|
char cur = current;
|
||||||
|
prepareNext();
|
||||||
|
return Character.valueOf(cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Always throws UnsupportedOperationException.
|
||||||
|
*
|
||||||
|
* @throws UnsupportedOperationException
|
||||||
|
* @see java.util.Iterator#remove()
|
||||||
|
*/
|
||||||
|
public void remove() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
package org.apache.commons.lang3;
|
package org.apache.commons.lang3;
|
||||||
|
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
@ -301,7 +303,73 @@ public void testContainsNullArg() {
|
||||||
assertEquals("The Range must not be null", e.getMessage());
|
assertEquals("The Range must not be null", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testIterator() {
|
||||||
|
CharRange a = CharRange.is('a');
|
||||||
|
CharRange ad = CharRange.isIn('a', 'd');
|
||||||
|
CharRange nota = CharRange.isNot('a');
|
||||||
|
CharRange emptySet = CharRange.isNotIn((char) 0, Character.MAX_VALUE);
|
||||||
|
CharRange notFirst = CharRange.isNotIn((char) 1, Character.MAX_VALUE);
|
||||||
|
CharRange notLast = CharRange.isNotIn((char) 0, (char) (Character.MAX_VALUE - 1));
|
||||||
|
|
||||||
|
Iterator aIt = a.iterator();
|
||||||
|
assertNotNull(aIt);
|
||||||
|
assertTrue(aIt.hasNext());
|
||||||
|
assertEquals(Character.valueOf('a'), aIt.next());
|
||||||
|
assertFalse(aIt.hasNext());
|
||||||
|
|
||||||
|
Iterator adIt = ad.iterator();
|
||||||
|
assertNotNull(adIt);
|
||||||
|
assertTrue(adIt.hasNext());
|
||||||
|
assertEquals(Character.valueOf('a'), adIt.next());
|
||||||
|
assertEquals(Character.valueOf('b'), adIt.next());
|
||||||
|
assertEquals(Character.valueOf('c'), adIt.next());
|
||||||
|
assertEquals(Character.valueOf('d'), adIt.next());
|
||||||
|
assertFalse(adIt.hasNext());
|
||||||
|
|
||||||
|
Iterator notaIt = nota.iterator();
|
||||||
|
assertNotNull(notaIt);
|
||||||
|
assertTrue(notaIt.hasNext());
|
||||||
|
while (notaIt.hasNext()) {
|
||||||
|
Character c = (Character) notaIt.next();
|
||||||
|
assertFalse('a' == c.charValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator emptySetIt = emptySet.iterator();
|
||||||
|
assertNotNull(emptySetIt);
|
||||||
|
assertFalse(emptySetIt.hasNext());
|
||||||
|
try {
|
||||||
|
emptySetIt.next();
|
||||||
|
fail("Should throw NoSuchElementException");
|
||||||
|
} catch (NoSuchElementException e) {
|
||||||
|
assertTrue(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator notFirstIt = notFirst.iterator();
|
||||||
|
assertNotNull(notFirstIt);
|
||||||
|
assertTrue(notFirstIt.hasNext());
|
||||||
|
assertEquals(Character.valueOf((char) 0), notFirstIt.next());
|
||||||
|
assertFalse(notFirstIt.hasNext());
|
||||||
|
try {
|
||||||
|
notFirstIt.next();
|
||||||
|
fail("Should throw NoSuchElementException");
|
||||||
|
} catch (NoSuchElementException e) {
|
||||||
|
assertTrue(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator notLastIt = notLast.iterator();
|
||||||
|
assertNotNull(notLastIt);
|
||||||
|
assertTrue(notLastIt.hasNext());
|
||||||
|
assertEquals(Character.valueOf(Character.MAX_VALUE), notLastIt.next());
|
||||||
|
assertFalse(notLastIt.hasNext());
|
||||||
|
try {
|
||||||
|
notLastIt.next();
|
||||||
|
fail("Should throw NoSuchElementException");
|
||||||
|
} catch (NoSuchElementException e) {
|
||||||
|
assertTrue(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------
|
//-----------------------------------------------------------------------
|
||||||
public void testSerialization() {
|
public void testSerialization() {
|
||||||
CharRange range = CharRange.is('a');
|
CharRange range = CharRange.is('a');
|
||||||
|
|
Loading…
Reference in New Issue