我正在开发一个小应用程序,它可以计算文本中的字符外观并打印一个简单的报告。它基于TreeMap。它应该适用于任何UTF-8(迄今为止)可编码语言。当我尝试通过调用Collator.getInstance()
来使用标准整理器时,我得到异常java.lang.ClassCastException: java.lang.Character cannot be cast to java.lang.String
。
有没有Char collator?
static Map<Character, Integer> map = new TreeMap<>();
TreeMap构造函数可以使用collator,但不能用于Chars。
public static void main(String[] args) {
InputStream in = System.in;
try {
if (in.available() == 0) System.exit(0);
} catch (IOException e) {
e.printStackTrace();
}
count(in);
printMap();
}
static void count(InputStream in) {
new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))
.lines()
.forEach(x -> tallyCharArray(x.toCharArray()));
}
static void tallyCharArray (char[] chars) {
for (int i=0; i<chars.length; i++) {
map.merge(chars[i], 1, Integer::sum);
}
}
static void printMap() {
map.entrySet().stream()
.forEach(x -> System.out.println(x.getKey() + "\t" + x.getValue()));
}
比较问题
static Map<Character, Integer> map = new TreeMap<>(
Collator.getInstance().compare(String.valueOf(c1), String.valueOf(c2))
);
这很笨拙,但它还没有奏效。如何将c1
和c2
与地图绑定?
答案 0 :(得分:1)
<强>已更新强>
如果您只希望Collator
在打印时对结果进行排序,请在计数后进行排序。表现要好得多。请进一步查看代码。
如果您希望TreeMap
使用Collator
,请获取Collator
,然后将Comparator<Character>
提供给TreeMap
构造函数。由于您使用的是Java 8流,因此您可以使用lambda表达式执行此操作:
Collator collator = Collator.getInstance(Locale.GERMAN);
collator.setStrength(Collator.PRIMARY);
Map<Character, int[]> countMap = new TreeMap<>(
(c1, c2) -> collator.compare(c1.toString(), c2.toString())
);
使用Collator
,重音符号和大写/小写字符全部合并。请参阅本答案末尾的示例输出。
计算后排序的完整代码
String input = "Das Polaritätsprofil für das Wort \"Hund\" als Testeinheit " +
"könnte zeigen , dass verschiedene Personen unterschiedliche " +
"Einstellungen zu diesen Tieren haben .";
Map<Character, int[]> countMap = new HashMap<>();
for (Character ch : input.toCharArray()) {
int[] counter = countMap.get(ch);
if (counter == null)
countMap.put(ch, new int[] { 1 });
else
counter[0]++;
}
@SuppressWarnings("unchecked")
Entry<Character, int[]>[] counts = countMap.entrySet().toArray(new Map.Entry[countMap.size()]);
Collator collator = Collator.getInstance(Locale.GERMAN);
Arrays.sort(counts, (e1, e2) -> collator.compare(e1.getKey().toString(), e2.getKey().toString()));
for (Entry<Character, int[]> entry : counts)
System.out.printf("%c - %d%n", entry.getKey(), entry.getValue()[0]);
计算后的排序输出
, - 1
. - 1
" - 2
- 20
a - 6
ä - 1
b - 1
c - 3
d - 6
D - 1
E - 1
e - 22
f - 2
g - 2
h - 5
H - 1
i - 11
k - 1
l - 6
n - 15
ö - 1
o - 4
P - 2
p - 1
r - 8
s - 12
t - 8
T - 2
u - 4
ü - 1
v - 1
W - 1
z - 2
如您所见,结果是根据德语整理打印的,ä
和a
之间的b
。
如果你想要统一大写和小写字符,你应该在结果中决定你想要哪个并转换成那个,否则它将是任意的。
在PRIMARY
Collator
TreeMap
的输出
- 20
, - 1
. - 1
" - 2
a - 7
b - 1
c - 3
D - 7
e - 23
f - 2
g - 2
H - 6
i - 11
k - 1
l - 6
n - 15
o - 5
P - 3
r - 8
s - 12
t - 10
ü - 5
v - 1
W - 1
z - 2
正如您所看到的,有时您会得到一个小写字母(例如a
),有时您会得到一个大写字母(例如D
),有时您会得到一个带重音的字母(例如{{1} }})。 这对我来说似乎不对。
答案 1 :(得分:0)
char
是UTF-16格式的2字节值。 Unicode符号,代码点,达到3字节范围,在java中表示为 int 。所以最好使用代码点。从它们创建一个String,如下所示:
int codePoint = ...
int[] codePoints = { codePoint };
String s = new String(codePoints, 0, codePoints.length);
然后整理是没问题的。
顺便说一句,Character有许多不错的Unicode信息:
String name = Character.getName(codePoint);