Java中的一些基础代码片段_5


=Start=

缘由:

在用Java编程的过程中不断用文章进行整理总结(常用功能的Java实现),争取早日能非常熟练的使用Java进行开发。

正文:

参考解答:
0.Java中字符串切分并填充JSONObject时的问题
package com.ixyzero.learn.utils;

import com.alibaba.fastjson.JSONObject;

public class DoSplitTest {
    public static void main(String[] args) {
        String raw = "2018-07-15 11:26:32.040 hostname  #TAGS#{ ip=}#TAGS# #MESSAGE#{\"data\":\"some data\",\"type\":\"app_1\",\"os\":\"Android\",\"version\":\"1.3.7\",\"time\":\"2018-07-15 11:26:31\"}#MESSAGE#";
        String ip = raw.substring(raw.indexOf("#TAGS#{")+11, raw.indexOf("}#TAGS#"));
        System.out.println("ip = '" + ip + "'");

        raw = "2018-07-14 11:27:25.103 hostname  #TAGS#{ uuid=22046941-958B-4D5C-6T83-XY3PO9UI ip=}#TAGS# #MESSAGE#{\"data\": \"some data\",\"type\": \"app_2\",\"os\": \"iOS\",\"dateTime\": \"2018-06-04 15:31:40\",\"version\": \"1.0.6\"}#MESSAGE#";
        ip = raw.substring(raw.indexOf("#TAGS#{")+8, raw.indexOf("}#TAGS#"));
        System.out.println("ip = '" + ip + "'");

        String tags = raw.substring(raw.indexOf("#TAGS#{")+8, raw.indexOf("}#TAGS#"));
        System.out.println("'" + tags + "'");

        JSONObject jsonObject = new JSONObject();
        for (String item: tags.split(" ")) {
            // System.out.println(item);
            String[] arr = item.split("=", 2);
            // for (int i=0; i<arr.length; i++) {
            //     System.out.println(i + ":\t'" + arr[i] + "'");
            // }
            // System.out.println(arr.length);
            // System.out.print(arr[0] + "\t'");
            // System.out.println(arr[1] + "'");
            // String value = arr[1].isEmpty() ? "xnull" : arr[1];
            // System.out.println(value);
            // jsonObject.put(arr[0], value);

            jsonObject.put(arr[0], arr[1]);

            // if (arr.length == 2) {
            //     try {
            //         jsonObject.put(arr[0], arr[1]);
            //     } catch (Exception e) {
            //         jsonObject.put(arr[0], "");
            //     }
            // }
        }
        System.out.println(jsonObject);
    }
}

 

1.在Java中使用CRC32进行校验
package com.ixyzero.learn.utils;

import com.google.common.primitives.Longs;

import java.util.Arrays;
import java.util.zip.CRC32;

public class DoCRC32 {
    private static CRC32 crc32;
    private static byte[] initBytes = new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

    public static void main(String[] args) {
        String inputStr = "hello-world";
        System.out.println("raw: " + inputStr);
        byte[] inputByte = inputStr.getBytes();
        System.out.println("byte array: " + Arrays.toString(inputByte));

        crc32 = new CRC32();
        crc32.update(inputByte);
        long crc32Result = crc32.getValue();
        System.out.println("crc32: " + crc32Result);

        byte[] bytes = Longs.toByteArray(crc32Result);
        System.out.println("crc32 size: " + bytes.length);
        System.out.println("byte array: " + Arrays.toString(bytes));

        System.out.println("initBytes: " + Arrays.toString(initBytes));
    }
}
2.在Java中如何将 long 转换成 byte[]
import com.google.common.primitives.Longs;

byte[] bytes = Longs.toByteArray(12345L);
3.在Java中如何快速对 byte[] 数组初始化
byte arr[] = new byte[] {0, 0, 0};
// 下面这样也行
Arrays.fill(arr, (byte)0);
4.在Java中如何截取/获取 byte[] 数组的一部分
// slice from index 5 to index 9
byte[] slice = Arrays.copyOfRange(myArray, 5, 10);
5.Java中 byte[] 数组的拷贝和复制
// Java 中 System.arraycopy 方法的参数列表
System.arraycopy(Object src,
				int srcPos,
			 	Object dest,
			 	int destPos,
			 	int length
)

