使用地图时编码字符串

问题描述

我感觉我的字符串(带有变音符号)在我的班级中使用不同的编码,在哈希图中使用不同的编码(对于其他地图实例也“工作”),在我的班级中定义了字符串,我尝试将其用作在地图中键入关键值,然后再输入一些值,当我尝试通过关键值获得此值时,它将无法正常工作。好玩的东西-在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(如果重要)。有谁知道在哪里找到根本原因?是编码正确的线索,还是完全不同?当然,我可以创建替代方法以将所有变音符号替换为正常字符,但是我想了解发生了什么

更新: 我发现来自石像鬼软件的数据是不同的。这不是填充地图的方法,它没有连接到地图(实际上,地图是第一个可见的地方)。我修改了一些代码:

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;
}

if中的条件永远不会为真。仍然仅在评估期间是正确的,但永远不会达到与println一致的行。对象映射看起来像这样:

"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"

因此,手动添加的条目以某种方式更改为“ TM”版本。没关系,因为在从该地图获取价值的过程中发生了相同的更改,因此价值是正确的。但是,为什么手动放置的字符串与gargoylelesoft的字符串之间有什么区别?

解决方法

我找到了!这是intellij,windows和网页中复杂的编码关系。 HtmlElement中的数据具有utf8,String具有utf16,windows具有其自己的,而intellij具有所有这些的某种组合。我在玩String构造函数,并找到了正确的组合。

new String(labelFromHtmlElement.getBytes("UTF-8"),"windows-1252");

用变音符号编程可能很复杂:)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...