理解集合框架--set集合【2】

集合框架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>{}
 * 
 */

猜你喜欢

转载自blog.csdn.net/qq_44241551/article/details/94652440
今日推荐