/*
Java中System.arraycopy()和Arrays.copyOf()两者的区别在于:
arraycopy()需要目标数组,将原数组拷贝到你自己定义的数组里,而且可以选择拷贝的起点和长度以及放入新数组中的位置;
copyOf()是系统自动在内部新建一个数组,调用arraycopy()将original内容复制到copy中去,并且长度为newLength。返回copy; 即将原数组拷贝到一个长度为newLength的新数组中,并返回该数组。

总结:
Array.copyOf()可以看作是受限的System.arraycopy(),它主要是用来将原数组全部拷贝到一个新长度的数组,适用于数组扩容。
*/
6.Java中如何较为友好的打印 byte[] 数组
# 简单数组(各种类型都可以,比如 int/double/String/byte)
String[] array = new String[] {"John", "Mary", "Bob"};
System.out.println(Arrays.toString(array));

# 嵌套数组
String[][] deepArray = new String[][] {{"John", "Mary"}, {"Alice", "Bob"}};
System.out.println(Arrays.toString(deepArray));
// output: [[Ljava.lang.String;@106d69c, [Ljava.lang.String;@52e922]
System.out.println(Arrays.deepToString(deepArray));
// [[John, Mary], [Alice, Bob]]

 

参考链接:
  • 如上

=END=

,

