📄 rulebasedbreakiterator.java
字号:
*/ public Object clone() { RuleBasedBreakIterator result = (RuleBasedBreakIterator) super.clone(); if (text != null) { result.text = (CharacterIterator) text.clone(); } return result; } /** * Returns true if both BreakIterators are of the same class, have the same * rules, and iterate over the same text. */ public boolean equals(Object that) { try { RuleBasedBreakIterator other = (RuleBasedBreakIterator) that; if (!description.equals(other.description)) { return false; } if (text == null) { return other.text == null; } else { return text.equals(other.text); } } catch(ClassCastException e) { return false; } } /** * Returns the description used to create this iterator */ public String toString() { return description; } /** * Compute a hashcode for this BreakIterator * @return A hash code */ public int hashCode() { return description.hashCode(); } //======================================================================= // BreakIterator overrides //======================================================================= /** * Sets the current iteration position to the beginning of the text. * (i.e., the CharacterIterator's starting offset). * @return The offset of the beginning of the text. */ public int first() { CharacterIterator t = getText(); t.first(); return t.getIndex(); } /** * Sets the current iteration position to the end of the text. * (i.e., the CharacterIterator's ending offset). * @return The text's past-the-end offset. */ public int last() { CharacterIterator t = getText(); // I'm not sure why, but t.last() returns the offset of the last character, // rather than the past-the-end offset t.setIndex(t.getEndIndex()); return t.getIndex(); } /** * Advances the iterator either forward or backward the specified number of steps. * Negative values move backward, and positive values move forward. This is * equivalent to repeatedly calling next() or previous(). * @param n The number of steps to move. The sign indicates the direction * (negative is backwards, and positive is forwards). * @return The character offset of the boundary position n boundaries away from * the current one. */ public int next(int n) { int result = current(); while (n > 0) { result = handleNext(); --n; } while (n < 0) { result = previous(); ++n; } return result; } /** * Advances the iterator to the next boundary position. * @return The position of the first boundary after this one. */ public int next() { return handleNext(); } /** * Advances the iterator backwards, to the last boundary preceding this one. * @return The position of the last boundary position preceding this one. */ public int previous() { // if we're already sitting at the beginning of the text, return DONE CharacterIterator text = getText(); if (current() == text.getBeginIndex()) { return BreakIterator.DONE; } // set things up. handlePrevious() will back us up to some valid // break position before the current position (we back our internal // iterator up one step to prevent handlePrevious() from returning // the current position), but not necessarily the last one before // where we started int start = current(); text.previous(); int lastResult = handlePrevious(); int result = lastResult; // iterate forward from the known break position until we pass our // starting point. The last break position before the starting // point is our return value while (result != BreakIterator.DONE && result < start) { lastResult = result; result = handleNext(); } // set the current iteration position to be the last break position // before where we started, and then return that value text.setIndex(lastResult); return lastResult; } /** * Throw IllegalArgumentException unless begin <= offset < end. */ protected static final void checkOffset(int offset, CharacterIterator text) { if (offset < text.getBeginIndex() || offset >= text.getEndIndex()) { throw new IllegalArgumentException("offset out of bounds"); } } /** * Sets the iterator to refer to the first boundary position following * the specified position. * @offset The position from which to begin searching for a break position. * @return The position of the first break after the current position. */ public int following(int offset) { CharacterIterator text = getText(); checkOffset(offset, text); // Set our internal iteration position (temporarily) // to the position passed in. If this is the _beginning_ position, // then we can just use next() to get our return value text.setIndex(offset); if (offset == text.getBeginIndex()) { return handleNext(); } // otherwise, we have to sync up first. Use handlePrevious() to back // us up to a known break position before the specified position (if // we can determine that the specified position is a break position, // we don't back up at all). This may or may not be the last break // position at or before our starting position. Advance forward // from here until we've passed the starting position. The position // we stop on will be the first break position after the specified one. int result = handlePrevious(); while (result != BreakIterator.DONE && result <= offset) { result = handleNext(); } return result; } /** * Sets the iterator to refer to the last boundary position before the * specified position. * @offset The position to begin searching for a break from. * @return The position of the last boundary before the starting position. */ public int preceding(int offset) { // if we start by updating the current iteration position to the // position specified by the caller, we can just use previous() // to carry out this operation CharacterIterator text = getText(); checkOffset(offset, text); text.setIndex(offset); return previous(); } /** * Returns true if the specfied position is a boundary position. As a side * effect, leaves the iterator pointing to the first boundary position at * or after "offset". * @param offset the offset to check. * @return True if "offset" is a boundary position. */ public boolean isBoundary(int offset) { CharacterIterator text = getText(); checkOffset(offset, text); if (offset == text.getBeginIndex()) { return true; } // to check whether this is a boundary, we can use following() on the // position before the specified one and return true if the position we // get back is the one the user specified else { return following(offset - 1) == offset; } } /** * Returns the current iteration position. * @return The current iteration position. */ public int current() { return getText().getIndex(); } /** * Return a CharacterIterator over the text being analyzed. This version * of this method returns the actual CharacterIterator we're using internally. * Changing the state of this iterator can have undefined consequences. If * you need to change it, clone it first. * @return An iterator over the text being analyzed. */ public CharacterIterator getText() { // The iterator is initialized pointing to no text at all, so if this // function is called while we're in that state, we have to fudge an // an iterator to return. if (text == null) { text = new StringCharacterIterator(""); } return text; } /** * Set the iterator to analyze a new piece of text. This function resets * the current iteration position to the beginning of the text. * @param newText An iterator over the text to analyze. */ public void setText(CharacterIterator newText) { // Test iterator to see if we need to wrap it in a SafeCharIterator. // The correct behavior for CharacterIterators is to allow the // position to be set to the endpoint of the iterator. Many // CharacterIterators do not uphold this, so this is a workaround // to permit them to use this class. int end = newText.getEndIndex(); boolean goodIterator; try { newText.setIndex(end); // some buggy iterators throw an exception here goodIterator = newText.getIndex() == end; } catch(IllegalArgumentException e) { goodIterator = false; } if (goodIterator) { text = newText; } else { text = new SafeCharIterator(newText); } text.first(); } //======================================================================= // implementation //======================================================================= /** * This method is the actual implementation of the next() method. All iteration * vectors through here. This method initializes the state machine to state 1 * and advances through the text character by character until we reach the end * of the text or the state machine transitions to state 0. We update our return * value every time the state machine passes through a possible end state. */ protected int handleNext() { // if we're already at the end of the text, return DONE. CharacterIterator text = getText(); if (text.getIndex() == text.getEndIndex()) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -