Char和Character

Char和Character

在 Java 中,Character 是一个 包装类(Wrapper Class),它属于 java.lang 包,用于将基本数据类型 char 封装成对象。


Character 的作用

  • 它提供了一些静态方法,用于对字符进行操作(如判断字符类型、大小写转换等)。
  • 在需要使用 对象 而不是基本类型 char 时(例如存储到 Set< Character >List< Character >),Character 可以自动装箱(Autoboxing)和拆箱(Unboxing)。

char 和 Character 的区别

特性 char(基本类型) Character(包装类)
类型 基本数据类型 类(对象)
默认值 ‘\u0000’(空字符) null
存储方式 直接存储字符值 存储 char 的引用
使用场景 高效,适用于简单字符操作 需要对象时(如集合 Set< Character >
自动转换 自动装箱(charCharacter 自动拆箱(Characterchar

常见用法

自动装箱(Autoboxing)和拆箱(Unboxing)

1
2
3
char c = 'A';                // 基本类型 char
Character ch = c; // 自动装箱(char → Character)
char c2 = ch; // 自动拆箱(Character → char)

存储到集合(如 Set< Character >)

1
2
3
Set<Character> uniqueChars = new HashSet<>();
uniqueChars.add('a'); // 自动装箱 char → Character
uniqueChars.add('b');

使用 Character 的静态方法

1
2
3
4
char c = 'A';
System.out.println(Character.isLetter(c)); // true(判断是否是字母)
System.out.println(Character.isDigit('9')); // true(判断是否是数字)
System.out.println(Character.toLowerCase('B')); // 'b'(转小写)

为什么 Set< Character > 需要 Character 而不是 char?

Java 的集合(如 SetList)只能存储 对象,不能存储基本数据类型(charint 等)。

  • Set< char >错误(集合不能存基本类型)
  • Set< Character >正确Characterchar 的包装类,可以存储)

总结

  • Characterchar 的包装类,用于在需要对象的地方存储字符。
  • 它提供了许多有用的静态方法(如 isLetter()toLowerCase())。
  • 在集合(如 Set< Character >)中必须使用 Character 而不是 char

算法中Char和Character的常用知识点与代码示例

字符与 ASCII 码转换

  • char 可以直接转 int(ASCII 码),用于统计字符频率或做数学运算。
  • Character 提供 isLetter()isDigit() 等方法判断字符类型。
1
2
3
4
5
6
7
8
char c = 'A';
int ascii = (int) c; // 65
System.out.println(ascii);

// 判断字符类型
System.out.println(Character.isLetter('a')); // true
System.out.println(Character.isDigit('5')); // true
System.out.println(Character.isWhitespace(' ')); // true

字符大小写转换

  • Character.toLowerCase()Character.toUpperCase() 直接转换。
  • 手动转换(ASCII 码差值法)。
1
2
3
4
5
6
7
8
9
// 方法1:使用 Character 类
char lower = Character.toLowerCase('Z'); // 'z'
char upper = Character.toUpperCase('a'); // 'A'

// 方法2:ASCII 码差值(适用于字母)
char c = 'B';
if (c >= 'A' && c <= 'Z') {
c = (char) (c + ('a' - 'A')); // 'B' -> 'b'
}

统计字符频率

  • int[26]int[256] 数组统计字母或 ASCII 字符出现次数。
  • 适用于 字母异位词(Anagram)唯一字符判断 等问题。
1
2
3
4
5
6
7
String s = "leetcode";
int[] freq = new int[26];
for (char c : s.toCharArray()) {
freq[c - 'a']++; // 'a'->0, 'b'->1, ..., 'z'->25
}
System.out.println(Arrays.toString(freq));
// 输出:[l, e, e, t, c, o, d, e] 的频率统计

统计字符频率

  • int[26]int[256] 数组统计字母或 ASCII 字符出现次数。
  • 适用于 字母异位词(Anagram)唯一字符判断 等问题。
1
2
3
4
5
6
7
String s = "leetcode";
int[] freq = new int[26];
for (char c : s.toCharArray()) {
freq[c - 'a']++; // 'a'->0, 'b'->1, ..., 'z'->25
}
System.out.println(Arrays.toString(freq));
// 输出:[l, e, e, t, c, o, d, e] 的频率统计

字符去重(HashSet / LinkedHashSet)

  • Set< Character > 自动去重,LinkedHashSet 保持顺序。
1
2
3
4
5
6
String s = "hello";
Set<Character> uniqueChars = new LinkedHashSet<>();
for (char c : s.toCharArray()) {
uniqueChars.add(c);
}
System.out.println(uniqueChars); // [h, e, l, o]

字符与字符串转换

  • char[]Stringnew String(charArray)
  • Stringchar[]str.toCharArray()
1
2
3
4
5
char[] chars = {'a', 'b', 'c'};
String str = new String(chars); // "abc"

String s = "hello";
char[] charArray = s.toCharArray(); // ['h', 'e', 'l', 'l', 'o']

回文字符串判断

  • 双指针法,比较 charAt(left)charAt(right)
1
2
3
4
5
6
7
8
9
10
11
public boolean isPalindrome(String s) {
int left = 0, right = s.length() - 1;
while (left < right) {
if (s.charAt(left) != s.charAt(right)) {
return false;
}
left++;
right--;
}
return true;
}

字符串反转

  • 交换 char[] 中的字符。
1
2
3
4
5
6
7
8
9
10
11
12
public String reverseString(String s) {
char[] chars = s.toCharArray();
int left = 0, right = chars.length - 1;
while (left < right) {
char temp = chars[left];
chars[left] = chars[right];
chars[right] = temp;
left++;
right--;
}
return new String(chars);
}

字符流中的第一个唯一字符(LeetCode 387)

  • HashMapint[256] 统计频率,再遍历找第一个唯一字符。
1
2
3
4
5
6
7
8
9
10
11
12
public int firstUniqChar(String s) {
int[] freq = new int[26];
for (char c : s.toCharArray()) {
freq[c - 'a']++;
}
for (int i = 0; i < s.length(); i++) {
if (freq[s.charAt(i) - 'a'] == 1) {
return i;
}
}
return -1;
}

字母异位词分组(LeetCode 49)

  • char[] 排序后的字符串作为 HashMap 的 key。
1
2
3
4
5
6
7
8
9
10
11
public List<List<String>> groupAnagrams(String[] strs) {
Map<String, List<String>> map = new HashMap<>();
for (String s : strs) {
char[] chars = s.toCharArray();
Arrays.sort(chars);
String key = new String(chars);
map.putIfAbsent(key, new ArrayList<>());
map.get(key).add(s);
}
return new ArrayList<>(map.values());
}

最长不含重复字符的子串(LeetCode 3)

  • 滑动窗口 + HashSet 去重。

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
public int lengthOfLongestSubstring(String s) {
Set<Character> set = new HashSet<>();
int left = 0, maxLen = 0;
for (int right = 0; right < s.length(); right++) {
char c = s.charAt(right);
while (set.contains(c)) {
set.remove(s.charAt(left++));
}
set.add(c);
maxLen = Math.max(maxLen, right - left + 1);
}
return maxLen;
}

总结

场景 方法 适用问题
字符统计 int[26]int[256] 字母频率、唯一字符
字符去重 HashSet< Character > 去重、滑动窗口
大小写转换 Character.toUpperCase() 忽略大小写比较
回文判断 双指针 回文字符串
字符串反转 交换 char[] 反转字符串
异位词分组 char[] 排序 + HashMap 字母异位词

掌握这些技巧后,可以高效解决大部分字符串/字符相关的算法题! 🚀