《 “Java中的一些基础代码片段_5” 》 有 9 条评论

  1. 如果再有人问你分布式ID,这篇文章丢给他
    https://mp.weixin.qq.com/s/KfoLFClRwDXlcTDmhCEdaQ
    `
    1.背景
    在我们的业务需求中通常有需要一些唯一的ID,来记录我们某个数据的标识:
    · 某个用户的ID
    · 某个订单的单号
    · 某个信息的ID
    通常我们会调研各种各样的生成策略,根据不同的业务,采取最合适的策略,下面我会讨论一下各种策略/算法,以及他们的一些优劣点。

    2.UUID
    UUID的优点:
    通过本地生成,没有经过网络I/O,性能较快
    无序,无法预测他的生成顺序。(当然这个也是他的缺点之一)
    UUID的缺点:
    128位二进制一般转换成36位的16进制,太长了只能用String存储,空间占用较多。
    不能生成递增有序的数字

    3.数据库主键自增
    优点:
    简单方便,有序递增,方便排序和分页
    缺点:
    性能、可用性问题.

    4.Redis
    熟悉Redis的同学,应该知道在Redis中有两个命令Incr,IncrBy,因为Redis是单线程的所以能保证原子性。
    优点:
    性能比数据库好,能满足有序递增。
    缺点:
    由于redis是内存的KV数据库,即使有AOF和RDB,但是依然会存在数据丢失,有可能会造成ID重复。
    依赖于redis,redis要是不稳定,会影响ID生成。

    5.Zookeeper
    利用ZK的Znode数据版本如下面的代码,每次都不获取期望版本号也就是每次都会成功,那么每次都会返回最新的版本号。
    Zookeeper这个方案用得较少,严重依赖Zookeeper集群,并且性能不是很高,所以不予推荐。

    6.数据库分段+服务缓存ID
    这个方法在美团的Leaf中有介绍,详情可以参考美团技术团队的发布的技术文章:Leaf——美团点评分布式ID生成系统,这个方案是将数据库主键自增进行优化。
    优点:
    比主键递增性能高,能保证趋势递增。
    如果DB宕机,proxServer由于有缓存依然可以坚持一段时间。
    缺点:
    和主键递增一样,容易被人猜测。
    DB宕机,虽然能支撑一段时间但是仍然会造成系统不可用。

    适用场景:需要趋势递增,并且ID大小可控制的,可以使用这套方案。

    7.雪花算法-Snowflake
    `

  2. jvm的GC日志分析
    http://swcdxd.iteye.com/blog/1859858
    `
    JVM的GC日志的主要参数包括如下几个:

    -XX:+PrintGC 输出GC日志
    -XX:+PrintGCDetails 输出GC的详细日志
    -XX:+PrintGCTimeStamps 输出GC的时间戳(以基准时间的形式)
    -XX:+PrintGCDateStamps 输出GC的时间戳(以日期的形式,如 2013-05-04T21:53:59.234+0800)
    -XX:+PrintHeapAtGC 在进行GC的前后打印出堆的信息
    -Xloggc:../logs/gc.log 指定日志文件的输出路径
    `

    快速解读GC日志
    https://blog.csdn.net/renfufei/article/details/49230943

    JVM实用参数(八)GC日志
    http://ifeve.com/useful-jvm-flags-part-8-gc-logging/

    在运行时开启GC日志 #测试不成功
    http://www.importnew.com/15722.html

  3. java高分局之jstat命令使用
    https://blog.csdn.net/maosijunzi/article/details/46049117
    `
    jstat [-命令选项] [jvmid] [间隔时间(毫秒)] [查询次数]

    每 2 秒一次显示进程号为 4423 的java进程的GC情况:
    $ jstat -gcutil 4423 2000

    每 1 秒一次显示进程号为 4423 的java进程的GC情况,打印100次:
    $ jstat -gcutil 4423 1000 100
    S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
    1.09 0.00 3.28 37.50 97.02 94.36 10083 206.680 33 8.011 214.691
    1.09 0.00 14.97 37.50 97.02 94.36 10083 206.680 33 8.011 214.691
    1.09 0.00 27.94 37.50 97.02 94.36 10083 206.680 33 8.011 214.691
    1.09 0.00 40.30 37.50 97.02 94.36 10083 206.680 33 8.011 214.691

    S0: 幸存1区当前使用比例
    S1: 幸存2区当前使用比例
    E: 伊甸园区使用比例
    O: 老年代使用比例
    M: 元数据区使用比例
    CCS: 压缩使用比例
    YGC: 年轻代垃圾回收次数
    FGC: 老年代垃圾回收次数
    FGCT: 老年代垃圾回收消耗时间
    GCT: 垃圾回收消耗总时间

    YGC平均耗时(YGCT/YGC):
    (206.680 * 1000) / 10083 == 20.4979 ms

    FGC平均耗时(FGCT/FGC):
    (8.011 * 1000) / 33 == 242.758 ms
    `

  4. Major GC和Full GC的区别是什么?触发条件呢?
    https://www.zhihu.com/question/41922036

    Java命令学习系列(4):Jstat
    http://www.importnew.com/18202.html
    `
    $ java -version
    $ man java
    -Xms #设定初始Java堆大小
    -Xmx #设定最大Java堆大小
    # 在生产环境中,-Xms和-Xmx通常设置为相同的值。

    -Xmn #为堆中的年轻代(young generation)设定初始和最大内存的大小
    # 堆的年轻代区域用于新建对象。年轻代区域的垃圾收集(GC)频率会比其它区域的更高。如果年轻代的内存设置的太小,则会产生大量的 minorGC 。如果年轻代的内存设置的太大,则只会在 fullGC 时执行垃圾回收,可能会导致垃圾回收时间过长。Oracle 建议将年轻代区域的大小设置为总的堆内存大小的1/4到1/2之间。

    -Xss set java thread stack size
    `

  5. Java 中 String 和 byte[] 相互转换
    http://baimoz.me/1896/
    `
    // String 转 byte[]:
    String s = “some text here”;
    byte[] b = s.getBytes(StandardCharsets.UTF_8); // Java 7+ only

    // byte[] 转 String:
    byte[] b = {(byte) 99, (byte)97, (byte)116};
    String s = new String(b, StandardCharsets.US_ASCII);
    `
    https://stackoverflow.com/questions/18571223/how-to-convert-java-string-into-byte
    https://stackoverflow.com/questions/8654141/convert-byte-to-string-in-java
    https://www.journaldev.com/770/string-byte-array-java

  6. Java中如何读取文件的内容存成字符串?
    https://stackoverflow.com/questions/326390/how-do-i-create-a-java-string-from-the-contents-of-a-file
    `
    # 从文件中读取全部内容返回至字符串
    ## Java 11 and above
    String content = Files.readString(path, StandardCharsets.US_ASCII);

    ## Java 7~11
    static String readFile(String path, Charset encoding) throws IOException {
    byte[] encoded = Files.readAllBytes(Paths.get(path));
    return new String(encoded, encoding);
    }

    # 从文件中读取全部内容返回至字符串列表
    ## Java 7 and above
    List lines = Files.readAllLines(Paths.get(path), encoding);

    # 借助外部库,比如:Apache Commons IO
    import java.io.*;
    import java.nio.charset.*;
    import org.apache.commons.io.*;
    public String readFile(String filePath) throws IOException {
    File file = new File(filePath);
    return FileUtils.readFileToString(file, StandardCharsets.UTF_8);
    }
    `

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注