目录
集合框架Set
1.set集合不能存放重复元素的问题
a.不能存放重复元素(指的是字符串、八点基本数据类型)
package com.myy.set;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class SetDemo {
public static void main(String[] args) {
Set set=new HashSet<>();
set.add(new Person("zhangsan", 16, 1300) );
set.add(new Person("lisi",23,2000));
set.add(new Person("wanwu",18,1500));
set.add(new Person("wanmazi",22,3500));
set.add(new Person("lisi",23,2000));
System.out.println(set.size());//打印5
}
}
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();
}
}
b.set集合中的元素是无序的
Iterator it=set.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
用迭代器遍历得到打印对比
第一次:
第二次:
2.HashSet哈希表存储,重复元素存储底层探究
(1)List.contains—底层调用了equals方法
(2)Set.add–底层调用了hashCode/equals
(1)在Person类里写
public int hashCode() {
System.out.println("hashCode---");
int code=super.hashCode();
System.out.println(code);
return code;
}
public boolean equals(Object obj) {
System.out.println("equals---");
return super.equals(obj);
}
输出:
(2)当hashCode 返回定义死数据时
输出:
分析:每new一个对象都有一个地址值(不同),首先调用hashCode方法。如何让相同的参数地址值相同?
(通过相同姓名年龄得相同到地址)改变hashCode方法为:
public int hashCode() {
System.out.println("hashCode---"+this.name);
int code=this.name.hashCode()+this.age;
System.out.println(code);
return code;
}
输出:
分析:由上得知,当我们想认定为同一个人时,该如何做?
把equals方法改为:
public boolean equals(Object obj) {
Person p=(Person) obj;
return this.name.equals(p.name) && this.age==p.age;
}
输出:
结论:hashCode方法先算总和相同,则再判断equals方法。取而反之。提高效能性
集合框架TreeSet(自然排序,数据结构二叉树,比较器排序)
1.自然排序
(1)treeSet容器是根据二叉树的排序规则对容器中元素进行排序的
自然排序(元素自身具有比较性)
package com.myy.set;
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet set=new TreeSet<>();
set.add(13);
set.add(16);
set.add(44);
set.add(10);
set.add(11);
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() {
super();
}
public int hashCode() {
System.out.println("hashCode---"+this.name);
int code=this.name.hashCode()+this.age;
System.out.println(code);
return code;
}
public boolean equals(Object obj) {
Person p=(Person) obj;
return this.name.equals(p.name) && this.age==p.age;
}
}
输出:
举例说明:自然排序(元素自身具有比较性)
public static void main(String[] args) {
TreeSet set=new TreeSet<>();
set.add("abc");
set.add("bc");
set.add("ef");
set.add("efg");
set.add("de");
System.out.println(set);
}
输出:
package com.myy.set;
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet set=new TreeSet<>();
set.add(new Person("zhangsan", 16, 1300) );
set.add(new Person("wanwu",18,1500));
set.add(new Person("lisi",23,2000));
set.add(new Person("wanmazi",22,3500));
set.add(new Person("lisi",23,2000));
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() {
super();
}
public int hashCode() {
System.out.println("hashCode---"+this.name);
int code=this.name.hashCode()+this.age;
System.out.println(code);
return code;
}
public boolean equals(Object obj) {
Person p=(Person) obj;
return this.name.equals(p.name) && this.age==p.age;
}
}
输出:
类转换异常(原因在于没有实现该接口)
java.lang.ClassCastException:
com.myy.set.Person cannot be cast to java.lang.Comparable
a.实现后年龄和钱的自然排序代码:
(分析:排序作用。如果数据不在“A”这里,“A”该怎么排序)
package com.myy.set;
import java.util.Iterator;
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet set=new TreeSet<>();
set.add(new Person("zhangsan", 16, 1300) );
set.add(new Person("wanwu",18,1500));
set.add(new Person("lisi",23,2000));
set.add(new Person("wanmazi",22,3500));
set.add(new Person("lisi",23,2000));
// System.out.println(set);
Iterator it=set.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
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();
}
public int hashCode() {
System.out.println("hashCode---"+this.name);
int code=this.name.hashCode()+this.age;
System.out.println(code);
return code;
}
public boolean equals(Object obj) {
Person p=(Person) obj;
return this.name.equals(p.name) && this.age==p.age;
}
/**
* 让元素具有比较性
*注意:
*在做自然排序方法重写的时候,一定先判断主要条件、还要判断要条件
*/
public int compareTo(Person o) {
int num=o.money-this.money;
if(num==0) {
return this.age-o.age;
}
return num;
}
}
输出:
2.TreeSet数据结构(二叉树)
可以对set集合进行排序,底层数据结构是二叉树;
保证元素唯一性的依据是,compareTo方法return 0
注意:TreeSet排序的第一种方式,让元素自身具有比较性;
元素需要实现Comparable接口,覆盖compareTo方法;
这种方式也被称为元素的自然顺序,或者叫做默认顺序。
详细了解点击:
二叉树
问:如何让TreeSet集合中的元素怎么存进去怎么取出来呢?
答:compareTo方法返回值为正数,返回值写死,那么就是怎么存进去怎么取出来。
compareTo方法返回值为负数数,返回值写死,那么就是先进后出。
TreeSet比较器排序
a.年少多金
package com.myy.set;
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
//TreeSet set=new TreeSet<>();
TreeSet<Person> set=new TreeSet<>(new PersonAgeMoneyComp());
set.add(new Person("zhangsan", 16, 1300) );
set.add(new Person("wanwu",18,1500));
set.add(new Person("lisi",23,2000));
set.add(new Person("wanmazi",22,3500));
set.add(new Person("liting",23,4300));
// System.out.println(set);
Iterator it=set.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
/**
* 年少多金
* @author myy
*
*/
class PersonAgeMoneyComp implements Comparator<Person>{
public int compare(Person o1, Person o2) {
int num=o1.getAge()-o2.getAge();
if(num==0) {
return o2.getMoney()-o1.getMoney();
}
return num;
}
}
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();
}
public int hashCode() {
System.out.println("hashCode---"+this.name);
int code=this.name.hashCode()+this.age;
System.out.println(code);
return code;
}
public boolean equals(Object obj) {
Person p=(Person) obj;
return this.name.equals(p.name) && this.age==p.age;
}
/**
* 让元素具有比较性
*注意:
*在做自然排序方法重写的时候,一定先判断主要条件、还要判断要条件
*/
public int compareTo(Person o) {
int num=o.money-this.money;
if(num==0) {
return this.age-o.age;
}
return num;
}
}
输出:
b.有钱并且年轻
由a的代码改:
class PersonMoneyAgeComp implements Comparator<Person>{
public int compare(Person o1, Person o2) {
int num=o2.getMoney()-o1.getMoney();
if(num==0) {
return o1.getAge()-o2.getAge();
}
return num;
}
}
传迭代器方法如图:
输出:
结论:无论“B”如何传数据,“A”都能进行排序
泛型(概述及使用、泛型类、泛型方法、静态方法泛型、泛型接口)
好处/为什么出现?
举例说明:不使用泛型的情况下,会将未知的错误表现在运行时期
如果说用代码去处理了,这个可能发现的错误,那么运行时期的错误 就不会出来
package com.myy.set;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Genericity {
public static void main(String[] args) {
List 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();
if(obj instanceof Integer) {
int num=(int) obj;
if(num % 2 == 0) {
System.out.println(num);
}
}
}
}
}
输出:
1.将运行期的异常转换成遍译期的错误,让程序员更早发现,从而解决代码隐患
代码效果图:
2.提高了代码健壮性
健壮性强意味着代码运行过程中不容易报错,弱则反。
对于编码而言有什么更深层次的好处呢?
举例说明:泛型的简单应用
/*
* 购物车项目
* 订单模块、用户模块、商品模块
* Class OrderDao{
* public List<Order> list(Order o){}
* public int add(Order o){}
* public int edit(String id,Order o){}
* public int del(String id){}
*
* }
* Class UserDao{
* public List<User> list(User u){}
* public int add(User u){}
* public int edit(String id,User u){}
* public int del(String id){}
*
* }
* * Class ProductDao{
* public List<Product> list(Product p){}
* public int add(Product p){}
* public int edit(String id,Product p){}
* public int del(String id){}
*
* }
*
* ----不使用泛型的情况---
* ----使用泛型的情况---
* Class BaseDao<T>{
* public List<T> list(T t){}
* public int add(T t){}
* public int edit(String id,T t){}
* public int del(String id){}
* }
*Class OrderDao extends BaseDao<Order>{}
*Class UserDao extends BaseDao<User>{}
*Class ProductDao extends BaseDao<Product>{}
*
*/