初学 Java ,请教大神们一个问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
chur
V2EX    Java

初学 Java ,请教大神们一个问题

  •  
  •   chur 2022-02-11 14:58:14 +08:00 4058 次点击
    这是一个创建于 1366 天前的主题,其中的信息可能已经有所发展或是发生改变。

    rt.最近在看编码方面的文章,了解到 utf32 是定长编码,String.charAt 方法对此编码有更好的支持,于是写了段代码试了一下:

     long start = System.nanoTime(); for (int i = 0; i < utf8.length(); i++) { char c = utf8.charAt(i); } long end = System.nanoTime(); System.out.println(end - stat); start = System.nanoTime(); for (int i = 0; i < utf32.length(); i++) { char c = utf32.charAt(i); } end = System.nanoTime(); System.out.println(end - start); System.out.println("=========="); 

    将这段代码放入 for 循环中输出如下

    5435600 3786200 ========== 5370700 200 ========== .... 

    手动复制代码片段执行输出如下:

    7608200 5690900 ========== 5709800 4930700 ========== ... 

    放入 for 循环中执行的代码,从第二次循环开始 utf32 耗时在 0-500 纳秒浮动 是代码哪里写的有问题吗? utf8 和 utf32 两个 String 对象是同一段一亿个字符的文本

    24 条回复    2022-02-14 13:41:52 +08:00
    Kasumi20
        1
    Kasumi20  
       2022-02-11 15:28:47 +08:00   1
    你的 utf8 和 utf32 怎么来的?这样 new 出来的吗?

    String(byte[] bytes, Charset charset)
    Constructs a new String by decoding the specified array of bytes using the specified charset.

    Java 中的对象使用无法修改的 UTF-16 编码,不可能有 UTF-8 和 UTF-32 编码的 Java 字符串。
    txwd
        2
    txwd  
       2022-02-11 16:10:00 +08:00
    借楼问,为什么 Java 的工程目录要那么多层级...\src\main\java\com\...
    KomiSans
        3
    KomiSans  
       2022-02-11 16:11:46 +08:00
    [![HadMz8.png]( https://s4.ax1x.com/2022/02/11/HadMz8.png)]( https://imgtu.com/i/HadMz8)
    像是这样的么? 好像对于比较大的文本 UTF32 耗时比较短相对于 UTF8
    q474818917
        4
    q474818917  
       2022-02-11 16:27:01 +08:00   1
    还学 java ?这都卷成什么样了
    chur
        5
    chur  
    OP
       2022-02-11 16:36:27 +08:00
    @Kasumi20 貌似是可以的?对同一个字符的 byte 数组使用 new String 指定 utf-8 或 utf-32 字符集重新编码会得到不同的结果
    chur
        6
    chur  
    OP
       2022-02-11 16:37:59 +08:00
    @KomiSans 对,现在疑惑的点在于 这段代码放到 for 循环中 输出的结果很离谱= =
    chur
        7
    chur  
    OP
       2022-02-11 16:48:04 +08:00   1
    @txwd src/main/java 貌似是 maven 编译项目时默认的路径,可以修改; com 和后面的就是自定义的了
    VeryZero
        8
    VeryZero  
       2022-02-11 16:49:15 +08:00
    感觉是被优化了,把各种优化关了试试
    xiangyuecn
        9
    xiangyuecn  
       2022-02-11 16:50:12 +08:00   2
    @txwd #2 java 没有要求你这样搞,但开发环境要求你这样搞 其实你源码随便放哪里都行,只要编译时找得到
    xiangyuecn
        10
    xiangyuecn  
       2022-02-11 16:53:21 +08:00
    欢迎观摩我手撸的 java 仓库,https://github.com/xiangyuecn/RSA-java 源码文件全丢在根目录,但包名还是那个包名
    gadfly3173
        11
    gadfly3173  
       2022-02-11 17:03:34 +08:00   1
    @txwd #2 这玩意算是工程实践,src 下 main 放项目源码,test 放单元测试; main 下 java 放包名路径,resource 下放要打包进去的资源。你乐意的话把打包配置改了也能放别的地方
    Jooooooooo
        12
    Jooooooooo  
       2022-02-11 17:17:13 +08:00
    搜 jit
    Kasumi20
        13
    Kasumi20  
       2022-02-11 17:25:18 +08:00
    charset 不是指定 String 的编码,而是指定 bytes 的解码方法,你用 UTF-32 去解码,得到的乱码字符数量很可能只是 UTF-8 的四分之一
    Kasumi20
        14
    Kasumi20  
       2022-02-11 17:32:05 +08:00
    如果你这堆文本都是 UTF-8 编码的汉字的话,UTF-8 和 UTF-32 去解码得到的 UTF-16 代码点的比值应该是 3 : 4 ,即 0.75

    > 4930700/5709800
    0.8635503870538372

    > 5690900/7608200
    0.7479955837123105

    似乎是成立的
    thedrwu
        15
    thedrwu  
       2022-02-11 17:35:10 +08:00 via Android   2
    @txwd
    可能因为 Java 语言的设计初衷就不是用来写单文件的迷你 script 的。于是人们在 applet 之外发明了 Javascript 。
    讽刺的是 Javascript 屠了 applet 的龙。
    pxiphx891
        16
    pxiphx891  
       2022-02-11 18:10:03 +08:00
    @chur @KomiSans 你们 getBytes()的时候,得到的是默认编码的 bytes ,一般是 utf8 ,utf8 的 bytes 转换到 utf32 ,length 会变短
    pxiphx891
        17
    pxiphx891  
       2022-02-11 18:11:50 +08:00
    可以试试这段代码:
    ```java
    import java.nio.charset.StandardCharsets;

    public class Utf{
    public static void main(String[] args) throws Exception {
    for (int j = 0; j < 30; j++) {
    String b = "《新能源汽车推广应用推荐车型目录》( 2021 年第 4 批)车型主要参数";
    String utf8 = new String(b.getBytes(),StandardCharsets.UTF_8);
    String utf32 = new String(b.getBytes(), "UTF_32");
    long start = System.nanoTime();
    for (int i = 0; i < utf8.length(); i++) {
    char c = utf8.charAt(i);
    System.out.printf("%s",c);
    }
    System.out.printf("%n");
    long end = System.nanoTime();
    System.out.println(end - start);

    start = System.nanoTime();
    for (int i = 0; i < utf32.length(); i++) {
    char c = utf32.charAt(i);
    System.out.printf("%s",c);
    }
    System.out.printf("%n");
    end = System.nanoTime();
    System.out.println(end - start);
    System.out.println("==========");
    }
    }
    }
    ```
    结果是这样的:
    ```
    《新能源汽车推广应用推荐车型目录》( 2021 年第 4 批)车型主要参数
    358397

    255780
    ==========
    《新能源汽车推广应用推荐车型目录》( 2021 年第 4 批)车型主要参数
    415140

    226139
    ==========
    ```
    maokabc
        18
    maokabc  
       2022-02-11 21:24:06 +08:00 via Android
    你测试 utf8 不用 byte 数组,utf32 不用 int 数组,用 String 干什么? String 固定的 utf16 没其他编码。
    ohwind
        19
    ohwind  
       2022-02-11 21:41:12 +08:00
    @txwd ../src/main/java 这是一般项目层级,可以修改的。
    到了 "com" 就是 java 的 package 层级。假如有一个类的路径是这样的: /src/main/java/com/xxx/Util.java
    那么 "/src/main/java" 就是项目路径, 它的类名是 "Util" ,包名就是 "com.xxx"。而 "com.xxx.Util" 称为这个类的全限定类名
    KomiSans
        20
    KomiSans  
       2022-02-11 22:12:46 +08:00
    @pxiphx891 这... 有什么太大差别么
    bequt
        21
    bequt  
       2022-02-11 22:41:21 +08:00
    已经开始学,rust 了
    EscYezi
        22
    EscYezi  
       2022-02-13 04:26:09 +08:00 via iPhone
    @txwd #2 src/main/java 是 maven 项目约定的源码位置,后面的 com/…是因为 java 包名通常是域名倒序,如 api.baidu.com 变成 com/baidu/api
    Bingchunmoli
        23
    Bingchunmoli  
       2022-02-13 12:34:12 +08:00
    @txwd 你看一看现在前端也是 src public 什么的,都是规范的事情,你可以用,但是约定大于配置,都用规范,易懂,好用
    chur
        24
    chur  
    OP
       2022-02-14 13:41:52 +08:00
    @maokabc 没太明白你的意思。String 如果没有显示指定字符集,默认是按系统默认字符集来的? java 内部存储字符使用的是 utf-16 编码,实际调用 getBytes 等方法时会有一个转码的过程
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2546 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 33ms UTC 06:27 PVG 14:27 LAX 22:27 JFK 01:27
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86