Java中一些小知识点

今天来总结一些平时不起眼的东西。For Java.


for循环进行遍历删除元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ArrayList<String> list = new ArrayList(Arrays.asList("a", "b", "c", "d"));
System.out.println("before :" + list);
// 在这个方法中有一个严重的错误。当一个元素被删除时,列表的大小缩小并且下标变化,
// 所以当你想要在一个循环中用下标删除多个元素的时候,它并不会正常的生效。
for (int i = 0; i < list.size(); i++) {
String s = list.get(i);
System.out.println("s :" + s);
if ("a".equals(s)) {
list.remove(s);
}
if ("b".equals(s)) {
list.remove(s);
}
}
System.out.println("after :" + list);

上述代码结果不尽人意:

1
2
3
4
5
before :[a, b, c, d]
s :a
s :c
s :d
after :[b, c, d]

这正是因为注释中说的那样,list.remove()操作完的时候list就已经改变了大小以及下标,故当”a”删除后list变成了["b","c","d"],然而下标变成了1,这时候取值就是变成了”c”,所以”b”这个元素就自然跳过了。
故我们在进行遍历删除list中元素时要使用Iterator迭代器来操作

变量声明

今天自己写了几行简单测试了下:

1.
1
2
3
4
5
6
7
8
9
System.out.println("----------------start------------------");
int num = 100000;
long start = System.currentTimeMillis();
for (int i = 0; i < 9999999; i++) {
num += 20000;
}
long end = System.currentTimeMillis();
System.out.println("时间差 >> :" + (end - start));

结果为:

1
2
----------------start------------------
时间差 >> :2
2.
1
2
3
4
5
6
7
8
9
System.out.println("----------------start------------------");
Integer num = 100000;
long start = System.currentTimeMillis();
for (int i = 0; i < 9999999; i++) {
num += 20000;
}
long end = System.currentTimeMillis();
System.out.println("时间差 >> :" + (end - start));

结果为:

1
2
----------------start------------------
时间差 >> :20

结果差了整10倍。想必数据一大自动拆装箱也挺累的吧。故之后变量要多次基本操作声明尽量不用包装类

String相关

  • intern()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    String str = "sss";
    String str1 = new String("sss");
    String str2 = str1;

    System.out.println("str2.intern() == str1 >>" + (str2.intern() == str1));
    System.out.println("str2.intern() == str3 >>" + (str2.intern() == str));
    System.out.println("str2.intern().equals(str1) >>" + str2.intern().equals(str1));
    System.out.println("str2 == str1 >>" + (str2 == str1));
    System.out.println("str2.equals(str1) >>" + str2.equals(str1));

    结果:

    1
    2
    3
    4
    5
    str2.intern() == str1 >>false
    str2.intern() == str3 >>true
    str2.intern().equals(str1) >>true
    str2 == str1 >>true
    str2.equals(str1) >>true

    我个人理解是,str2.intern()即是str1.intern()指向的故是常量池中的”sss”,常量池中的”sss”就是str,str1指向一个String对象,而equals比较大小就不说了。这里面说得就详细多了。

  • new String

    1
    2
    3
    4
    5
    6
    7
    char[] c = { '1', '2', '3', '4', '5', '6', '7', '8' };
    String strC = new String(c, 2, 3);
    System.out.println("strC >>" + strC);

    int[] arrInt = { 1, 2, 3, 4, 5, 6, 7, 8 };
    String strI = new String(arrInt, 2, 3);
    System.out.println("strI >>" + strI);

    结果:

    1
    2
    strC >>345
    strI >>

    从下标2位置(包含)开始截取,数量为3

  • join

    1
    2
    String joinS = String.join(":", "e", "r", "y");
    System.out.println("joinS >>" + joinS);

    结果:

    1
    joinS >>e:r:y

    我们走进join源码看一下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public static String join(CharSequence delimiter, CharSequence... elements) {
    Objects.requireNonNull(delimiter);
    Objects.requireNonNull(elements);
    // Number of elements not likely worth Arrays.stream overhead.
    StringJoiner joiner = new StringJoiner(delimiter);
    for (CharSequence cs: elements) {
    joiner.add(cs);
    }
    return joiner.toString();
    }

    发现了StringJoiner

  • StringJoiner

所以也可以这么用:

1
2
3
StringJoiner joiner = new StringJoiner(",");
joiner.add("a").add("b").add("c");
System.out.println(joiner.toString());

结果:

1
a,b,c

Today End.


Face++与Java简单应用(新)

开篇

  • 前段时间逛了下旷视官网,真是变化好大页面好漂亮现在,依稀记得最开始上的官网哪来这么炫酷
  • 然后就继续点进去看了下Face++API,果不其然参数变了不少,识别点越来越多了
  • 再接下来我又翻了翻自己很久前写的一篇博文,这不行了,这之前写的啥玩意,代码也找不到了,而且现在也不能用了,故,立了个flag

操刀

开始操刀了,还是一样我选择了SpringBoot,没什么,就是方便。这次选择用BootStrap框架。

  • 首先操刀之前,先去上面官网去注册用户,创建个应用,目的是为了获取它的api-key和api-secret
  • 现在不像之前那样复杂了,那时候还得下个jar包导入才能调它的方法,现在直接在线调用即可。具体代码如图位置:这样的话只需要把你需要识别的图片路径,你刚获取的api-key和api-secret替换就行了,然后你就可以得到一串json格式的字符串。太长我就不放了,主要信息就在faces中。我这里主要就是简单获取faces下面attributes中的一些参数。具体可直接看它官网的API,很详细的。
  • 图片上传我使用的是BootStrap-FileInput插件,这个插件确实很美观,刚开始使用的时候不太会,故研究了会。特别需要注意需要导入此插件的js和css,不然你就会有种想砸键盘的感觉了。

