编写Java code时的Util方案

Java这种静态语言使用IDE写起来比较有安全感 ,看到各种提示错误即时修改即可。
有时过多的声明或原生提供的方法又让人感觉写起来有些繁杂。

由于懒以及个人对代码整洁程度的一点点洁癖,会寻找一些简易的方法来改善这些编码过程中的不爽,而这篇便用来记录这些解决常见问题的Util方案。
不止包括代码抽象层面,亦有IDE的使用技巧与一些辅助功能性类的介绍。

由于现在进度还没有越过第一章,随着项目的进行,此篇亦会持续更新。

打印

这个项目要做很多题,经常要使用打印来证明程序的正确性以及效果。
而Java的打印要使用System.out.println()方法,是我见过的语言中打印方法编写字数最长的一个,尽管JS的console.log()已经够恶心了。
可能还是我孤陋寡闻了吧。

解决方案很简单,写一个Print类,提供一个静态的print方法,在该方法中再调用Java原本的打印。
其他地方static import即可,而作为编写人员,Intellij更是使我不用编写该import语句,直接调用,然后ALT+ENTER快捷键即可,方便很多。

import java.io.PrintStream;

public class Print {

    // Print with a newline:
    public static void print(Object obj) {
        System.out.println(obj);
    }
    // Print a newline by itself:
    public static void print() {
        System.out.println();
    }
    // Print with no line break:
    public static void printnb(Object obj) {
        System.out.print(obj);
    }
    // The new Java SE5 printf() (from C):
    public static PrintStream
    printf(String format, Object... args) {
        return System.out.printf(format, args);
    }
}

该类的实现来自于Java编程思想 (第4版),而这种写Util类的思想,不仅在Java,在任何语言的编码中,应该都很常用。

记录时间运行时间

第一章的排序算法对时间是有要求的,10s以内即认为可行。
课后练习又有一些不同实现,以及它们的运行时间比较。
如何记录Java程序的运行时间呢?

我采用最简单的方法:

public class CheckSpaceAndTime {

    public static void main(String[] args) {
        long startAt = System.currentTimeMillis();
        // algorithm code here.
        long endAt = System.currentTimeMillis();
        print("Program cost time: " + (float)(endAt-startAt)/1000 + 's');
    }
}

使用System类调用currentTimeMillis()方法可得当前时间戳,单位为毫秒。
endAt与startAt相减可得结果,进行有意义地打印。

这依然不够优雅,每个要检查时间的方法,都要在它的开始和结束插入这几句,真的是一点都不clean。
而且每次都要将这几句代码复制来复制去,烦得不行。

我希望达到像Python的装饰器一样的效果,打印运行时间不会侵入到算法实现函数的运行。
比如这样:

@print_cost_time
def main():
    # code here
    return

Java是设计模式的“重灾区”,很Javanic的实现方法可能是装饰器模式,同时又在Java编程思想中看到了代理模式的一个实现,可能也可以处理这种情况。
具体实现等那本书消化好了再来改进。

目前采用一个折中的办法,使用Intellij的live template来自动生成一个带有这几行代码的main方法,至少可以省去复制的功夫。
在IDE的设置页面,搜索live template,点击右边的+号,会在user的命名空间下,增加一个live template。
此处缩写给maint,选择context为Java。
如图:


image.png

Apply以及OK后,在Java类中,输入maint按tab即可生成上面的代码。

检查对象占用的内存空间

网上查找了一些方法,大都不怎么好用,而且不够clean,用起来很不爽。
更有甚者,搞了好大一会儿终于跑起来后,发现它查到的只是该对象的引用所占用的空间而不是该对象在栈或堆上占用的空间。
曾一度以为Java并没有一个for human的对象内存查看工具包。

而,柳暗花明又一村,这一村是Apache的RamUsageEstimator包。
为使用它,强行将项目改成了maven管理。
pom.xml中导入:

  </dependencies>
    <dependency>
      <groupId>org.apache.lucene</groupId>
      <artifactId>lucene-core</artifactId>
      <version>4.2.0</version>
    </dependency>
  </dependencies>

然后开箱即用,正是我想要的东西:

public class CheckSpaceAndTime {

    public static void main(String[] args) {
        long startAt = System.currentTimeMillis();
        ArrayList<Integer> s = new ArrayList<>();
        for (int i=0; i<10000000; i++) {
            s.add(i);
        }
        int[] sss = new int[10000000];
        for (int i=0; i<10000000; i++) {
            sss[i] = i;
        }
        BitSet ss = new BitSet(10000000);
        print("ArrayList cost memory: " + RamUsageEstimator.sizeOf(s) + "bytes.");
        print("BitSet cost memory: " + RamUsageEstimator.sizeOf(ss) + "bytes.");
        print("List cost memory: " + RamUsageEstimator.sizeOf(sss) + "bytes.");
        long endAt = System.currentTimeMillis();
        print("Program cost time: " + (float)(endAt-startAt)/1000 + 's');
    }
}

运行结果为:


image.png

可以看到,不同的存储结构所占的内存差别真的是天差地别。
数组很明显,10^7个int,再加上引用本身,所占内存不到4M;
MyBitSet表现很好,只占用了1.25M;
ArrayList是最恐怖的,竟然占了205M,惊了!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,294评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,780评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,001评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,593评论 1 289
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,687评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,679评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,667评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,426评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,872评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,180评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,346评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,019评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,658评论 3 323
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,268评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,495评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,275评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,207评论 2 352

推荐阅读更多精彩内容