集合框架——set集合

一.HashSet哈希表存储、重复元素存储底层探究
- set集合不能存放重复元素,并且是无序的
- list.contains 底层调用了equals
- set.add 底层调用hashCode/equals
package com.xfz.set;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/**
* 1.set集合不能存放重复元素的问题
* 不能存放重复的元素 (八大基本数据类型)
* set集合中的元素是无序的
* 2.HashSet哈希表存储、重复元素存储底层探究
* list.contains 底层调用了equals
* set.add 底层调用hashCode/equals
*
* @author ld
*
*/
public class SetDemo {
public static void main(String[] args) {
Set set=new HashSet<>();
set.add(new Person("zhangsan",18,1500));
set.add(new Person("lisi",23,500));
set.add(new Person("wangwu",19,1200));
set.add(new Person("zhaoliu",22,2500));
set.add(new Person("zhangsan",18,1500));
System.out.println(set.size()); //运行结果为4 因为set集合不能存放重复的元素
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() {
super();
}
@Override
public int hashCode() {
System.out.println("hashCode-------"+this.name);
// int code=super.hashCode();
// System.out.println(code);
int code=this.name.hashCode()+this.age;
System.out.println(code);
return code;//运行结果还是5人。
//原因:在set集合里面判断是否是同一个人不单单由hashCode这一个方法决定。还需要结合equals方法一起论证
}
@Override
public boolean equals(Object obj) {
System.out.println("equals---------");
Person p=(Person) obj;
return this.name.equals(p.name) && this.age==p.age;
}
}


二.TreeSet
- 自然排序(自身具有比较性)
引用大护具类型要实现Comparable接口,才可以直接进行排序。
注意:排序时,当主要条件相同时,一定要判断次要条件 - 比较器排序
定义一个类,实现comparator接口,实现compare方法。
与自然排序相比优先级更高 - treeset底层数据结构是:二叉树
package com.xfz.set;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
/**
* treeset容器是根据二叉树的排序规则对容器中的元素进行排序的 自然排序(元素自身具有比较性)
* java.lang.ClassCastException:
* com.xfz.set.Person cannot be cast to java.lang.Comparable
* (没有实现接口,所以报类转换异常)
* @author ld
*
*/
public class TreeSetDemo {
public static void main(String[] args) {
//TreeSet<Object> set=new TreeSet<>();
//TreeSet<Person> set=new TreeSet<>(new PersonAgeMoneyComp());//运行结果:按年龄升序排序,如果年龄相等则判断money
TreeSet<Person> set=new TreeSet<>(new PersonMoneyAgeComp());
set.add(new Person("zhangsan",18,5500));
set.add(new Person("lisi",23,500));
set.add(new Person("wangwu",22,1200));
set.add(new Person("zhaoliu",22,2500));
set.add(new Person("zhangsan",78,5500));
//Student extends/implements Person
//Student stu=(Student) p;
//System.out.println(set);
Iterator it=set.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
//上课例子(世纪佳缘)start----
class PersonAgeMoneyComp implements Comparator<Person>{
@Override
public int compare(Person o1, Person o2) {
int num=o1.getAge()-o2.getAge();
if(num==0) {
return o2.getMoney()-o1.getMoney();
}
return num;
}
}
class PersonMoneyAgeComp implements Comparator<Person>{
@Override
public int compare(Person o1, Person o2) {
int num=o2.getMoney()-o1.getMoney();
if(num==0) {
return o1.getAge()-o2.getAge();
}
return num;
}
}
//end----
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() {
super();
}
@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) {
int num=o.money-this.money;
if(num==0) {
return o.age-this.age;
}
return num;
}
}


三.泛型
- 泛型带来的好处:
1.1 将运行期的异常转换为编译期的错误,可以更早的发现,从而解决代码隐患
1.2 提高了代码的健壮性 - 对于编码而言更深层的好处:简化代码
package com.xfz.fanxin;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* 泛型:
* 好处:1.将运行期的异常转换为编译期的错误,可以更早的发现,从而解决代码隐患
* 2.提高了代码的健壮性
* 对于编码而言更深层的好处:简化代码
* @author ld
*
*/
public class FanXinDemo {
public static void main(String[] args) {
List<Integer> c=new ArrayList<>();
c.add(22);
c.add(23);
c.add(26);
c.add(28);
c.add(55);
//c.add("s");
Iterator it=c.iterator();
while(it.hasNext()) {
Object obj=it.next();
int num=(int) it.next();
if(num%2==0) {
System.out.println(num);//不用泛型插入String会出现java.lang.ClassCastException:类转换异常
}
}
}
}
/*
* 购物车项目
* 订单模块,用户模块、商品模块
* 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<User> 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){}
* }
* 继承BaseDao所有方法都有 简化代码
* Class OrderDao extends BaseDao<Order>{}
* Class UserDao extends BaseDao<User>{}
* Class ProductDao extends BaseDao<Product>{}
*/