问题描述
我感觉我的字符串(带有变音符号)在我的班级中使用不同的编码,在哈希图中使用不同的编码(对于其他地图实例也“工作”),在我的班级中定义了字符串,我尝试将其用作在地图中键入关键值,然后再输入一些值,当我尝试通过关键值获得此值时,它将无法正常工作。好玩的东西-在intellij评估过程中按预期工作。 一些细节:
IntelliJ IDEA 2019.3.1(社区版) 版本#IC-193.5662.53, 建于12月18日, 2019运行时版本:11.0.5 + 10-b520.17 amd64 VM:由JetBrains s.r.o Windows 10 10.0 GC发行的OpenJDK 64位服务器VM: 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);
}
在放入哈希图期间,单词“język”会转换为“ j?zyk”,但是在从地图中获取单词时,它也会转换为“ 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获取String .htmlunit.html.HtmlElement(如果重要)。有谁知道在哪里找到根本原因?是编码正确的线索,还是完全不同?当然,我可以创建替代方法以将所有变音符号替换为正常字符,但是我想了解发生了什么 更新:
我发现来自石像鬼软件的数据是不同的。这不是填充地图的方法,它没有连接到地图(实际上,地图是第一个可见的地方)。我修改了一些代码: if中的条件永远不会为真。仍然仅在评估期间是正确的,但永远不会达到与println一致的行。对象映射看起来像这样: 因此,手动添加的条目以某种方式更改为“ TM”版本。没关系,因为在从该地图获取价值的过程中发生了相同的更改,因此价值是正确的。但是,为什么手动放置的字符串与gargoylelesoft的字符串之间有什么区别?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"
解决方法
我找到了!这是intellij,windows和网页中复杂的编码关系。 HtmlElement中的数据具有utf8,String具有utf16,windows具有其自己的,而intellij具有所有这些的某种组合。我在玩String构造函数,并找到了正确的组合。
new String(labelFromHtmlElement.getBytes("UTF-8"),"windows-1252");
用变音符号编程可能很复杂:)