中文描述是 Maven 增强插件,主要功能是编译的时候对一些"规则"进行检测,命中就会拦截抛错。当然排除依赖还是依赖 mvn dependency:tree -Dverbose 定位到去哪里排除。
看起来是给自己添麻烦,其实是一个管理整个 project 质量的很好工具,特别是在引入二方包的时候。
基本用法
如代码,展示了
- 禁用插件
- 指定maven最低版本
- 指定java最低版本
- 指定操作系统
中文描述是 Maven 增强插件,主要功能是编译的时候对一些"规则"进行检测,命中就会拦截抛错。当然排除依赖还是依赖 mvn dependency:tree -Dverbose 定位到去哪里排除。
看起来是给自己添麻烦,其实是一个管理整个 project 质量的很好工具,特别是在引入二方包的时候。
如代码,展示了
继上一篇文章讲述JAVA同步模型,如没有看过可以先看上一篇。
JAVA中使用锁确是非常的频繁,与此同时,JAVA还提供了多种方式进行同步互斥和协作。
总的来说,JAVA中锁分为两种:
监视器是由Per Brich Hansen和Tony Hoare提出的概念,Java以不精确的方式采用了它,也就是Java中的每个对象有一个内部的锁和内部条件。如果一个方法用synchronized关键字声明,那么,它表现的就像一个监视器方法。通过wait/notifyAll/nofify来访问条件变量。
Java 字符串的使用以及特性就不再多说了,本次主要讲String.intern()方法。
Java中String类型是加上final修饰符的(常量类),一般存放于常量池中。但是相同的字符串对象却不一定相等的,Java会把编译期已确定的字符串存入常量池,但是对于运行时产生的字符串JAVA并不会再主动放入常量池。
String str = "abc"; // 会存放进常量池
String str = new String("abc"); // 不会主动存进常量池
本文适合有过Servlet编程经验的半小白观看~~
Servlet 全称是Java Server Applet。从命名来看就知道名字起名来自于Java Applet(曾经也不没有风靡一时的java 小应用程序,主要应用于嵌入HTML),那么Servlet 顾名思义就是应用于服务器端的程序(小服务程序)了。
Servlet 的含义比较多,一句话概括的话我倾向于理解为——Servlet 是Java语言的一套接口和标准。他是目前最主流的实现动态页面的技术之一,开发者可以由此编写java web 服务端应用。而且截止目前,Java 服务端生态圈已经发展处众多的应用框架,如Spring MVC、Struts2…… 尽管已经有众多框架可以让开发者免于手动编写Servlet开发程序,但是对于初学者来讲,学习并使用Servlet开发一次Web项目是非常有必要的。
用node.js爬虫爬了不少图片之后,尽管经过了简单的处理,但是图片重复率还是很高。
本来打算用node继续写一个去重脚本,可是node处理图片的API文档不太足,也不是太简单,自己也不会用,还是回到了java写一个class一下吧。
对于图片来说,暴力hash算法是不可取的,因为只要有一个小像素点的改变,就导致不一样的hash。
网上查验得知可以用DHash算法,一种相对Hash值的算法进行检验去重。于是参照一篇别人的python计算DHash值的代码。
写了一个批量去重的java文件
package util;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.List;
import java.util.stream.Collectors;
/**
* DHash 算法对图片去重
*
* @author a9043
*/
public class DHashUtil {
/**
* 计算dHash方法
*
* @param file 文件
* @return hash
*/
private static long getDHash(File file) {
//读取文件
BufferedImage srcImage;
try {
srcImage = ImageIO.read(file);
} catch (IOException e) {
e.printStackTrace();
return -1;
}
//文件转成9*8像素,为算法比较通用的长宽
BufferedImage buffImg = new BufferedImage(9, 8, BufferedImage.TYPE_INT_RGB);
buffImg.getGraphics().drawImage(
srcImage.getScaledInstance(9, 8, Image.SCALE_SMOOTH), 0,
0, null);
//图片灰度化,灰度和加亮算法是网上找的,本人不懂图像
int width = buffImg.getWidth();
int height = buffImg.getHeight();
int[] grayPix = new int[width * height];
int i = 0;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int rgb = buffImg.getRGB(x, y);
int r = rgb >> 16 & 0xff;
int g = rgb >> 8 & 0xff;
int b = rgb & 0xff;
int gray = (r * 30 + g * 59 + b * 11) / 100;
grayPix[i++] = gray;
}
}
//开始计算dHash 总共有9*8像素 每行相对有8个差异值 总共有 8*8=64 个
long figure = 0;
for (i = 0; i < 63; i++) {
long bit = grayPix[i] > grayPix[i + 1] ? 1 : 0;
figure |= bit << i;
}
return figure;
}
/**
* 计算海明距离, 计网接触过的
* <p>
* 原本用于编码的检错和纠错的一个算法
* 现在拿来计算相似度,如果差异值小于一定阈值则相似
*
* @param x hash
* @param y hash
* @return 距离
*/
private static long getHammingDistance(long x, long y) {
int cnt = 0;
x = x ^ y;
while (x != 0) {
if (1 == (x & 0x01)) {
cnt++;
}
x = x >> 1;
}
return cnt;
}
/**
* 去重函数
*
* @param files 文件列表
*/
private static void doDistinct(File[] files) {
//以File作Key, hash作val 新建一个map
Map<File, Long> hashMap = Arrays
.stream(files)
.parallel()
.collect(Collectors.toMap(File::getAbsoluteFile, DHashUtil::getDHash));
//有效的hashList
List<Long> hashList = new ArrayList<>();
//去重循环
for (Iterator<Map.Entry<File, Long>> it = hashMap.entrySet().iterator(); it.hasNext(); ) {
Map.Entry<File, Long> entry = it.next();
//如果判定为重复,则移除map且删除
if (entry.getValue() != -1 && hashList.parallelStream().anyMatch(hash -> getHammingDistance(entry.getValue(), hash) < 10)) {
it.remove();
entry.getKey().deleteOnExit();
return;
}
//不重复/第一次 直接加入hashList
hashList.add(entry.getValue());
}
}
//DHashUtil 参数值为待处理文件夹
public static void main(String[] args) {
File file = new File(args[0]);
if (file.isDirectory()) {
doDistinct(file.listFiles());
}
}
}
我们先声明一个类
class Apple {
private int id;
private double weight;
private boolean maturity;
public Apple(int id, double weight, boolean maturity) {
this.id = id;
this.weight = weight;
this.maturity = maturity;
}
public int getId() {
return id;
}
public Apple setId(int id) {
this.id = id;
return this;
}
public double getWeight() {
return weight;
}
public Apple setWeight(double weight) {
this.weight = weight;
return this;
}
public boolean isMaturity() {
return maturity;
}
public Apple setMaturity(boolean maturity) {
this.maturity = maturity;
return this;
}
}
本次主要介绍以下内容
空引用和NullPointerException估计是java最讨人厌的地方了。还没学习JDK8新特性的时候IntelliJ IDEA IDE 的代码优化已经让我初步接触了Optional类,比如以下三目运算符
// 三目运算符判null
obj == null ? "default" : obj.getString();
// Optional判null
Optional.ofNullalble(obj.getString()).orElse("default");