什么是Set集合
set存储的元素是无序的,存入和取出的顺序不一定一致,并且set不可以存入重复的元素(不能存放重复元素:字符串、八大基本数据类型)
下面代码
public class SetDemo {
public static void main(String[] args) {
// List list=new ArrayList<>();
Set set=new HashSet<>();
set.add(new Person("zhang", 10, 1500));
set.add(new Person("zhang", 12, 1234));
set.add(new Person("liang", 12, 1400));
set.add(new Person("zhen", 13, 1900));
set.add(new Person("li", 12, 1500));
System.out.println(set.size());
Iterator it=set.iterator();//迭代器遍历
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
最后输出结果证明了不能存放重复的元素
2.怎么样证明Set是无序的。举下面的一个句子
public static void main(String[] args) {
// List list=new ArrayList<>();
Set set=new HashSet<>();
set.add(new Person("zhang", 19, 1200));
set.add(new Person("zhang", 19, 1205));
set.add(new Person("li", 22, 1900));
set.add(new Person("hei", 90, 9000));
set.add(new Person("nan", 23, 1230));
System.out.println(set.size());
Iterator it=set.iterator();//迭代器遍历
while(it.hasNext()) {
System.out.println(it.next());
}
}
class Person{
private String name;
private int age;
private int money;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", money=" + money + "]";
}
public Person(String name, int age, int money) {
super();
this.name = name;
this.age = age;
this.money = money;
}
public Person() {
}
}
最后结果为5,
字符串和8大基本数据类型
![在这里插入图片描述]
(h
ttps://img-blog.csdnimg.cn/20190705183810193.png)
- HashSet哈希表存储,重复元素储存底层探究
*list.contains 底层调用了equals方法
*set.add 底层调用了hashCode和equals方法
看下面代码
Set set=new HashSet<>();
set.add(new Person("zhang", 19, 1200));
set.add(new Person("zhang", 19, 1205));
set.add(new Person("li", 22, 1900));
set.add(new Person("hei", 90, 9000));
set.add(new Person("nan", 23, 1230));
System.out.println(set.size());
Iterator it=set.iterator();//迭代器遍历
while(it.hasNext()) {
System.out.println(it.next());
}
看下面图片
验证*set.add 底层调用了hashCode和equals方法
如下代码
public int hashCode() {
System.out.println("hashCode------");
// TODO Auto-generated method stub
return super.hashCode();
}
@Override
public boolean equals(Object obj) {
System.out.println("equals--------");
return super.equals(obj);
}
然后在
运行代码,看下面图
上面这个代码为什么只返回了hashCode因为你返回的值都不一样,不相信我们打印一下
public int hashCode() {
System.out.println("hashCode------");
int code=super.hashCode();
System.out.println(code);
return super.hashCode();
}
最
后输
出代码
二、集合框架TreeSet(自然排序、数据结构二叉树、比较器排序)
2.1 TreeSet自然排序
看下面代码
public static void main(String[] args) {
TreeSet<Object> set=new TreeSet<>();
set.add(new Person("zhang", 19, 1200));
set.add(new Person("zhang", 19, 1205));
set.add(new Person("li", 22, 1900));
set.add(new Person("hei", 90, 9000));
set.add(new Person("nan", 23, 1230));
System.out.println(set);
}
}
class Person{
private String name;
private int age;
private int money;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", money=" + money + "]";
}
public Person(String name, int age, int money) {
super();
this.name = name;
this.age = age;
this.money = money;
}
public Person() {
}
@Override
public int hashCode() {
System.out.println("hashCode------"+this.name);
int code=this.name.hashCode()+this.age;
System.out.println(code);
return code;
}
@Override
public boolean equals(Object obj) {
Person p=(Person) obj;
return this.name.equals(p.name) && this.age==p.age;
}
把前面的代码考过来。会报错内转换异常
![在这里插入图片描述](https://img-blog.csdnim
g.cn/20190705201202313.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTM1NTM0Mw==,size_16,color_FFFFFF,t_70)
如何实现Comparable接口:如下代码
class Person implements Comparable<Person>{
private String name;
private int age;
private int money;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", money=" + money + "]";
}
public Person(String name, int age, int money) {
super();
this.name = name;
this.age = age;
this.money = money;
}
public Person() {
}
@Override
public int hashCode() {
System.out.println("hashCode------"+this.name);
int code=this.name.hashCode()+this.age;
System.out.println(code);
return code;
}
@Override
public boolean equals(Object obj) {
Person p=(Person) obj;
return this.name.equals(p.name) && this.age==p.age;
}
@Override
public int compareTo(Person o) {
return this.age-o.age;
}
没有加implements Comparable<Person>这样会报错,当实现了Comparable接
口后就不会报错了:
如下代码
注意:在做自然排序方法重写的时候,一定先判断主要条件、还要判断次要条件
2.2、TreeSet数据结构(二叉树)
可以对set集合进行排序,底层数据结构是二叉树;
保证元素唯一性的就是compareTo方法return 0
注意:TreeSet排序的第一种方式,让元素自身具有比较性;
元素需要实现Comparable接口,覆盖compareTo方法;
这种方式也被称为元素的自然顺序,或者叫做默认顺序。
三、泛型
好处/为什么出现?
①不使用泛型的情况下,会将未知的错误表现在运行时期:
错误示例:
public class FanXinDemo {
public static void main(String[] args) {
List c=new ArrayList();
c.add(22);
c.add(23);
c.add(24);
c.add(25);
c.add(28);
c.add("这个是错误");
Iterator it=c.iterator();
while(it.hasNext()) {
// System.out.println(it.next());
int num=(int) it.next();
if(num%2==0) {
System.out.println(num);
}
}
}
}
上面这些代码在编译期并没有错误,但
是在运行后却会报错,如下图
有错误的也有正确的,我们看看正确的,如下图
List<Integer> c=new ArrayList();
c.add(22);
c.add(23);
c.add(24);
c.add(25);
c.add(28);
// c.add("s");
Iterator it=c.iterator();
while(it.hasNext()) {
Object obj=it.next();
int num=(int) obj;
if(num%2==0) {
System.out.println(num);
}
// System.out.println(it.next());
}
}
在lis
t集合第一行代码加上一个integer就可以了。这样就会在你打代码的时候会提醒你,而不是在运行的时候报错,这样会更快的解决问题,就这是泛型的好处
最后的一个问题,就是我们编程的时候加上泛型有什么好处,举行下面的一个例子,比如购物车的方法是这样的
购物车项目
* 订单模块。用户模块,商品模块
* Class OrderDao{
* public List<Order> list(Order order){
*
*
* }
* public int add(Order order){}
*
*
*
* public int edit(Order order){}
*
*
*
*
* public int del(Order order){}
* Class UserDao{
* public List<Order> list(User user){
* public int add(User user){}
* public int edit(User user){}
* public int del(User user){}
// }
这些代码是不使用泛型的
写法。下面这个是用泛型的写法,如下图
public int del(Order order){}
* Class UserDao{
* public List<Order> list(User user){
* public int add(User user){}
* public int edit(User user){}
* public int del(User user){}
// }
-
Class ProductDao{
-
}
-
Class BaseDao<T>{
-
public List<T> list(T t) * public int add(T t){} * public int edit(T t){} * public int del(T t){}
-
} * * * Class OrderDao extends BaseDao<Order>{} * Class UserDao extends BaseDao<User>{} * Class ProductDao extends BaseDao<Product>{} 我们只要调用它的那个方法就可以了,不要那么麻烦了