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

2022-02-11 14:58:14 +08:00
 chur

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 - start);

    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 对象是同一段一亿个字符的文本

3430 次点击
所在节点    Java
24 条回复
Kasumi20
2022-02-11 15:28:47 +08:00
你的 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
2022-02-11 16:10:00 +08:00
借楼问,为什么 Java 的工程目录要那么多层级...\src\main\java\com\...
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
2022-02-11 16:27:01 +08:00
还学 java ?这都卷成什么样了
chur
2022-02-11 16:36:27 +08:00
@Kasumi20 貌似是可以的?对同一个字符的 byte 数组使用 new String 指定 utf-8 或 utf-32 字符集重新编码会得到不同的结果
chur
2022-02-11 16:37:59 +08:00
@KomiSans 对,现在疑惑的点在于 这段代码放到 for 循环中 输出的结果很离谱= =
chur
2022-02-11 16:48:04 +08:00
@txwd src/main/java 貌似是 maven 编译项目时默认的路径,可以修改; com 和后面的就是自定义的了
VeryZero
2022-02-11 16:49:15 +08:00
感觉是被优化了,把各种优化关了试试
xiangyuecn
2022-02-11 16:50:12 +08:00
@txwd #2 java 没有要求你这样搞,但开发环境要求你这样搞😂 其实你源码随便放哪里都行,只要编译时找得到😂
xiangyuecn
2022-02-11 16:53:21 +08:00
欢迎观摩我手撸的 java 仓库,https://github.com/xiangyuecn/RSA-java 源码文件全丢在根目录,但包名还是那个包名🐶
gadfly3173
2022-02-11 17:03:34 +08:00
@txwd #2 这玩意算是工程实践,src 下 main 放项目源码,test 放单元测试; main 下 java 放包名路径,resource 下放要打包进去的资源。你乐意的话把打包配置改了也能放别的地方
Jooooooooo
2022-02-11 17:17:13 +08:00
搜 jit
Kasumi20
2022-02-11 17:25:18 +08:00
charset 不是指定 String 的编码,而是指定 bytes 的解码方法,你用 UTF-32 去解码,得到的乱码字符数量很可能只是 UTF-8 的四分之一
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
2022-02-11 17:35:10 +08:00
@txwd
可能因为 Java 语言的设计初衷就不是用来写单文件的迷你 script 的。于是人们在 applet 之外发明了 javascript 。
讽刺的是 javascript 屠了 applet 的龙。
pxiphx891
2022-02-11 18:10:03 +08:00
@chur @KomiSans 你们 getBytes()的时候,得到的是默认编码的 bytes ,一般是 utf8 ,utf8 的 bytes 转换到 utf32 ,length 会变短
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
2022-02-11 21:24:06 +08:00
你测试 utf8 不用 byte 数组,utf32 不用 int 数组,用 String 干什么? String 固定的 utf16 没其他编码。
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
2022-02-11 22:12:46 +08:00
@pxiphx891 这... 有什么太大差别么

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/833213

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX