1、集合框架Set(HashSet哈希表存储、重复元素存储底层探究)
- 元素是无序(存入和取出的顺序不一定一致),元素不可以重复;
package com.hyf.set;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/**
* 1.set 集合 不能存放重复元素的问题 不能存放重复元素 字符串 八大基本数据类型
* 2.HashSet 哈希表存储,重复元素存储底层探究
* list.contains 底层调用 equals 方法 set.add 底层调用hashCode/equals
* */
public class SetDemo {
public static void main(String[] args) {
Set set=new HashSet<>();
set.add(new Person("张三", 14 , 1000));
set.add(new Person("张三", 14, 1000));
set.add(new Person("王五",23, 8999));
set.add(new Person("傻逼", 21,2000 ));
set.add(new Person("二百",32 ,30000 ));
set.add(new Person("刚刚", 43,4000 ));
Iterator it=set.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
class Person{
private String name;
private int age;
private int money;
public Person() {}
public Person(String name, int age, int money) {
this.name = name;
this.age = age;
this.money = 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;
}
public String toString() {
return "Person [name=" + name + ", age=" + age + ", money=" + money + "]";
}
// 重点
public int hashCode() {
System.out.println(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;
}
}
2、集合框架TreeSet(自然排序、数据结构二叉树、比较器排序)
-
自然排序 TreeSet之所以能够进行排序,原因在于让容器中元素自身具备比较性,
实现了java.lang.Conparable接口 -
数据结构二叉树 定义一个内实现 Comparable 接口,实现compareTo方法
compareTo方法返回值为正数,返回值写死,那么就是怎么存进去怎么取出来。
compareTo方法返回值为负数数,返回值写死,那么就是先进后出。 -
比较器排序 定义一个类,实现comparator接口,实现compare方法
package com.hyf.set;
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;
/**
* 2.集合框架TreeSet(自然排序、数据结构二叉树、比较器排序) 红黑树 1.treeSet 容器是根据二叉树的排序规则队容器中的元素进行排序
* 自然排序(元素自身具有比较性)
*
* 错误: java.lang.ClassCastException: com.hyf.set.Person cannot be cast to java.lang.Comparable
* a.自然排序
* b.比较排序()
*/
public class TreeSetDemo {
public static void main(String[] args) {
/* TreeSet ts = new TreeSet<>();*/ // 自然排序
// TreeSet<Person> ts=new TreeSet<>(new PersonAgeMoneyComp()); // 比较排序
TreeSet<Person> ts=new TreeSet<>(new PersonMoneyAgeComp());
ts.add(new Person("张三", 11, 16000));
ts.add(new Person("张好", 31, 12000));
ts.add(new Person("王五", 11, 32000));
ts.add(new Person("傻逼", 21, 2000));
ts.add(new Person("二百", 61, 30000));
ts.add(new Person("刚刚", 41, 4000));
Iterator it=ts.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
/**
* 年少多金
*
*/
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 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;
}
}
class Person implements Comparable<Person> {
private String name;
private int age;
private int money;
public Person() {
}
public Person(String name, int age, int money) {
this.name = name;
this.age = age;
this.money = 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;
}
public String toString() {
return "Person [name=" + name + ", age=" + age + ", money=" + money + "]";
}
// 重点 去重
public int hashCode() {
System.out.println(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 o.age -this.age;
}
return num;
}
}
最后执行的是 钱多 年少
3、泛型(概述及使用、泛型类、泛型方法、静态方法泛型、泛型接口)
1. 如果不使用泛型,会将未知的错误表现在运行时期。如果说用代码去解决了这个错误,那么运行时会隐藏掉错误
package com.hyf.set;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* 泛型
* 好处/为什么
* 不使用 泛型的情况下,会将未知的错误表现在运行期
* 如果说用代码去处理了,这个可能发现的错误,那么运行时期的错误就不会暴露
* 1,将运行期的异常转换成编译期的错误 ,让程序员更早的发现,从而解决隐患
* 2,提高了代码的健壮性
* 泛型类
* 泛型借口
* 泛型方法
* 对于编码而言有什么更深层的含义
*/
public class FanXinDemo {
public static void main(String[] args) {
List l= new ArrayList<>();
l.add(12);
l.add(13);
l.add(14);
l.add(15);
l.add(66);
l.add("s");
Iterator it=l.iterator();
while(it.hasNext()) {
Object obj=it.next();
if(obj instanceof Integer) {
int num=(int) obj;
if(num % 2==0) {
System.out.println(num);
}
}
}
}
}
2. 使用泛型的好处
- 将运行期的异常传换成编译时期的异常,让程序员更早发现,解决隐患
- 提高代码健壮性