intern()查询结果的字符串

时间:2014-12-30 12:37:42

标签: java string performance jpa

我需要实习查询结果的字符串。 因为我的查询第一个字段总是包含" 0"或" 1",每次创建新的String对象。 我想在这个字符串上使用intern()并使用池来保存一些内存。 enter image description here 但我的陈述回复了一个数字:

SELECT CASE WHEN b.num >= 12 THEN 1 ELSE 0 END as "result", 
        ROUND (((b.num - 12)/12),2) AS "weight" FROM (SELECT sum(t.amount_inst) AS num 
    FROM MRCH_CARD t 
    ....

所以它在java方面的结果是BigDecimal,而不是String: enter image description here

但是BigDecimal内部存在带有String值的stringCache字段,并且每当我将该查询作为exection的结果调用时,它就会使用" 1"来创建新的String对象。或" 0"值。 我如何将intern()值赋予字符串池? 我试过这种方式,但我认为这没有用,因为qr.getSingleResult()已经创建了新的String对象作为BigDecimal的stringCache字段:

  Object[] tempResult = (Object [])qr.getSingleResult();
  result.setResult(new BigDecimal(tempResult[0].toString().intern()));
  result.setWeight(new BigDecimal(tempResult[1].toString().intern()));

2 个答案:

答案 0 :(得分:0)

1)您可以修改SQL查询以返回字符串而不是整数

2)您可以缓存(“手动实习”)BigDecimal对象本身 - 将它们替换为BigDecimal.ONE和BigDecimal.ZERO静态缓存值

3)只有在BigDecinal对象上调用toString()时才会计算BigDecinal中的私有字段stringCache - 但如果需要toString(),则可能会丢弃BigDecinal对象

4)(不推荐!)你甚至可以在带有反射的私人字符串上打电话给实习生,见How do I read a private field in Java?

答案 1 :(得分:0)

更好的解决方案是使用第一列的数字(int)。这应该有效:

 BigDecimal result = resultAsBigDecimal( (Number)tempResult[0] );

 public static BigDecimal resultAsBigDecimal( Number value ) {
     int i = value.intValue();
     if( 0 == i ) return BigDecimal.ZERO;
     if( 1 == i ) return BigDecimal.ONE;
     throw new RuntimException( "Unexpected value: " + value );
 }

intern()对于体重来说可能毫无用处。因为重量会有很多不同的值。