java高效组定长报文

定长报文简介

  系统与系统按约定格式进行信息交互的字符串,称为报文。通常的格式有定长字符串和XML字符串。这里主要介绍一下定长字符串。
  定长字符串,就是报文要素按固定顺序,固定长度组成一个报文字符串。这里的定长通常是指固定长度。固定的长度按字节计算。

定长字符串报文结构

  1. 定长字符串由报文要素组成,报文要素按位置表示具体的业务含义
  2. 报文要素包含3个内容:业务含义,固定长度(也是最大长度),要素值
  3. 对于要素值不够最大长度的情况,要填充指定字符以达到固定长度
  4. 对于包含中文的要素,要先指定信息交互的字符集,才能确定要素值的长度
    GBK : 一个中文算两个字节
    UTF-8 : 一个中文算3个字节

组定长报文的优化思路

  组定长报文的核心方法,我个人觉得是拼接填充字符串的方法。
常用方法是逐个拼接

  1. 逐个拼接,时间复杂度O(n)
	/**
	 * 右补空格
	 * @param padLen		填充长度
	 * @param fieldValue	要素值
	 * @return
	 */
	public static String paddingSpaces(int padLen, String fieldValue) {
		if(padLen <= 0){
			return fieldValue;
		}
		
		if (fieldValue == null){
			fieldValue = "";
		}
		
		StringBuilder fixedValue = new StringBuilder(fieldValue);
		while (padLen-- > 0) {
			fixedValue.append(" ");
		}
		return fixedValue.toString();
	}
  1. 扩展一下思路,为什么不可以2个2个拼呢,完成可以啊,时间复杂度O(n/2)
	/**
	 * 右补空格,一次补两个空格
	 * @param padLen		填充长度
	 * @param fieldValue	要素值
	 * @return
	 */
	public static String paddingTwoSpaces(int padLen, String fieldValue) {
		if(padLen <= 0){
			return fieldValue;
		}
		
		if (fieldValue == null){
			fieldValue = "";
		}
		
		StringBuilder fixedValue = new StringBuilder(fieldValue);
		
		//要把填充长度先做成整倍数。
		//这里是一次拼2个,做成偶数就可以了
		//一次拼多于两个,要先在这里处理成整倍数
		if (((padLen & 1) == 1)){
			//补空格数为奇数,先补一个空格,变成偶数
			fixedValue.append(" ");
			padLen--;
		}
		
		while (padLen > 0) {
			fixedValue.append("  ");//一次拼两个个空格
			padLen -= 2;
		}
		return fixedValue.toString();
	}

  这个方法效率直接提高一倍☺,当然还可以继续扩展,一次拼3个,拼4次,本质都是一样的思路。要注意的一点,就是要把填充长度先做成整倍数。

  1. 上面的方法效率虽然提高了不少,但是时间复杂度数量级还是O(n),能不能进一步提高呢?
      可以在系统启动时,先初始化一个Map,key是长度,value是对应长度的字符串。这样每次拼字符串时,先从Map中取,没有再拼接。通常初始化长度从1到20个这样的字符串,就足够使用,很少有报文要素需要补超过20个填充字符的
	//初始化1-20个字符串供使用,这个可以根据需要调整
	private static int cachedCount = 20;
	//长字符串缓存开关,填充长度超过 cachedCount 时使用
	private static boolean longSpaceCacheSwitch = false;
	//初始化Map
	private static Map<Integer, String> spaceCacheMap = new HashMap<Integer, String>();
	static {
		//初始化方法
		//也可以定义成一个静态方法,系统启动时调用,以完成初始化
		StringBuilder space = new StringBuilder(" ");
		
		//1到20个字符串(空格)
		for (int i = 1; i <= cachedCount; i++) {
			spaceCacheMap.put(i, space.toString());
			space.append(" ");
		}
		
	}

	/**
	 * 使用缓存字符串Map,完成拼接
	 * @param padLen		填充长度
	 * @param fieldValue	要素值
	 * @return
	 */
	public static String paddingSpacesByCache(int padLen, String fieldValue){
		if(padLen <= 0){
			return fieldValue;
		}
		
		if (fieldValue == null){
			fieldValue = "";
		}
		
		StringBuilder fixedValue = new StringBuilder(fieldValue);
		
		String tmpValue = spaceCacheMap.get(padLen);
		if(tmpValue != null){
			//长度小于cachedCount,spaceCacheMap可以直接获取到
			return fixedValue.append(tmpValue).toString();
		}
		//以下是填充长度大于cachedCount时的情况,
		//这种情况应该很少,取决于cachedCount的设定
		int tmpLen = padLen;
		String spaces = spaceCacheMap.get(cachedCount);
		do {
			//一次拼20(cachedCount)个,
			fixedValue.append(spaces);
			padLen -= cachedCount;
			
		} while (padLen >= cachedCount);
		
		if(padLen > 0){
			//填充长度不是cachedCount整倍数,要补上不足的部分
			fixedValue.append(spaceCacheMap.get(padLen));
		}
		if(longSpaceCacheSwitch){
			//缓存长文本字符串
			//长度超过 cachedCount 时,把它添加到 spaceCacheMap 中,供下次使用
			spaceCacheMap.put(tmpLen, fixedValue.toString());
		}
		return fixedValue.toString();
	}

  这个方法基本上可以达到O(1)的时间复杂度。

上面是我的一些优化思路,希望给能大家带来一点帮助,也欢迎各路大佬提出宝贵意见

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
Java生成定报文的方法有很多种,下面我会介绍其中两种比较常用的方法。 方法一:使用字符串的格式化方法 可以使用Java中的String.format()方法来生成定报文。我们可以先定义一个定字符串模版,然后根据需要填充数据的位置,使用占位符来指定每个位置上填充的数据格式和度。再通过String.format()方法将数据填充到模版中,生成定报文。 示例代码如下: ``` String template = "%-10s%-10s%-10s"; String data1 = "ABC"; String data2 = "123"; String data3 = "XYZ"; String message = String.format(template, data1, data2, data3); System.out.println("生成的定报文: " + message); ``` 上述代码中,我们定义了一个度为30的字符串模版,其中每个数据项占用10个字符的度。使用%10s指定每个数据项的度为10个字符,并使用-进行左对齐。然后我们分别为data1、data2和data3赋值,并使用String.format()方法将数据填充到模版中,生成了一个定为30的报文。 方法二:使用StringBuilder拼接字符串 另一种方法是使用StringBuilder来拼接字符串,从而生成定报文。我们可以先创建一个StringBuilder对象,然后使用append()方法将各个数据项拼接到一起,通过设置固定的度来保证报文的定。 示例代码如下: ``` StringBuilder sb = new StringBuilder(); sb.append("ABC"); sb.append("123"); sb.append("XYZ"); while (sb.length() < 30) { sb.append(" "); } String message = sb.toString().substring(0, 30); System.out.println("生成的定报文: " + message); ``` 上述代码中,我们使用StringBuilder对象来拼接数据项,并使用while循环来不断追加空格,直到字符串度达到30个字符,保证报文的定。最后使用substring()方法截取字符串的前30个字符作为最终的定报文。 通过以上两种方法,我们可以方便地生成定报文
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值