/*
 * Copyright (C) 2010 The Guava Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */

package com.google.common.base;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;

import com.google.common.annotations.GwtCompatible;

Static methods pertaining to ASCII characters (those in the range of values 0x00 through 0x7F), and to strings containing such characters.

ASCII utilities also exist in other classes of this package:

  • Charsets.US_ASCII specifies the Charset of ASCII characters.
  • CharMatcher.ascii matches ASCII characters and provides text processing methods which operate only on the ASCII characters of a string.
Author:Catherine Berry, Gregory Kick
Since:7.0
/** * Static methods pertaining to ASCII characters (those in the range of values {@code 0x00} through * {@code 0x7F}), and to strings containing such characters. * * <p>ASCII utilities also exist in other classes of this package: * * <ul> * <!-- TODO(kevinb): how can we make this not produce a warning when building gwt javadoc? --> * <li>{@link Charsets#US_ASCII} specifies the {@code Charset} of ASCII characters. * <li>{@link CharMatcher#ascii} matches ASCII characters and provides text processing methods * which operate only on the ASCII characters of a string. * </ul> * * @author Catherine Berry * @author Gregory Kick * @since 7.0 */
@GwtCompatible public final class Ascii { private Ascii() {} /* The ASCII control characters, per RFC 20. */
Null ('\0'): The all-zeros character which may serve to accomplish time fill and media fill. Normally used as a C string terminator.

Although RFC 20 names this as "Null", note that it is distinct from the C/C++ "NULL" pointer.

Since:8.0
/** * Null ('\0'): The all-zeros character which may serve to accomplish time fill and media fill. * Normally used as a C string terminator. * * <p>Although RFC 20 names this as "Null", note that it is distinct from the C/C++ "NULL" * pointer. * * @since 8.0 */
public static final byte NUL = 0;
Start of Heading: A communication control character used at the beginning of a sequence of characters which constitute a machine-sensible address or routing information. Such a sequence is referred to as the "heading." An STX character has the effect of terminating a heading.
Since:8.0
/** * Start of Heading: A communication control character used at the beginning of a sequence of * characters which constitute a machine-sensible address or routing information. Such a sequence * is referred to as the "heading." An STX character has the effect of terminating a heading. * * @since 8.0 */
public static final byte SOH = 1;
Start of Text: A communication control character which precedes a sequence of characters that is to be treated as an entity and entirely transmitted through to the ultimate destination. Such a sequence is referred to as "text." STX may be used to terminate a sequence of characters started by SOH.
Since:8.0
/** * Start of Text: A communication control character which precedes a sequence of characters that * is to be treated as an entity and entirely transmitted through to the ultimate destination. * Such a sequence is referred to as "text." STX may be used to terminate a sequence of characters * started by SOH. * * @since 8.0 */
public static final byte STX = 2;
End of Text: A communication control character used to terminate a sequence of characters started with STX and transmitted as an entity.
Since:8.0
/** * End of Text: A communication control character used to terminate a sequence of characters * started with STX and transmitted as an entity. * * @since 8.0 */
public static final byte ETX = 3;
End of Transmission: A communication control character used to indicate the conclusion of a transmission, which may have contained one or more texts and any associated headings.
Since:8.0
/** * End of Transmission: A communication control character used to indicate the conclusion of a * transmission, which may have contained one or more texts and any associated headings. * * @since 8.0 */
public static final byte EOT = 4;
Enquiry: A communication control character used in data communication systems as a request for a response from a remote station. It may be used as a "Who Are You" (WRU) to obtain identification, or may be used to obtain station status, or both.
Since:8.0
/** * Enquiry: A communication control character used in data communication systems as a request for * a response from a remote station. It may be used as a "Who Are You" (WRU) to obtain * identification, or may be used to obtain station status, or both. * * @since 8.0 */
public static final byte ENQ = 5;
Acknowledge: A communication control character transmitted by a receiver as an affirmative response to a sender.
Since:8.0
/** * Acknowledge: A communication control character transmitted by a receiver as an affirmative * response to a sender. * * @since 8.0 */
public static final byte ACK = 6;
Bell ('\a'): A character for use when there is a need to call for human attention. It may control alarm or attention devices.
Since:8.0
/** * Bell ('\a'): A character for use when there is a need to call for human attention. It may * control alarm or attention devices. * * @since 8.0 */
public static final byte BEL = 7;
Backspace ('\b'): A format effector which controls the movement of the printing position one printing space backward on the same printing line. (Applicable also to display devices.)
Since:8.0
/** * Backspace ('\b'): A format effector which controls the movement of the printing position one * printing space backward on the same printing line. (Applicable also to display devices.) * * @since 8.0 */
public static final byte BS = 8;
Horizontal Tabulation ('\t'): A format effector which controls the movement of the printing position to the next in a series of predetermined positions along the printing line. (Applicable also to display devices and the skip function on punched cards.)
Since:8.0
/** * Horizontal Tabulation ('\t'): A format effector which controls the movement of the printing * position to the next in a series of predetermined positions along the printing line. * (Applicable also to display devices and the skip function on punched cards.) * * @since 8.0 */
public static final byte HT = 9;
Line Feed ('\n'): A format effector which controls the movement of the printing position to the next printing line. (Applicable also to display devices.) Where appropriate, this character may have the meaning "New Line" (NL), a format effector which controls the movement of the printing point to the first printing position on the next printing line. Use of this convention requires agreement between sender and recipient of data.
Since:8.0
/** * Line Feed ('\n'): A format effector which controls the movement of the printing position to the * next printing line. (Applicable also to display devices.) Where appropriate, this character may * have the meaning "New Line" (NL), a format effector which controls the movement of the printing * point to the first printing position on the next printing line. Use of this convention requires * agreement between sender and recipient of data. * * @since 8.0 */
public static final byte LF = 10;
Alternate name for LF. (LF is preferred.)
Since:8.0
/** * Alternate name for {@link #LF}. ({@code LF} is preferred.) * * @since 8.0 */
public static final byte NL = 10;
Vertical Tabulation ('\v'): A format effector which controls the movement of the printing position to the next in a series of predetermined printing lines. (Applicable also to display devices.)
Since:8.0
/** * Vertical Tabulation ('\v'): A format effector which controls the movement of the printing * position to the next in a series of predetermined printing lines. (Applicable also to display * devices.) * * @since 8.0 */
public static final byte VT = 11;
Form Feed ('\f'): A format effector which controls the movement of the printing position to the first pre-determined printing line on the next form or page. (Applicable also to display devices.)
Since:8.0
/** * Form Feed ('\f'): A format effector which controls the movement of the printing position to the * first pre-determined printing line on the next form or page. (Applicable also to display * devices.) * * @since 8.0 */
public static final byte FF = 12;
Carriage Return ('\r'): A format effector which controls the movement of the printing position to the first printing position on the same printing line. (Applicable also to display devices.)
Since:8.0
/** * Carriage Return ('\r'): A format effector which controls the movement of the printing position * to the first printing position on the same printing line. (Applicable also to display devices.) * * @since 8.0 */
public static final byte CR = 13;
Shift Out: A control character indicating that the code combinations which follow shall be interpreted as outside of the character set of the standard code table until a Shift In character is reached.
Since:8.0
/** * Shift Out: A control character indicating that the code combinations which follow shall be * interpreted as outside of the character set of the standard code table until a Shift In * character is reached. * * @since 8.0 */
public static final byte SO = 14;
Shift In: A control character indicating that the code combinations which follow shall be interpreted according to the standard code table.
Since:8.0
/** * Shift In: A control character indicating that the code combinations which follow shall be * interpreted according to the standard code table. * * @since 8.0 */
public static final byte SI = 15;
Data Link Escape: A communication control character which will change the meaning of a limited number of contiguously following characters. It is used exclusively to provide supplementary controls in data communication networks.
Since:8.0
/** * Data Link Escape: A communication control character which will change the meaning of a limited * number of contiguously following characters. It is used exclusively to provide supplementary * controls in data communication networks. * * @since 8.0 */
public static final byte DLE = 16;
Device Control 1. Characters for the control of ancillary devices associated with data processing or telecommunication systems, more especially switching devices "on" or "off." (If a single "stop" control is required to interrupt or turn off ancillary devices, DC4 is the preferred assignment.)
Since:8.0
/** * Device Control 1. Characters for the control of ancillary devices associated with data * processing or telecommunication systems, more especially switching devices "on" or "off." (If a * single "stop" control is required to interrupt or turn off ancillary devices, DC4 is the * preferred assignment.) * * @since 8.0 */
public static final byte DC1 = 17; // aka XON
Transmission On: Although originally defined as DC1, this ASCII control character is now better known as the XON code used for software flow control in serial communications. The main use is restarting the transmission after the communication has been stopped by the XOFF control code.
Since:8.0
/** * Transmission On: Although originally defined as DC1, this ASCII control character is now better * known as the XON code used for software flow control in serial communications. The main use is * restarting the transmission after the communication has been stopped by the XOFF control code. * * @since 8.0 */
public static final byte XON = 17; // aka DC1
Device Control 2. Characters for the control of ancillary devices associated with data processing or telecommunication systems, more especially switching devices "on" or "off." (If a single "stop" control is required to interrupt or turn off ancillary devices, DC4 is the preferred assignment.)
Since:8.0
/** * Device Control 2. Characters for the control of ancillary devices associated with data * processing or telecommunication systems, more especially switching devices "on" or "off." (If a * single "stop" control is required to interrupt or turn off ancillary devices, DC4 is the * preferred assignment.) * * @since 8.0 */
public static final byte DC2 = 18;
Device Control 3. Characters for the control of ancillary devices associated with data processing or telecommunication systems, more especially switching devices "on" or "off." (If a single "stop" control is required to interrupt or turn off ancillary devices, DC4 is the preferred assignment.)
Since:8.0
/** * Device Control 3. Characters for the control of ancillary devices associated with data * processing or telecommunication systems, more especially switching devices "on" or "off." (If a * single "stop" control is required to interrupt or turn off ancillary devices, DC4 is the * preferred assignment.) * * @since 8.0 */
public static final byte DC3 = 19; // aka XOFF
Transmission off. See XON for explanation.
Since:8.0
/** * Transmission off. See {@link #XON} for explanation. * * @since 8.0 */
public static final byte XOFF = 19; // aka DC3
Device Control 4. Characters for the control of ancillary devices associated with data processing or telecommunication systems, more especially switching devices "on" or "off." (If a single "stop" control is required to interrupt or turn off ancillary devices, DC4 is the preferred assignment.)
Since:8.0
/** * Device Control 4. Characters for the control of ancillary devices associated with data * processing or telecommunication systems, more especially switching devices "on" or "off." (If a * single "stop" control is required to interrupt or turn off ancillary devices, DC4 is the * preferred assignment.) * * @since 8.0 */
public static final byte DC4 = 20;
Negative Acknowledge: A communication control character transmitted by a receiver as a negative response to the sender.
Since:8.0
/** * Negative Acknowledge: A communication control character transmitted by a receiver as a negative * response to the sender. * * @since 8.0 */
public static final byte NAK = 21;
Synchronous Idle: A communication control character used by a synchronous transmission system in the absence of any other character to provide a signal from which synchronism may be achieved or retained.
Since:8.0
/** * Synchronous Idle: A communication control character used by a synchronous transmission system * in the absence of any other character to provide a signal from which synchronism may be * achieved or retained. * * @since 8.0 */
public static final byte SYN = 22;
End of Transmission Block: A communication control character used to indicate the end of a block of data for communication purposes. ETB is used for blocking data where the block structure is not necessarily related to the processing format.
Since:8.0
/** * End of Transmission Block: A communication control character used to indicate the end of a * block of data for communication purposes. ETB is used for blocking data where the block * structure is not necessarily related to the processing format. * * @since 8.0 */
public static final byte ETB = 23;
Cancel: A control character used to indicate that the data with which it is sent is in error or is to be disregarded.
Since:8.0
/** * Cancel: A control character used to indicate that the data with which it is sent is in error or * is to be disregarded. * * @since 8.0 */
public static final byte CAN = 24;
End of Medium: A control character associated with the sent data which may be used to identify the physical end of the medium, or the end of the used, or wanted, portion of information recorded on a medium. (The position of this character does not necessarily correspond to the physical end of the medium.)
Since:8.0
/** * End of Medium: A control character associated with the sent data which may be used to identify * the physical end of the medium, or the end of the used, or wanted, portion of information * recorded on a medium. (The position of this character does not necessarily correspond to the * physical end of the medium.) * * @since 8.0 */
public static final byte EM = 25;
Substitute: A character that may be substituted for a character which is determined to be invalid or in error.
Since:8.0
/** * Substitute: A character that may be substituted for a character which is determined to be * invalid or in error. * * @since 8.0 */
public static final byte SUB = 26;
Escape: A control character intended to provide code extension (supplementary characters) in general information interchange. The Escape character itself is a prefix affecting the interpretation of a limited number of contiguously following characters.
Since:8.0
/** * Escape: A control character intended to provide code extension (supplementary characters) in * general information interchange. The Escape character itself is a prefix affecting the * interpretation of a limited number of contiguously following characters. * * @since 8.0 */
public static final byte ESC = 27;
File Separator: These four information separators may be used within data in optional fashion, except that their hierarchical relationship shall be: FS is the most inclusive, then GS, then RS, and US is least inclusive. (The content and length of a File, Group, Record, or Unit are not specified.)
Since:8.0
/** * File Separator: These four information separators may be used within data in optional fashion, * except that their hierarchical relationship shall be: FS is the most inclusive, then GS, then * RS, and US is least inclusive. (The content and length of a File, Group, Record, or Unit are * not specified.) * * @since 8.0 */
public static final byte FS = 28;
Group Separator: These four information separators may be used within data in optional fashion, except that their hierarchical relationship shall be: FS is the most inclusive, then GS, then RS, and US is least inclusive. (The content and length of a File, Group, Record, or Unit are not specified.)
Since:8.0
/** * Group Separator: These four information separators may be used within data in optional fashion, * except that their hierarchical relationship shall be: FS is the most inclusive, then GS, then * RS, and US is least inclusive. (The content and length of a File, Group, Record, or Unit are * not specified.) * * @since 8.0 */
public static final byte GS = 29;
Record Separator: These four information separators may be used within data in optional fashion, except that their hierarchical relationship shall be: FS is the most inclusive, then GS, then RS, and US is least inclusive. (The content and length of a File, Group, Record, or Unit are not specified.)
Since:8.0
/** * Record Separator: These four information separators may be used within data in optional * fashion, except that their hierarchical relationship shall be: FS is the most inclusive, then * GS, then RS, and US is least inclusive. (The content and length of a File, Group, Record, or * Unit are not specified.) * * @since 8.0 */
public static final byte RS = 30;
Unit Separator: These four information separators may be used within data in optional fashion, except that their hierarchical relationship shall be: FS is the most inclusive, then GS, then RS, and US is least inclusive. (The content and length of a File, Group, Record, or Unit are not specified.)
Since:8.0
/** * Unit Separator: These four information separators may be used within data in optional fashion, * except that their hierarchical relationship shall be: FS is the most inclusive, then GS, then * RS, and US is least inclusive. (The content and length of a File, Group, Record, or Unit are * not specified.) * * @since 8.0 */
public static final byte US = 31;
Space: A normally non-printing graphic character used to separate words. It is also a format effector which controls the movement of the printing position, one printing position forward. (Applicable also to display devices.)
Since:8.0
/** * Space: A normally non-printing graphic character used to separate words. It is also a format * effector which controls the movement of the printing position, one printing position forward. * (Applicable also to display devices.) * * @since 8.0 */
public static final byte SP = 32;
Alternate name for SP.
Since:8.0
/** * Alternate name for {@link #SP}. * * @since 8.0 */
public static final byte SPACE = 32;
Delete: This character is used primarily to "erase" or "obliterate" erroneous or unwanted characters in perforated tape.
Since:8.0
/** * Delete: This character is used primarily to "erase" or "obliterate" erroneous or unwanted * characters in perforated tape. * * @since 8.0 */
public static final byte DEL = 127;
The minimum value of an ASCII character.
Since:9.0 (was type int before 12.0)
/** * The minimum value of an ASCII character. * * @since 9.0 (was type {@code int} before 12.0) */
public static final char MIN = 0;
The maximum value of an ASCII character.
Since:9.0 (was type int before 12.0)
/** * The maximum value of an ASCII character. * * @since 9.0 (was type {@code int} before 12.0) */
public static final char MAX = 127;
A bit mask which selects the bit encoding ASCII character case.
/** A bit mask which selects the bit encoding ASCII character case. */
private static final char CASE_MASK = 0x20;
Returns a copy of the input string in which all uppercase ASCII characters have been converted to lowercase. All other characters are copied without modification.
/** * Returns a copy of the input string in which all {@linkplain #isUpperCase(char) uppercase ASCII * characters} have been converted to lowercase. All other characters are copied without * modification. */
public static String toLowerCase(String string) { int length = string.length(); for (int i = 0; i < length; i++) { if (isUpperCase(string.charAt(i))) { char[] chars = string.toCharArray(); for (; i < length; i++) { char c = chars[i]; if (isUpperCase(c)) { chars[i] = (char) (c ^ CASE_MASK); } } return String.valueOf(chars); } } return string; }
Returns a copy of the input character sequence in which all uppercase ASCII characters have been converted to lowercase. All other characters are copied without modification.
Since:14.0
/** * Returns a copy of the input character sequence in which all {@linkplain #isUpperCase(char) * uppercase ASCII characters} have been converted to lowercase. All other characters are copied * without modification. * * @since 14.0 */
public static String toLowerCase(CharSequence chars) { if (chars instanceof String) { return toLowerCase((String) chars); } char[] newChars = new char[chars.length()]; for (int i = 0; i < newChars.length; i++) { newChars[i] = toLowerCase(chars.charAt(i)); } return String.valueOf(newChars); }
If the argument is an uppercase ASCII character returns the lowercase equivalent. Otherwise returns the argument.
/** * If the argument is an {@linkplain #isUpperCase(char) uppercase ASCII character} returns the * lowercase equivalent. Otherwise returns the argument. */
public static char toLowerCase(char c) { return isUpperCase(c) ? (char) (c ^ CASE_MASK) : c; }
Returns a copy of the input string in which all lowercase ASCII characters have been converted to uppercase. All other characters are copied without modification.
/** * Returns a copy of the input string in which all {@linkplain #isLowerCase(char) lowercase ASCII * characters} have been converted to uppercase. All other characters are copied without * modification. */
public static String toUpperCase(String string) { int length = string.length(); for (int i = 0; i < length; i++) { if (isLowerCase(string.charAt(i))) { char[] chars = string.toCharArray(); for (; i < length; i++) { char c = chars[i]; if (isLowerCase(c)) { chars[i] = (char) (c ^ CASE_MASK); } } return String.valueOf(chars); } } return string; }
Returns a copy of the input character sequence in which all lowercase ASCII characters have been converted to uppercase. All other characters are copied without modification.
Since:14.0
/** * Returns a copy of the input character sequence in which all {@linkplain #isLowerCase(char) * lowercase ASCII characters} have been converted to uppercase. All other characters are copied * without modification. * * @since 14.0 */
public static String toUpperCase(CharSequence chars) { if (chars instanceof String) { return toUpperCase((String) chars); } char[] newChars = new char[chars.length()]; for (int i = 0; i < newChars.length; i++) { newChars[i] = toUpperCase(chars.charAt(i)); } return String.valueOf(newChars); }
If the argument is a lowercase ASCII character returns the uppercase equivalent. Otherwise returns the argument.
/** * If the argument is a {@linkplain #isLowerCase(char) lowercase ASCII character} returns the * uppercase equivalent. Otherwise returns the argument. */
public static char toUpperCase(char c) { return isLowerCase(c) ? (char) (c ^ CASE_MASK) : c; }
Indicates whether c is one of the twenty-six lowercase ASCII alphabetic characters between 'a' and 'z' inclusive. All others (including non-ASCII characters) return false.
/** * Indicates whether {@code c} is one of the twenty-six lowercase ASCII alphabetic characters * between {@code 'a'} and {@code 'z'} inclusive. All others (including non-ASCII characters) * return {@code false}. */
public static boolean isLowerCase(char c) { // Note: This was benchmarked against the alternate expression "(char)(c - 'a') < 26" (Nov '13) // and found to perform at least as well, or better. return (c >= 'a') && (c <= 'z'); }
Indicates whether c is one of the twenty-six uppercase ASCII alphabetic characters between 'A' and 'Z' inclusive. All others (including non-ASCII characters) return false.
/** * Indicates whether {@code c} is one of the twenty-six uppercase ASCII alphabetic characters * between {@code 'A'} and {@code 'Z'} inclusive. All others (including non-ASCII characters) * return {@code false}. */
public static boolean isUpperCase(char c) { return (c >= 'A') && (c <= 'Z'); }
Truncates the given character sequence to the given maximum length. If the length of the sequence is greater than maxLength, the returned string will be exactly maxLength chars in length and will end with the given truncationIndicator. Otherwise, the sequence will be returned as a string with no changes to the content.

Examples:


Ascii.truncate("foobar", 7, "..."); // returns "foobar"
Ascii.truncate("foobar", 5, "..."); // returns "fo..."

Note: This method may work with certain non-ASCII text but is not safe for use with arbitrary Unicode text. It is mostly intended for use with text that is known to be safe for use with it (such as all-ASCII text) and for simple debugging text. When using this method, consider the following:

  • it may split surrogate pairs
  • it may split characters and combining characters
  • it does not consider word boundaries
  • if truncating for display to users, there are other considerations that must be taken into account
  • the appropriate truncation indicator may be locale-dependent
  • it is safe to use non-ASCII characters in the truncation indicator
Throws:
Since:16.0
/** * Truncates the given character sequence to the given maximum length. If the length of the * sequence is greater than {@code maxLength}, the returned string will be exactly {@code * maxLength} chars in length and will end with the given {@code truncationIndicator}. Otherwise, * the sequence will be returned as a string with no changes to the content. * * <p>Examples: * * <pre>{@code * Ascii.truncate("foobar", 7, "..."); // returns "foobar" * Ascii.truncate("foobar", 5, "..."); // returns "fo..." * }</pre> * * <p><b>Note:</b> This method <i>may</i> work with certain non-ASCII text but is not safe for use * with arbitrary Unicode text. It is mostly intended for use with text that is known to be safe * for use with it (such as all-ASCII text) and for simple debugging text. When using this method, * consider the following: * * <ul> * <li>it may split surrogate pairs * <li>it may split characters and combining characters * <li>it does not consider word boundaries * <li>if truncating for display to users, there are other considerations that must be taken * into account * <li>the appropriate truncation indicator may be locale-dependent * <li>it is safe to use non-ASCII characters in the truncation indicator * </ul> * * * @throws IllegalArgumentException if {@code maxLength} is less than the length of {@code * truncationIndicator} * @since 16.0 */
public static String truncate(CharSequence seq, int maxLength, String truncationIndicator) { checkNotNull(seq); // length to truncate the sequence to, not including the truncation indicator int truncationLength = maxLength - truncationIndicator.length(); // in this worst case, this allows a maxLength equal to the length of the truncationIndicator, // meaning that a string will be truncated to just the truncation indicator itself checkArgument( truncationLength >= 0, "maxLength (%s) must be >= length of the truncation indicator (%s)", maxLength, truncationIndicator.length()); if (seq.length() <= maxLength) { String string = seq.toString(); if (string.length() <= maxLength) { return string; } // if the length of the toString() result was > maxLength for some reason, truncate that seq = string; } return new StringBuilder(maxLength) .append(seq, 0, truncationLength) .append(truncationIndicator) .toString(); }
Indicates whether the contents of the given character sequences s1 and s2 are equal, ignoring the case of any ASCII alphabetic characters between 'a' and 'z' or 'A' and 'Z' inclusive.

This method is significantly faster than String.equalsIgnoreCase and should be used in preference if at least one of the parameters is known to contain only ASCII characters.

Note however that this method does not always behave identically to expressions such as:

  • string.toUpperCase().equals("UPPER CASE ASCII")
  • string.toLowerCase().equals("lower case ascii")

due to case-folding of some non-ASCII characters (which does not occur in String.equalsIgnoreCase). However in almost all cases that ASCII strings are used, the author probably wanted the behavior provided by this method rather than the subtle and sometimes surprising behavior of toUpperCase() and toLowerCase().

Since:16.0
/** * Indicates whether the contents of the given character sequences {@code s1} and {@code s2} are * equal, ignoring the case of any ASCII alphabetic characters between {@code 'a'} and {@code 'z'} * or {@code 'A'} and {@code 'Z'} inclusive. * * <p>This method is significantly faster than {@link String#equalsIgnoreCase} and should be used * in preference if at least one of the parameters is known to contain only ASCII characters. * * <p>Note however that this method does not always behave identically to expressions such as: * * <ul> * <li>{@code string.toUpperCase().equals("UPPER CASE ASCII")} * <li>{@code string.toLowerCase().equals("lower case ascii")} * </ul> * * <p>due to case-folding of some non-ASCII characters (which does not occur in {@link * String#equalsIgnoreCase}). However in almost all cases that ASCII strings are used, the author * probably wanted the behavior provided by this method rather than the subtle and sometimes * surprising behavior of {@code toUpperCase()} and {@code toLowerCase()}. * * @since 16.0 */
public static boolean equalsIgnoreCase(CharSequence s1, CharSequence s2) { // Calling length() is the null pointer check (so do it before we can exit early). int length = s1.length(); if (s1 == s2) { return true; } if (length != s2.length()) { return false; } for (int i = 0; i < length; i++) { char c1 = s1.charAt(i); char c2 = s2.charAt(i); if (c1 == c2) { continue; } int alphaIndex = getAlphaIndex(c1); // This was also benchmarked using '&' to avoid branching (but always evaluate the rhs), // however this showed no obvious improvement. if (alphaIndex < 26 && alphaIndex == getAlphaIndex(c2)) { continue; } return false; } return true; }
Returns the non-negative index value of the alpha character c, regardless of case. Ie, 'a'/'A' returns 0 and 'z'/'Z' returns 25. Non-alpha characters return a value of 26 or greater.
/** * Returns the non-negative index value of the alpha character {@code c}, regardless of case. Ie, * 'a'/'A' returns 0 and 'z'/'Z' returns 25. Non-alpha characters return a value of 26 or greater. */
private static int getAlphaIndex(char c) { // Fold upper-case ASCII to lower-case and make zero-indexed and unsigned (by casting to char). return (char) ((c | CASE_MASK) - 'a'); } }