【发布时间】:2021-01-20 02:28:24
【问题描述】:
我有一种感觉,我的字符串(带有变音符号)在我的类中使用不同的编码,在 hashmap 中也不同(对于其他地图实例也“工作”)字符串是在我的类中定义的,我尝试将其用作在地图中键入,也放一些值,当我尝试通过键获取该值时,它不起作用。有趣的事情 - 在 intellij 评估期间按预期工作。 一些细节:
IntelliJ IDEA 2019.3.1(社区版) 构建#IC-193.5662.53, 12月18日建成, 2019运行时版本:11.0.5+10-b520.17 amd64 虚拟机:JetBrains s.r.o Windows 10 10.0 GC 的 OpenJDK 64 位服务器虚拟机: ParNew,ConcurrentMarkSweep 内存:1986M 内核:4 注册表: 非捆绑插件:
使用 SDK Java 1.8.0_231
为了检查这种情况是否可重复,我创建了这个 junit:
@Test
public void test() {
Map<String, String> map = new TreeMap<>();
map.put("język", "polski");
String res = map.get("język");
System.out.println(res);
}
在放入 hashmap 期间,单词“język”被转换为“j?zyk”,但在从 map 中获取它的过程中,它也被转换为“j?zyk”,所以一切看起来都很好。但在我的生产代码中,它更复杂。我使用以下代码从字符串列表创建了地图:
private Map<String, String> getBookDetails(HtmlElement from) {
HtmlElement bookDetails = BOOK_DETAILS.getFirst(from);
return Arrays.stream(bookDetails.asText().split(BOOK_DETAILS_SEPARATOR))
.collect(MappingErrors.collector());
}
bookDetails.asXml:
<div class="collapse d-xs-none" id="book-details">
<dl>
<dt>
Tytuł oryginału:
</dt>
<dd>
Wat?
</dd>
<dt>
Data wydania:
</dt>
<dd>
2016-05-16
</dd>
<dt data-toggle="tooltip" title="Data pierwszego wydania polskiego">
Data 1. wyd. pol.:
</dt>
<dd>
2016-05-16
</dd>
<dt>
Liczba stron:
</dt>
<dd>
20
</dd>
<dt>
Język:
</dt>
<dd>
polski
</dd>
<dt>
ISBN:
</dt>
<dd>
9788374206600
</dd>
<dt>
Tłumacz:
</dt>
<dd>
<a href="https://lubimyczytac.pl/tlumacz/10593/ryszard-turczyn">
Ryszard Turczyn
</a>
</dd>
<dt class="d-lg-none">
Wydawnictwo:
</dt>
<dd class="d-lg-none">
<a href="https://lubimyczytac.pl/wydawnictwo/13832/wydawnictwo-adamada/ksiazki">
Wydawnictwo Adamada
</a>
</dd>
</dl>
</div>
缺少变量
private String BOOK_DETAILS_SEPARATOR = "\r\n";
static final DefinedHtmlElement BOOK_DETAILS =
new DefinedHtmlElement("div", "id", "book-details");
DefinedHtmlElement 内部类:
static class DefinedHtmlElement {
String elementName;
String attributeName;
String attributeValue;
DefinedHtmlElement (String elementName, String attributeName, String attributeValue) {
this.attributeName = attributeName;
this.elementName = elementName;
this.attributeValue = attributeValue;
}
public String getAttributeName() {
return attributeName;
}
public String getAttributeValue() {
return attributeValue;
}
public String getElementName() {
return elementName;
}
public HtmlElement getFirst(HtmlElement element) {
return element
.getElementsByAttribute(elementName, attributeName, attributeValue)
.stream().findFirst().orElse(null);
}
}
和收集器:
private static final class MappingErrors {
private static int counter = 1;
private Map<String, String> map = new TreeMap<>();
private String first;
private String second;
public void accept(String str) {
first = second;
second = str;
if (first != null && counter % 2 == 0) {
map.put(first.trim(), second.trim());
}
counter++;
}
public MappingErrors combine(MappingErrors other) {
throw new UnsupportedOperationException("Parallel Stream not supported");
}
public Map<String, String> finish() {
return map;
}
public static Collector<String, ?, Map<String, String>> collector() {
return Collector.of(MappingErrors::new, MappingErrors::accept, MappingErrors::combine,
MappingErrors::finish);
}
}
有趣的事实是,在将键/值放入映射期间,它不会转换为问号版本,而是按应有的方式写入。当我尝试通过键获取值时,键字符串被转换,找不到任何匹配的键,并且代码不起作用。我尝试使用单词“Język:”作为键,得到“JÄ>商标符号 我不知道从哪里找到根本原因。我检查所有文件是否具有相同的编码(在这种情况下,utf-8 和 windows 1252 的工作方式相同)所有项目都设置了相同的编码,没有输入文件,只从网页中抓取,并通过 com.gargoylesoftware 获取字符串.htmlunit.html.HtmlElement 如果它很重要。有谁知道在哪里可以找到根本原因?编码是正确的线索,还是完全不同的东西?当然我可以创建walkaround来将所有变音符号替换为正常,但我想了解发生了什么 更新:
我发现来自 gargoylesoftware 的数据是不同的。这不是一种填充地图的方式,它没有连接到地图(实际上地图是第一个可见的地方)。我修改了一点代码: if 中的条件永远不会为真。仍然只有在评估期间才是真的,但永远不会达到与 println 的线。对象映射如下所示: 因此,手动添加的条目以某种方式更改为“TM”版本。但没关系,因为在从这张地图获取价值的过程中,同样的变化发生了,所以价值是正确的。但是为什么手动放置字符串和 gargoylesoftware 之间存在差异?private Map<String, String> getBookDetails(HtmlElement from) {
HtmlElement bookDetails = BOOK_DETAILS.getFirst(from);
String[] split = bookDetails.asText().split(BOOK_DETAILS_SEPARATOR);
Map<String, String> mapa = new HashMap<>();
for (int i=0;i<split.length-1;i+=2) {
mapa.put(split[i].trim(), split[i+1].trim());
if (split[i].trim().compareTo("Język:") == 0) {
System.out.println("test");
}
}
mapa.put("Język:","TEST");
return mapa;
}
"Data 1. wyd. pol.:" -> "2016-05-16"
"Liczba stron:" -> "20"
"Data wydania:" -> "2016-05-16"
"Tłumacz:" -> "Ryszard Turczyn"
"Język:" -> "TEST"
"Tytuł oryginału:" -> "Wat?"
"Język:" -> "polski"
"Wydawnictwo:" -> "Wydawnictwo Adamada"
"ISBN:" -> "9788374206600"
【问题讨论】:
-
你能在这里发布你的“HtmlElement from”吗?如果我们无法复制您的示例,我们将无法帮助您。顺便说一句,jUnit 测试对我来说工作正常
-
String始终为 utf-16。Map没有转化,除非你自己做。 -
我认为问题没有包含足够的信息来调试问题。如果您对如何调试它没有其他想法,您可以随时添加调试打印以查看字符串“乱码”的第一个点。
-
否则,看起来就像是编码错误。
-
我知道,但是为了能够测试我们是否需要您正在使用的所有输入,其中包括“HtmlElement from”、“BOOK_DETAILS”、“BOOK_DETAILS_SEPARATOR”的值。所以直到您编辑您的问题并包含足够的代码以允许其他人重现我们无法帮助您的问题
标签: java string dictionary diacritics