泛型、Set、TreeSet、自然排序Comparable、比较排序Comparator、HashSet

为什么Comparator接口有两个抽象方法compare和equals,却可以用Lambdahttp://t.csdn.cn/ktsoVJava中,接口是否继承自Object?http://t.csdn.cn/wMwyo为什么TreeSet<>(lambda)一定要加<>(java默认加上的,可以简写),但此处在编写lambda时不加<>编译报错,加了编译正常,运行也正常,这是什么原因?

一个包里不能有S和s两个文件名存在?

同一个文件夹下,不能存在s和S两个类名吗?报错:
6d837f43568c4105aa69dcfc8ee7284e.png
这是用匿名内部类报错

-------以后名称不要有大小写,例如一个包下的两个文件夹名,一个为S一个为s,会导致运行报错

此处要注意,异常和报错不一样,异常是Exception、报错是报出错误Error

这是正常的接口-实现类-实现类对象-调方法报错
Exception in thread "main" java.lang.NoClassDefFoundError: package3/s (wrong name: package3/S)

java.lang.NoClassDefFoundError异常缘由及解决办法http://t.csdn.cn/4UysWClassNotFoundException和NoClassDefFoundError区别是什么?

NoClassDefFoundError:简单理解是一个方法在运行的过程中,在调用另外一个类时,无法找到对应的类

泛型:<>

是jdk5中引入的特性,它提供了编译时类型安全检测机制

好处:

1.把运行时期的问题提前到了编译时期

2.避免了强制类型转换(减少代码量)

Set:

构造:Set<String> = new TreeSet();

特点:

1.可去除重复元素

2.存取顺序不一致(因为存取顺序不一致,所以重复元素只会出现一个,没有前后顺序区别)

3.没有带索引的方法,所以不能用普通for循环遍历,也不能通过索引来获取、删除Set集合里面的元素

TreeSet:

特点:

1.不包含重复元素

2.没有带索引的方法

3.必须将元素按规则进行排序

注意区分四个:

、compareTo、compare、、

自然排序:Comparable<>

Comparable<>为接口

在自定义类中实现,且注意要在泛型中加入自定义类!

接口内只有一个抽象方法:(在自定义类中重写)

compareTo()

注意:此处的compareTo()和String里的不一样,一个是接口调用的一个是String调用的,作用不一样。

new TreeSet();空参使用

比较器排序:Comparator<>

Comparable<>为接口

在TreeSet的带参中实现接口,

可以用匿名内部类也可用lambda

但注意:

重写方法是compare(),不是compareTo(),但在string中还是用compareTo(),一定要注意区分。

匿名内部类必须在Caomparator<>泛型中加入集合类型

lambda必须在等式右边TreeSet手动加上<>符号

Comparable<>自然排序的使用:(只能空参使用)

1.使用空参构造创建TreeSet集合

2.自定义Student类要实现Comparable<>接口(注意:Comparable<Student>泛型要和定义类保持一致)

3.重写里面的compareTo方法(注意:返回的是int值)

自然排序的简单原理:(后续数据结构会再讲)

1.返回值为负数,较小值存左边

2.返回值为0,重复元素,不存

3.返回值为正数,存右边

@Override

public int compareTo(Student o){

int result = this.age - o.age;-----this.age为准备存入的元素(会对每一个已存的元素进行对比)o.age为已存的元素

result = result == 0 ? this.getName.compareTo(o.getName) :result;

----this.getName.compareTo(o.getName),注意此处是String(this.getName返回来的是String)调用compareTo()方法,而不是重写自然排序的方法

"a".compareTo("b") → a - b 负数存左边,0继续比对,正数存右边,全部都为0不存

但需要把名字改成英文才能对比,先比较第一个字母,如果一样会继续比较后面的字母(Ascall码表)中文怎么办?

return result;

}

Comparator比较器排序:(只能在带参中使用)

1.TreeSet带参构造是使用比较器排序