html:

1
2
3
4
<div class="modal-body" style="text-align: center;">  
<a href="" class="form-control" style="border:none;">上传照骗</a>
<input type="file" name="picFile" id="picFile" class="file-loading" />
</div>

js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
//参数1:控件id、参数2:上传地址  
init("picFile", "/sendPic");

//初始化fileinput控件(第一次初始化)
function init(ctrlName, uploadUrl) {
var control = $('#' + ctrlName);
//初始化上传控件的样式
control.fileinput({
language: 'zh', //设置语言
uploadUrl: uploadUrl, //上传的地址
allowedFileExtensions: ['jpg', 'png', 'jpeg'], //接收的文件后缀
showUpload: true, //是否显示上传按钮
showCaption: false, //是否显示标题
browseClass: "btn btn-primary", //按钮样式
dropZoneEnabled: false, //是否显示拖拽区域
//minImageWidth: 50, //图片的最小宽度
//minImageHeight: 50, //图片的最小高度
//maxImageWidth: 1000, //图片的最大宽度
//maxImageHeight: 1000, //图片的最大高度
maxFileSize: 2048, //单位为kb,如果为0表示不限制文件大小
//minFileCount: 0,
//maxFileCount: 10, //表示允许同时上传的最大文件个数
//enctype: 'multipart/form-data',
validateInitialCount:true,
previewFileIcon: "<i class='glyphicon glyphicon-king'></i>",
//msgFilesTooMany: "选择上传的文件数量({n}) 超过允许的最大数值{m}!",
uploadExtraData:function (previewId, index) { //传参
var data = {
//此处自定义传参
};
return data;
}
});

//导入文件上传完成之后的事件
$("#picFile").on("fileuploaded", function (event, data, previewId, index) {

});
}

文件上传成功后后台还需要接收它,如何接收?且听我慢慢道来:

1
2
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
List<MultipartFile> fileList = multipartRequest.getFiles(dstFileName);

这两句可以接收到对应页面上传的图片,List说明它可以一次上传多张。既然能接收到,那就什么都不是事了。接下来想怎么玩就怎么玩。

  • 在页面用到BootStrap模态框的时候我发现它不能拖拽,然后网上冲浪了一会,发现把jquery-ui导入就可以使用draggable()方法。可全局可单页面,我这里是全局设置。

    1
    2
    3
    4
    5
    6
    // 使模态框可拖拽		    
    $(document).on("show.bs.modal", ".modal", function(){
    $(this).draggable();
    $(this).css("overflow-y", "scroll");
    // 防止出现滚动条,出现的话,你会把滚动条一起拖着走的
    });
  • 前端知识还需要恶补啊,现在页面想做点炫酷的效果是一点办法没有,布局排版还丑的一批。还需努力啊!

Screenshots

  • Index

  • One Person Result

  • More than One Person Result


那一天,那一月,那一年

文章首发个人公众号:普度狗生

那一天,
我闭目在经殿的香雾中,
蓦然听见,
你诵经中的真言;

那一月,
我摇动所有的经筒,
不为超度,
只为触摸你的指尖;

那一年,
磕长头匍匐在山路,
不为觐见,
只为贴着你的温暖;

那一世,
转山转水转佛塔,
不为修来世,
只为途中与你相见;

那一夜,
我听了一宿梵唱,
不为参悟,
只为寻你的一丝气息;

那一月,
我转过所有经筒,
不为超度,
只为触摸你的指纹;

那一年,
我磕长头拥抱尘埃,
不为朝佛,
只为贴着你的温暖;

那一世,
我翻遍十万大山,
不为修来世,
只为路中能与你相遇;

那一瞬,
我飞升成仙,
不为长生,
只为佑你平安喜乐;

只是,
就在那一夜,
我忘却了所有,
抛却了信仰,
舍弃了轮回,
只为,
那曾在佛前哭泣的玫瑰,
早已失去旧日的光泽。


个人博客今日开启

说说为什么弄了这个博客呢

  • 首先最近比较闲 - - 不太忙应该这么说
  • 其次呢前几天终于下狠心买了个一年的云服务器(超低配,搞活动..),心想,我这资源不能浪费啊,怎么说也是好几张老毛啊

然后决定开搞那就搞,上网开始搜一些博客模板,之前了解过WordPress/Hexo,后来还是决定就Hexo了还能托管在GitHub上也方便。


于是乎就去找适合自己的主题了呗,一个猛子扎下去,我的乖宝贝,这些五花八门的主题还真是炫酷炸宇宙啊。可是,我喜欢简约的。


就在这时,melody出现在我眼前。还真是确认过眼神,你就是我想要的简约啊…
so,选定离手,开始操刀了。


前前后后也是弄了一天时间吧,因为之前没有弄过这些类似的静态博客还是一步步看其他兄弟的详细步骤操刀下来的。一路走下来,看自己的博客逐步搭好也是莫名舒坦。


部署到GitHub上/部署到云服务器上


博客搭是搭好了,可惜没有干货啊..( ▼-▼ )


Hello World

This is a Test Page …


## 这是hexo的一个测试