View Javadoc

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.lang3;
18  
19  /**
20   * <p>Operations on char primitives and Character objects.</p>
21   *
22   * <p>This class tries to handle {@code null} input gracefully.
23   * An exception will not be thrown for a {@code null} input.
24   * Each method documents its behaviour in more detail.</p>
25   * 
26   * <p>#ThreadSafe#</p>
27   * @since 2.1
28   * @version $Id: CharUtils.java 1436768 2013-01-22 07:07:42Z ggregory $
29   */
30  public class CharUtils {
31      
32      private static final String[] CHAR_STRING_ARRAY = new String[128];
33      
34      /**
35       * {@code \u000a} linefeed LF ('\n').
36       * 
37       * @see <a href="http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#101089">JLF: Escape Sequences
38       *      for Character and String Literals</a>
39       * @since 2.2
40       */
41      public static final char LF = '\n';
42  
43      /**
44       * {@code \u000d} carriage return CR ('\r').
45       * 
46       * @see <a href="http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#101089">JLF: Escape Sequences
47       *      for Character and String Literals</a>
48       * @since 2.2
49       */
50      public static final char CR = '\r';
51      
52  
53      static {
54          for (char c = 0; c < CHAR_STRING_ARRAY.length; c++) {
55              CHAR_STRING_ARRAY[c] = String.valueOf(c);
56          }
57      }
58  
59      /**
60       * <p>{@code CharUtils} instances should NOT be constructed in standard programming.
61       * Instead, the class should be used as {@code CharUtils.toString('c');}.</p>
62       *
63       * <p>This constructor is public to permit tools that require a JavaBean instance
64       * to operate.</p>
65       */
66      public CharUtils() {
67        super();
68      }
69  
70      //-----------------------------------------------------------------------
71      /**
72       * <p>Converts the character to a Character.</p>
73       * 
74       * <p>For ASCII 7 bit characters, this uses a cache that will return the
75       * same Character object each time.</p>
76       *
77       * <pre>
78       *   CharUtils.toCharacterObject(' ')  = ' '
79       *   CharUtils.toCharacterObject('A')  = 'A'
80       * </pre>
81       *
82       * @deprecated Java 5 introduced {@link Character#valueOf(char)} which caches chars 0 through 127.
83       * @param ch  the character to convert
84       * @return a Character of the specified character
85       */
86      @Deprecated
87      public static Character toCharacterObject(final char ch) {
88          return Character.valueOf(ch);
89      }
90      
91      /**
92       * <p>Converts the String to a Character using the first character, returning
93       * null for empty Strings.</p>
94       * 
95       * <p>For ASCII 7 bit characters, this uses a cache that will return the
96       * same Character object each time.</p>
97       * 
98       * <pre>
99       *   CharUtils.toCharacterObject(null) = null
100      *   CharUtils.toCharacterObject("")   = null
101      *   CharUtils.toCharacterObject("A")  = 'A'
102      *   CharUtils.toCharacterObject("BA") = 'B'
103      * </pre>
104      *
105      * @param str  the character to convert
106      * @return the Character value of the first letter of the String
107      */
108     public static Character toCharacterObject(final String str) {
109         if (StringUtils.isEmpty(str)) {
110             return null;
111         }
112         return Character.valueOf(str.charAt(0));
113     }
114     
115     //-----------------------------------------------------------------------
116     /**
117      * <p>Converts the Character to a char throwing an exception for {@code null}.</p>
118      * 
119      * <pre>
120      *   CharUtils.toChar(' ')  = ' '
121      *   CharUtils.toChar('A')  = 'A'
122      *   CharUtils.toChar(null) throws IllegalArgumentException
123      * </pre>
124      *
125      * @param ch  the character to convert
126      * @return the char value of the Character
127      * @throws IllegalArgumentException if the Character is null
128      */
129     public static char toChar(final Character ch) {
130         if (ch == null) {
131             throw new IllegalArgumentException("The Character must not be null");
132         }
133         return ch.charValue();
134     }
135     
136     /**
137      * <p>Converts the Character to a char handling {@code null}.</p>
138      * 
139      * <pre>
140      *   CharUtils.toChar(null, 'X') = 'X'
141      *   CharUtils.toChar(' ', 'X')  = ' '
142      *   CharUtils.toChar('A', 'X')  = 'A'
143      * </pre>
144      *
145      * @param ch  the character to convert
146      * @param defaultValue  the value to use if the  Character is null
147      * @return the char value of the Character or the default if null
148      */
149     public static char toChar(final Character ch, final char defaultValue) {
150         if (ch == null) {
151             return defaultValue;
152         }
153         return ch.charValue();
154     }
155     
156     //-----------------------------------------------------------------------
157     /**
158      * <p>Converts the String to a char using the first character, throwing
159      * an exception on empty Strings.</p>
160      * 
161      * <pre>
162      *   CharUtils.toChar("A")  = 'A'
163      *   CharUtils.toChar("BA") = 'B'
164      *   CharUtils.toChar(null) throws IllegalArgumentException
165      *   CharUtils.toChar("")   throws IllegalArgumentException
166      * </pre>
167      *
168      * @param str  the character to convert
169      * @return the char value of the first letter of the String
170      * @throws IllegalArgumentException if the String is empty
171      */
172     public static char toChar(final String str) {
173         if (StringUtils.isEmpty(str)) {
174             throw new IllegalArgumentException("The String must not be empty");
175         }
176         return str.charAt(0);
177     }
178     
179     /**
180      * <p>Converts the String to a char using the first character, defaulting
181      * the value on empty Strings.</p>
182      * 
183      * <pre>
184      *   CharUtils.toChar(null, 'X') = 'X'
185      *   CharUtils.toChar("", 'X')   = 'X'
186      *   CharUtils.toChar("A", 'X')  = 'A'
187      *   CharUtils.toChar("BA", 'X') = 'B'
188      * </pre>
189      *
190      * @param str  the character to convert
191      * @param defaultValue  the value to use if the  Character is null
192      * @return the char value of the first letter of the String or the default if null
193      */
194     public static char toChar(final String str, final char defaultValue) {
195         if (StringUtils.isEmpty(str)) {
196             return defaultValue;
197         }
198         return str.charAt(0);
199     }
200     
201     //-----------------------------------------------------------------------
202     /**
203      * <p>Converts the character to the Integer it represents, throwing an
204      * exception if the character is not numeric.</p>
205      * 
206      * <p>This method coverts the char '1' to the int 1 and so on.</p>
207      *
208      * <pre>
209      *   CharUtils.toIntValue('3')  = 3
210      *   CharUtils.toIntValue('A')  throws IllegalArgumentException
211      * </pre>
212      *
213      * @param ch  the character to convert
214      * @return the int value of the character
215      * @throws IllegalArgumentException if the character is not ASCII numeric
216      */
217     public static int toIntValue(final char ch) {
218         if (isAsciiNumeric(ch) == false) {
219             throw new IllegalArgumentException("The character " + ch + " is not in the range '0' - '9'");
220         }
221         return ch - 48;
222     }
223     
224     /**
225      * <p>Converts the character to the Integer it represents, throwing an
226      * exception if the character is not numeric.</p>
227      * 
228      * <p>This method coverts the char '1' to the int 1 and so on.</p>
229      *
230      * <pre>
231      *   CharUtils.toIntValue('3', -1)  = 3
232      *   CharUtils.toIntValue('A', -1)  = -1
233      * </pre>
234      *
235      * @param ch  the character to convert
236      * @param defaultValue  the default value to use if the character is not numeric
237      * @return the int value of the character
238      */
239     public static int toIntValue(final char ch, final int defaultValue) {
240         if (isAsciiNumeric(ch) == false) {
241             return defaultValue;
242         }
243         return ch - 48;
244     }
245     
246     /**
247      * <p>Converts the character to the Integer it represents, throwing an
248      * exception if the character is not numeric.</p>
249      * 
250      * <p>This method coverts the char '1' to the int 1 and so on.</p>
251      *
252      * <pre>
253      *   CharUtils.toIntValue('3')  = 3
254      *   CharUtils.toIntValue(null) throws IllegalArgumentException
255      *   CharUtils.toIntValue('A')  throws IllegalArgumentException
256      * </pre>
257      *
258      * @param ch  the character to convert, not null
259      * @return the int value of the character
260      * @throws IllegalArgumentException if the Character is not ASCII numeric or is null
261      */
262     public static int toIntValue(final Character ch) {
263         if (ch == null) {
264             throw new IllegalArgumentException("The character must not be null");
265         }
266         return toIntValue(ch.charValue());
267     }
268     
269     /**
270      * <p>Converts the character to the Integer it represents, throwing an
271      * exception if the character is not numeric.</p>
272      * 
273      * <p>This method coverts the char '1' to the int 1 and so on.</p>
274      *
275      * <pre>
276      *   CharUtils.toIntValue(null, -1) = -1
277      *   CharUtils.toIntValue('3', -1)  = 3
278      *   CharUtils.toIntValue('A', -1)  = -1
279      * </pre>
280      *
281      * @param ch  the character to convert
282      * @param defaultValue  the default value to use if the character is not numeric
283      * @return the int value of the character
284      */
285     public static int toIntValue(final Character ch, final int defaultValue) {
286         if (ch == null) {
287             return defaultValue;
288         }
289         return toIntValue(ch.charValue(), defaultValue);
290     }
291     
292     //-----------------------------------------------------------------------
293     /**
294      * <p>Converts the character to a String that contains the one character.</p>
295      * 
296      * <p>For ASCII 7 bit characters, this uses a cache that will return the
297      * same String object each time.</p>
298      *
299      * <pre>
300      *   CharUtils.toString(' ')  = " "
301      *   CharUtils.toString('A')  = "A"
302      * </pre>
303      *
304      * @param ch  the character to convert
305      * @return a String containing the one specified character
306      */
307     public static String toString(final char ch) {
308         if (ch < 128) {
309             return CHAR_STRING_ARRAY[ch];
310         }
311         return new String(new char[] {ch});
312     }
313     
314     /**
315      * <p>Converts the character to a String that contains the one character.</p>
316      * 
317      * <p>For ASCII 7 bit characters, this uses a cache that will return the
318      * same String object each time.</p>
319      * 
320      * <p>If {@code null} is passed in, {@code null} will be returned.</p>
321      *
322      * <pre>
323      *   CharUtils.toString(null) = null
324      *   CharUtils.toString(' ')  = " "
325      *   CharUtils.toString('A')  = "A"
326      * </pre>
327      *
328      * @param ch  the character to convert
329      * @return a String containing the one specified character
330      */
331     public static String toString(final Character ch) {
332         if (ch == null) {
333             return null;
334         }
335         return toString(ch.charValue());
336     }
337     
338     //--------------------------------------------------------------------------
339     /**
340      * <p>Converts the string to the Unicode format '\u0020'.</p>
341      * 
342      * <p>This format is the Java source code format.</p>
343      *
344      * <pre>
345      *   CharUtils.unicodeEscaped(' ') = "\u0020"
346      *   CharUtils.unicodeEscaped('A') = "\u0041"
347      * </pre>
348      * 
349      * @param ch  the character to convert
350      * @return the escaped Unicode string
351      */
352     public static String unicodeEscaped(final char ch) {
353         if (ch < 0x10) {
354             return "\\u000" + Integer.toHexString(ch);
355         } else if (ch < 0x100) {
356             return "\\u00" + Integer.toHexString(ch);
357         } else if (ch < 0x1000) {
358             return "\\u0" + Integer.toHexString(ch);
359         }
360         return "\\u" + Integer.toHexString(ch);
361     }
362     
363     /**
364      * <p>Converts the string to the Unicode format '\u0020'.</p>
365      * 
366      * <p>This format is the Java source code format.</p>
367      * 
368      * <p>If {@code null} is passed in, {@code null} will be returned.</p>
369      *
370      * <pre>
371      *   CharUtils.unicodeEscaped(null) = null
372      *   CharUtils.unicodeEscaped(' ')  = "\u0020"
373      *   CharUtils.unicodeEscaped('A')  = "\u0041"
374      * </pre>
375      * 
376      * @param ch  the character to convert, may be null
377      * @return the escaped Unicode string, null if null input
378      */
379     public static String unicodeEscaped(final Character ch) {
380         if (ch == null) {
381             return null;
382         }
383         return unicodeEscaped(ch.charValue());
384     }
385     
386     //--------------------------------------------------------------------------
387     /**
388      * <p>Checks whether the character is ASCII 7 bit.</p>
389      *
390      * <pre>
391      *   CharUtils.isAscii('a')  = true
392      *   CharUtils.isAscii('A')  = true
393      *   CharUtils.isAscii('3')  = true
394      *   CharUtils.isAscii('-')  = true
395      *   CharUtils.isAscii('\n') = true
396      *   CharUtils.isAscii('&copy;') = false
397      * </pre>
398      * 
399      * @param ch  the character to check
400      * @return true if less than 128
401      */
402     public static boolean isAscii(final char ch) {
403         return ch < 128;
404     }
405     
406     /**
407      * <p>Checks whether the character is ASCII 7 bit printable.</p>
408      *
409      * <pre>
410      *   CharUtils.isAsciiPrintable('a')  = true
411      *   CharUtils.isAsciiPrintable('A')  = true
412      *   CharUtils.isAsciiPrintable('3')  = true
413      *   CharUtils.isAsciiPrintable('-')  = true
414      *   CharUtils.isAsciiPrintable('\n') = false
415      *   CharUtils.isAsciiPrintable('&copy;') = false
416      * </pre>
417      * 
418      * @param ch  the character to check
419      * @return true if between 32 and 126 inclusive
420      */
421     public static boolean isAsciiPrintable(final char ch) {
422         return ch >= 32 && ch < 127;
423     }
424     
425     /**
426      * <p>Checks whether the character is ASCII 7 bit control.</p>
427      *
428      * <pre>
429      *   CharUtils.isAsciiControl('a')  = false
430      *   CharUtils.isAsciiControl('A')  = false
431      *   CharUtils.isAsciiControl('3')  = false
432      *   CharUtils.isAsciiControl('-')  = false
433      *   CharUtils.isAsciiControl('\n') = true
434      *   CharUtils.isAsciiControl('&copy;') = false
435      * </pre>
436      * 
437      * @param ch  the character to check
438      * @return true if less than 32 or equals 127
439      */
440     public static boolean isAsciiControl(final char ch) {
441         return ch < 32 || ch == 127;
442     }
443     
444     /**
445      * <p>Checks whether the character is ASCII 7 bit alphabetic.</p>
446      *
447      * <pre>
448      *   CharUtils.isAsciiAlpha('a')  = true
449      *   CharUtils.isAsciiAlpha('A')  = true
450      *   CharUtils.isAsciiAlpha('3')  = false
451      *   CharUtils.isAsciiAlpha('-')  = false
452      *   CharUtils.isAsciiAlpha('\n') = false
453      *   CharUtils.isAsciiAlpha('&copy;') = false
454      * </pre>
455      * 
456      * @param ch  the character to check
457      * @return true if between 65 and 90 or 97 and 122 inclusive
458      */
459     public static boolean isAsciiAlpha(final char ch) {
460         return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
461     }
462     
463     /**
464      * <p>Checks whether the character is ASCII 7 bit alphabetic upper case.</p>
465      *
466      * <pre>
467      *   CharUtils.isAsciiAlphaUpper('a')  = false
468      *   CharUtils.isAsciiAlphaUpper('A')  = true
469      *   CharUtils.isAsciiAlphaUpper('3')  = false
470      *   CharUtils.isAsciiAlphaUpper('-')  = false
471      *   CharUtils.isAsciiAlphaUpper('\n') = false
472      *   CharUtils.isAsciiAlphaUpper('&copy;') = false
473      * </pre>
474      * 
475      * @param ch  the character to check
476      * @return true if between 65 and 90 inclusive
477      */
478     public static boolean isAsciiAlphaUpper(final char ch) {
479         return ch >= 'A' && ch <= 'Z';
480     }
481     
482     /**
483      * <p>Checks whether the character is ASCII 7 bit alphabetic lower case.</p>
484      *
485      * <pre>
486      *   CharUtils.isAsciiAlphaLower('a')  = true
487      *   CharUtils.isAsciiAlphaLower('A')  = false
488      *   CharUtils.isAsciiAlphaLower('3')  = false
489      *   CharUtils.isAsciiAlphaLower('-')  = false
490      *   CharUtils.isAsciiAlphaLower('\n') = false
491      *   CharUtils.isAsciiAlphaLower('&copy;') = false
492      * </pre>
493      * 
494      * @param ch  the character to check
495      * @return true if between 97 and 122 inclusive
496      */
497     public static boolean isAsciiAlphaLower(final char ch) {
498         return ch >= 'a' && ch <= 'z';
499     }
500     
501     /**
502      * <p>Checks whether the character is ASCII 7 bit numeric.</p>
503      *
504      * <pre>
505      *   CharUtils.isAsciiNumeric('a')  = false
506      *   CharUtils.isAsciiNumeric('A')  = false
507      *   CharUtils.isAsciiNumeric('3')  = true
508      *   CharUtils.isAsciiNumeric('-')  = false
509      *   CharUtils.isAsciiNumeric('\n') = false
510      *   CharUtils.isAsciiNumeric('&copy;') = false
511      * </pre>
512      * 
513      * @param ch  the character to check
514      * @return true if between 48 and 57 inclusive
515      */
516     public static boolean isAsciiNumeric(final char ch) {
517         return ch >= '0' && ch <= '9';
518     }
519     
520     /**
521      * <p>Checks whether the character is ASCII 7 bit numeric.</p>
522      *
523      * <pre>
524      *   CharUtils.isAsciiAlphanumeric('a')  = true
525      *   CharUtils.isAsciiAlphanumeric('A')  = true
526      *   CharUtils.isAsciiAlphanumeric('3')  = true
527      *   CharUtils.isAsciiAlphanumeric('-')  = false
528      *   CharUtils.isAsciiAlphanumeric('\n') = false
529      *   CharUtils.isAsciiAlphanumeric('&copy;') = false
530      * </pre>
531      * 
532      * @param ch  the character to check
533      * @return true if between 48 and 57 or 65 and 90 or 97 and 122 inclusive
534      */
535     public static boolean isAsciiAlphanumeric(final char ch) {
536         return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9');
537     }
538     
539 }