2.比较器排序,就是让集合构造方法接收Comparator的实现类对象重写compare(T o1, T o2)方法

3.重写方法一定要按照主次顺序写

匿名内部类重写:(自定义类)

TreeSet<Teacher> s = new TreeSet(new Comparator<Teacher>(){

@Override

public int compare(Teacher o1 , Teacher o2){

int result = o1.getAge() - o2.getAge();

result = result == 0 ? o1.getName().compareTo(o2.getName()) : result;

return result;

}

});

匿名内部类重写:(String类)

TreeSet<String> s = new TreeSet(new Comparator<String>(){---注意此处必须写String

@Override

public int compare(String o1 , String o2){----否则参数类型全都是Object类

int result = o1.length() - o2.length();

result = result == 0 ? o1.compareTo(o2) : result;

return result;

}

});

注意:String是java已写好的代码(可进源码查看),不能人为修改重写代码,所以只能用比较器

比较器也可用lambda重写

但TreeSet必须加上泛型符,否则编译报错

TreeSet<String> s = new TreeSet<>( (o1,o2) -> {

int result = o1.length() - o2.length();

result = result == 0 ? o1.compareTo(o2) : result;

return result;

});

看完数据结构再看hashSet

HashSet集合:

特点;

1.底层数据结构是哈希表

2.不能保证存取顺序完全一致

3.没有带索引的方法,所以不能使用普通for循环遍历

4.由于是Set集合,所以元素唯一

哈希值(哈希码值:hashCode):是JDK根据对象的地址值或属性值算出来的int类型的整数

Object类中有一个方法获取对象的哈希值:

public int hashCode()根据对象的地址值计算出来的哈希值

同一个对象哈希值一样,因为地址值一样

不同对象哈希值不一样,也因为地址值不一样

hashCode()重写后:一般是通过对象的属性值计算出哈希值

如果不同对象的属性值一样,那么计算出来的哈希值也是一样的

HashCode是计算出哈希值,从而存入数组

注意:没有重写的HashCode是根据对象的地址值计算出来的哈希值,重写的HashCode是根据对象的属性值计算出来的哈希值

equals是当存入的数组索引中已存在对象,则会对比键是否一致

只需要记住HashCode可以通过对象的地址值或属性值计算出来int哈希值(索引),是用来存入数组的,但equals是用来对比链表或红黑树的属性值是否一致的

linked和tree有什么区别?

哈希表:

JDK8之前,底层采用 数组 + 链表 实现

JDK8之后,底层进行优化,由 数组 + 链表 + 红黑树 实现

JDK1.7版本的原理总结:

1.底层结构:哈希表(数组 + 链表)(为什么使用数组而不用集合?)

HashMap底层为什么一定用数组http://t.csdn.cn/RqmEdArrayList底层也是数组,但是扩容机制是1.5倍扩容

2.数组长度默认为16(数组名称:table),加载因子为0.75(当数组存满12(即:16*0.75=12),会自动扩容两倍(即:16*2=32))

加载因子:当条件达到则翻倍

3.首先会先获取元素的哈希值(返回的是整数),计算出在数组中应存入的索引(因为底层结构有数组)

存入前先判断该索引是否为null

为null,直接添加

不为null,则与链表所有元素,通过equals方法比较属性值,每个比较后,只要有一个相同,不存,都不一样,则存在链表的第一个

JDK1.8版本的原理总结:

当链表=8时,自动转为红黑树

HashSet解决封装对象的属性值一样的问题:

Set集合,元素不能一样,

若自定义类Student未重写HashCode()和equals(),则默认是按照Object的Hashcode()比较地址值,两个都是new的,地址值不一样,所以会存入集合

Student s1 = new Student("zhang",15);

Student s2 = new Student("zhang",15);

若重写了自定义类Student未重写HashCode()和equals(),则会按照对象的属性值对比,一样则不存,不一样则存入

708d8c120b6f429085300572f01ac6c9.png

 注意:

Set的子类都有同样的属性:无序、无索引、元素不可重复

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值