好人卡
短暂的周末过去了,周一李大明白和诸葛十三依旧是最早到公司的。
然后两个人进行了一段有趣的对话。
李:周末干啥啦
十三:看会儿书,看会儿小姐姐视频。
李:还挺充实,没有出去转转呀。
十三:没有,在家呆着多舒服。
李:哈哈,你说的没毛病。
十三:你呢,出去玩儿了吗
李:我去领了一张卡片。
十三:办银行卡啦?
李:没有,领了一张好人卡。
十三:哦啊,明白了。
李:还得是我十三哥呀,啥都明白。
十三:我可是卡片专家,看我抽屉,那么多卡片呢。
李:哈哈,你可别出去跟人说你有很多小卡片,容易误会。也就我知道你那是外卖卡片,别人可不这么认为。
十三:管别人怎么想呢,你要活成你自己的样子。
李:对,十三哥说的是。
李:十三哥,问你个问题。
十三:你说
李:你说,我的朋友、同事、家人,也给我介绍了好几个相亲对象了,为啥好些人都看不上我呢。
十三:子非鱼焉知鱼之乐,我又不是她们,我也搞不清楚。
李:你三体人,不懂我们人类,以后怎么统治我们? 没有梦想了吗
十三:害,那我就简单给你分析分析,仅供参考。
李:且说无妨。
十三:无非是钱、貌
钱:你以及你家人的房、车、薪资、工作是否稳定。
貌:是否干干净净,这句话的意思就是是否长得像肖战。
性格:性格这点你一定要注意了,不是说性格好就能找到对象,如过是这样的话,你也早就脱单了。
一般说性格好,是指你要认同她所认同的。比如她认为地铁看短视频外放是一件正确的事,这个时候你就不能说,地铁规定不能外放。看似你是正确的,其实在她看来,你就是多管闲事。
李:嗯。认同你的说法,但是不认同她们做法。
李:很滑稽。
十三:你们人类就这样,每个人都会活成自己讨厌的样子。平日里的道德一旦到了自己身上,那就是你多管闲事。
李:也是,有时候不能怪别人,也正是有了这些不同,才有了这丰富多彩的大千世界。
十三:是的,还是我们三体人好,不像你们,那么虚伪。
李:你可别说了,我们顶多是害人,你们是想直接害人类。
李:如果可以用程序来匹配两个人是否合适多好。
以下内容纯属虚构:
假设自己跟自己定义为匹配,也就是说你跟你是可以在一起的(除非精神分裂,否则这点儿已经是实时)
其次,一男一女,2人薪资相差30%以内,男士必须有房、有车,两人性格匹配度80%以上。就可以匹配到一起。
很好玩的代码
package test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author 木子的昼夜编程
*/
public class Find {
public static void main(String[] args) {
MyPerson p01 = new MyPerson();
p01.gender = '男';
p01.hashCar = true;
p01.hasHouse =true;
p01.salary = 10000;
p01.natures = Arrays.asList(MyPerson.N1,MyPerson.N3,MyPerson.N5,MyPerson.N7,MyPerson.N8);
MyPerson p02 = new MyPerson();
p02.gender = '男';
p02.hashCar = true;
p02.hasHouse =false;
p02.salary = 10000;
p02.natures = Arrays.asList(MyPerson.N1,MyPerson.N3,MyPerson.N5,MyPerson.N7,MyPerson.N8);
MyPerson p03 = new MyPerson();
p03.gender = '女';
p03.hashCar = false;
p03.hasHouse = true;
p03.salary = 10000;
p03.natures = Arrays.asList(MyPerson.N2,MyPerson.N4,MyPerson.N5,MyPerson.N7,MyPerson.N8);
MyPerson p04 = new MyPerson();
p04.gender = '女';
p04.hashCar = false;
p04.hasHouse = true;
p04.salary = 7800;
p04.natures = Arrays.asList(MyPerson.N3,MyPerson.N4,MyPerson.N5,MyPerson.N7,MyPerson.N8);
// 自己跟自己
System.out.println("1:"+ifMatch(p01, p01));
// 男-男
System.out.println("2:"+ifMatch(p01, p02));
// 性格 1,3,5,7,8 《-》 2,4,5,7,8
System.out.println("3:"+ifMatch(p01, p03));
// 可以匹配
System.out.println("4:"+ifMatch(p01, p04));
// 没房
System.out.println("5:"+ifMatch(p02, p03));
// 没房
System.out.println("6:"+ifMatch(p02, p04));
}
public static String ifMatch(MyPerson p1, MyPerson p2){
// 1. 自己跟自己
if (p1 == p2) {
return "自己跟自己匹配,单着一辈子吧";
}
// 2. 性别校验
if (p1.gender == p2.gender) {
return "性别有问题呀!";
}
// 3.计算薪资差值
double salary01 = p1.salary;
double salary02 = p2.salary;
// 3.1 计算差值
double diff = Math.abs(salary02 - salary01);
// 3.2 获取薪资小的值
double small = Math.min(salary01, salary02);
// 3.3 计算差值比例 不能超过0.3
double v = diff / small;
if (v > 0.3) {
return "薪资差多了,可能会有一方看不上另一方";
}
// 4. 看男生是否有房、有车
MyPerson boy = p1.gender == '男' ? p1 : p2;
if(!boy.hasHouse || !boy.hashCar) {
return "不管你没房还是没车,没一个都不行";
}
// 5. 性格匹配 必须超过80%
if (p1.natures == null || p1.natures.size() == 0
|| p2.natures == null || p2.natures.size() ==0 ) {
return "有一个人可能是个布娃娃,还是找个真人吧";
}
// 5.1 求交集 为了不影响之前对象属性 所以复制一份新的进行比较
List<String> list01 = new ArrayList<>(p1.natures);
List<String> list02 = new ArrayList<>(p2.natures);
list01.retainAll(list02);
// 5.2 计算比例 按照一般惯例我们需要使用Bigdecimal 这里就直接使用double了,不需要那么精确。
int count = list01.size();
double bl01 = Double.valueOf(count) / Double.valueOf(p1.natures.size());
double bl02 = Double.valueOf(count) / Double.valueOf(p2.natures.size());
if (bl01 < 0.8 || bl02 < 0.8) {
return "性格匹配度小于80%";
}
return "匹配值不错,可以试试";
}
}
class MyPerson{
// 定义几种性格
public static final String N1 = "孝顺";
public static final String N2 = "喜欢读书";
public static final String N3 = "喜欢运动";
public static final String N4 = "喜欢历史";
public static final String N5 = "喜欢哲学";
public static final String N6 = "认为公共场所抽烟是不文明行为";
public static final String N7 = "认为随地吐痰是不文明行为";
public static final String N8 = "认为地铁视频外放是不文明行为";
// 男女
char gender;
// 收入
double salary;
// 是否有房
boolean hasHouse;
// 是否有车
boolean hashCar;
// 性格
List<String> natures;
}
输出:
十三:你这还需要一个专门的方法ifMatch 来进行辨别,两个人是否合适。是不是可以直接写到equals方法中? 返回true就是合适 ,返回false就是不合适。
李:这样吗
package test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
/**
* @author 木子的昼夜编程
*/
public class Find02 {
public static void main(String[] args) {
MyPerson p01 = new MyPerson();
p01.gender = '男';
p01.hashCar = true;
p01.hasHouse =true;
p01.salary = 10000;
p01.natures = Arrays.asList(MyPerson.N1,MyPerson.N3,MyPerson.N5,MyPerson.N7,MyPerson.N8);
MyPerson p02 = new MyPerson();
p02.gender = '男';
p02.hashCar = true;
p02.hasHouse =false;
p02.salary = 10000;
p02.natures = Arrays.asList(MyPerson.N1,MyPerson.N3,MyPerson.N5,MyPerson.N7,MyPerson.N8);
MyPerson p03 = new MyPerson();
p03.gender = '女';
p03.hashCar = false;
p03.hasHouse = true;
p03.salary = 10000;
p03.natures = Arrays.asList(MyPerson.N2,MyPerson.N4,MyPerson.N5,MyPerson.N7,MyPerson.N8);
MyPerson p04 = new MyPerson();
p04.gender = '女';
p04.hashCar = false;
p04.hasHouse = true;
p04.salary = 7800;
p04.natures = Arrays.asList(MyPerson.N3,MyPerson.N4,MyPerson.N5,MyPerson.N7,MyPerson.N8);
// 自己跟自己
System.out.println("1:"+p01.equals(p01));
// 男-男
System.out.println("2:"+p01.equals(p02));
// 性格 1,3,5,7,8 《-》 2,4,5,7,8
System.out.println("3:"+p01.equals(p03));
// 可以匹配
System.out.println("4:"+p01.equals(p04));
// 没房
System.out.println("5:"+p02.equals(p03));
// 没房
System.out.println("6:"+p02.equals(p04));
}
}
class MyPerson{
// 定义几种性格
public static final String N1 = "孝顺";
public static final String N2 = "喜欢读书";
public static final String N3 = "喜欢运动";
public static final String N4 = "喜欢历史";
public static final String N5 = "喜欢哲学";
public static final String N6 = "认为公共场所抽烟是不文明行为";
public static final String N7 = "认为随地吐痰是不文明行为";
public static final String N8 = "认为地铁视频外放是不文明行为";
// 男女
char gender;
// 收入
double salary;
// 是否有房
boolean hasHouse;
// 是否有车
boolean hashCar;
// 性格
List<String> natures;
@Override
public boolean equals(Object o) {
MyPerson p2 = (MyPerson)o;
// 1. 自己跟自己
if (this == p2) {
return true;
}
// 2. 性别校验
if (this.gender == p2.gender) {
return false;
}
// 3.计算薪资差值
double salary01 = this.salary;
double salary02 = p2.salary;
// 3.1 计算差值
double diff = Math.abs(salary02 - salary01);
// 3.2 获取薪资小的值
double small = Math.min(salary01, salary02);
// 3.3 计算差值比例 不能超过0.3
double v = diff / small;
if (v > 0.3) {
return false;
}
// 4. 看男生是否有房、有车
MyPerson boy = this.gender == '男' ? this : p2;
if(!boy.hasHouse || !boy.hashCar) {
return false;
}
// 5. 性格匹配 必须超过80%
if (this.natures == null || this.natures.size() == 0
|| p2.natures == null || p2.natures.size() ==0 ) {
return false;
}
// 5.1 求交集 为了不影响之前对象属性 所以复制一份新的进行比较
List<String> list01 = new ArrayList<>(this.natures);
List<String> list02 = new ArrayList<>(p2.natures);
list01.retainAll(list02);
// 5.2 计算比例 按照一般惯例我们需要使用Bigdecimal 这里就直接使用double了,不需要那么精确。
int count = list01.size();
double bl01 = Double.valueOf(count) / Double.valueOf(this.natures.size());
double bl02 = Double.valueOf(count) / Double.valueOf(p2.natures.size());
if (bl01 < 0.8 || bl02 < 0.8) {
return false;
}
return true;
}
@Override
public int hashCode() {
return Objects.hash(gender, salary, hasHouse, hashCar, natures);
}
}
输出:
李: 哈哈 写代码真有意思。这不禁让我想起了一个面试题。
十三:肯定是“==”和“equals”的区别 ?
李:什么都逃不过我十三哥的钛合金眼呀。
十三:我怎么感觉你在骂人,但是我证据不足。你给说说这个面试题,我就不跟你计较了。
李:好的, 一般面试官问刚毕业的,考察一下他们基础知识学得怎么样,就会问“==”和“equals”的区别
一、“==”:
基础类型比较:基础类型比较的时候是拿他们的字面值进行比较的,相等就是true,不相等就位false
(基础类型:byte、short、int、long、float、double、char、boolean)比如我们说,年龄比较、身高比较、薪资比较等,一些基础数值的比较都可以用“==”来比较
引用类型比较:引用类型比较的是对象地址,我们都知道一个引用变量指向的是内存中的一个地址,如果地址相同就返回true,不相同就返回false.
比如:一般我们很少用“”来比较对象,除非我们有时候会排除自己,会用到 “”,更多地我们是用equals引用类型比较遇到过一次坑
下边输出是什么:
Integer i01 = 1; Integer i02 = 1; Integer i03 = 127; Integer i04 = 127; Integer i05 = 128; Integer i06 = 128; System.out.println(i01 == i02); System.out.println(i03 == i04); System.out.println(i05 == i06);
结果是:
强调一遍,包装类型,不要用“==”比较值是否相等,这里为什么前两个比较是true
这个是因为Integer的缓存机制
二、equals
2.1
equals最本质功能就是用的“==”
我们没有定义equals为什么可以直接使用这个方法
继承了他爹(Object)的衣钵
package test;
/**
* @author 木子的昼夜编程
*/
public class Eq02 {
public static void main(String[] args) {
T t01 = new T();
T t02 = new T();
System.out.println(t01.equals(t02));
}
static class T{
}
}
2.2
当然了,默认使用的是他爹的方法,但是大部分时候,我们都是有个性的,我们会自定义equals,比如:
我们看一下常用的String 的 equals方法,可以看到,先用“==”比较是否是同一个对象,然后再逐个比较字符是否都相等,但凡有一个不相等就返回false
package test;
/**
* @author 木子的昼夜编程
*/
public class Eq02 {
public static void main(String[] args) {
String s1 = new String("01");
String s2 = new String("02");
System.out.println(s1.equals(s2));
}
static class T{
}
}
2.3
至于经常说的,自定义equals,就是普通的方法覆盖,我们最上边已经写过了。
2.4
有些面试官,很无聊的会问,hashCode相等的字符串,是不是equals一定相等。
这时候你就回他三个字:有哈希碰撞的啦。
是的,不同字符串的哈希值是可能会相等的
那就有人问了,既然Hash会冲突,那我们要HashCode干什么,那我就要问你了,既然你赚钱少,你为啥还要赚钱呢?
Hash是会冲突,但是概率很小,而且我们可以确定的是如果两个值相等,那么它们的hash值一定相等。
我们可以先通过HashCode进行分类,然后再从分类里边进行业务操作。分析过HashMap的put操作源码的人应该深有体会。
之前看到过有人写了这样一段话:
java集合中有两类,一类是List,一类是Set。前者有序可重复,后者无序不重复。当我们在set中插入元素的时候,可以通过equals来判断元素是否存在,但是如果元素过多,这个方法会比较慢。
于是有人发明了哈希算法来提高集合查找元素的效率(讲实话,我不知道是不是为了这个发明的哈希算法,但是这个哈希算法确实为类似的功能提升了不少性能)。这种方式将集合分成若干个存储区域,对每个对象可以计算出一个哈希码,可以将哈希码分组,每组分别对应某个存储区域,根据一个对象的哈希吗就可以确定该对象存储在哪个区域。
hashCode方法可以这样理解:它返回的就是根据对象内存地址换算出来的一个值,这样一来,当集合需要添加新元素时,先调用这个元素的hashCode方法,就一下子能定位到它应该放置的物理位置,如果这个位置没有元素,我们就直接放上去,如果有元素了,我们再用equals进行比较,这样就大大降低了equals的使用频次。
这段话很拗口,但是你可以读三遍,不理解没关系。等你有一天明白他的用处的时候,你就会恍然大悟。
还记得小时候计算4+5的时候,摆着手指,怎么也算不对,但是现在4+5 是不是很简单,如果没有小时候的不懂,就没有现在的懂。
所以不懂不可怕,可怕的是你不懂还不学。