Set集合、HashSet、TreeSet、泛型
- 声明:思路要自己慢慢掌握。
1、 Set set=new HashSet(); Set 和HasSet
1、Set和HasSet:唯一性,不能存放重复的值,允许使用null(值是八大基本类型,对象需要重写hashCode和equals方法);
代码如下:
package com.deng.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 Aromanic150
*
*/
public class SetDemo {
public static void main(String[] args) {
Set set = new HashSet();
set.add("q");
set.add("w");
set.add("e");
set.add("r");
set.add("t");
set.add("q");//和第一个相同被去到了
System.out.println(set.size());
System.out.println("----");
Iterator it = set.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
打印结果:
5
----
q
r
t
e
w
2、Set和HasSet:无序性 ; (声明:JDK版本的不同,就会不一样)
3、HasSet:底层数据结构是哈希表,没有提供get()方法,用HashMap一样,因为Set内部是无序的,所以只能通过跌代器Iterator和foreach的方式获得;
HashSet是如何保证元素唯一性的呢?
是通过元素的两个方法:hashCode与equals方法来完成;
如果hashCode值相同,才会判断equals是否为true;
如果hashCode值不同,那么不会调用equals。
这是HasSet的一下讲解链接,可以参考一下
https://blog.csdn.net/qq_36711757/article/details/80412894
去重复对象代码如下:
package com.deng.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 Aromanic150
*
*/
public class SetDemo {
public static void main(String[] args) {
Set set = new HashSet();
set.add(new Deng("qq", "12"));
set.add(new Deng("ww", "25"));
set.add(new Deng("ee", "22"));
set.add(new Deng("rr", "33"));
set.add(new Deng("tt", "12"));
set.add(new Deng("qq", "12"));
System.out.println(set.size());
System.out.println("----");
/*
* for (Object object : set) { System.out.println(object); }
*/
Iterator it = set.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
class Deng {
private String name;
private String age;
public Deng(String name, String age) {
super();
this.name = name;
this.age = age;
}
public Deng() {
super();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
@Override
public String toString() {
return "Deng [name=" + name + ", age=" + age + "]";
}
@Override
public int hashCode() {
System.out.println("code————hashcode--" + this.name);
int count = this.name.hashCode() + Integer.parseInt(this.age);// 因为我年龄是用String类型所以需要转一下
return count;// 返回的是int
}
@Override
public boolean equals(Object obj) {
Deng d = (Deng) obj;
return this.name.equals(d.name) && this.age == d.age;
}
}
打印出来的结果:
code————hashcode--qq
code————hashcode--ww
code————hashcode--ee
code————hashcode--rr
code————hashcode--tt
code————hashcode--qq
5
----
Deng [name=rr, age=33]
Deng [name=ee, age=22]
Deng [name=ww, age=25]
Deng [name=qq, age=12]
Deng [name=tt, age=12]
2、TreeSet集合框架(自然排序、数据结构二叉树、比较器排序)
1、TerrSet容器是根据二叉树的排序规则对容器中元素进行排序的自然排序(元素自身具有比较性)
代码如下:
package com.deng.set;
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet<Object> set=new TreeSet<>();
set.add("5");
set.add("3");
set.add("2");
set.add("4");
set.add("1");
System.out.println(set);
}
}
打印结果:
[1, 2, 3, 4, 5]
声明TreeSet自然排序比较重要,请认真查看
1、定义一个对象Deng.java类,实现Comparable接口
下面是对象的代码:
package com.deng.set;
import java.util.Iterator;
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet<Object> set=new TreeSet<>();
set.add(new Deng("qq", 12,5000));
set.add(new Deng("ww", 25,555));
set.add(new Deng("ee", 22,4040));
set.add(new Deng("rr", 33,4204));
set.add(new Deng("tt", 12,4500));
set.add(new Deng("qq", 100,5000));
Iterator it = set.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
class Deng implements Comparable<Deng>{//实现Comparable进行排序
private String name;
private int age;
private int money;
public Deng(String name, int age,int money) {
super();
this.name = name;
this.age = age;
this.money=money;
}
public Deng() {
super();
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
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;
}
@Override
public String toString() {
return "Deng [name=" + name + ", age=" + age + ", money=" + money + "]";
}
@Override
public int hashCode() {
System.out.println("code————hashcode--" + this.name);
return this.name.hashCode() + this.age;
}
@Override
public boolean equals(Object obj) {
Deng d = (Deng) obj;
return this.name.equals(d.name) && this.age == d.age;
}
/**
* 让元素具备比较性
* 注意:
* 在做自然排序方法重写的时候,一定先判断主要条件、还有判断次要条件
*
*/
@Override
public int compareTo(Deng o) {
//主要条件:先判断谁有钱
//次要条件:如果金额相等在判断年龄的谁的大;
int num=o.money-this.money;
if(num==0) {
return o.age-this.age;
}
return num;
}
}
打印结果:
//主要条件:先判断谁有钱
//次要条件:如果金额相等在判断年龄的谁的大;
Deng [name=qq, age=100, money=5000]
Deng [name=qq, age=12, money=5000]
Deng [name=tt, age=12, money=4500]
Deng [name=rr, age=33, money=4204]
Deng [name=ee, age=22, money=4040]
Deng [name=ww, age=25, money=555]
注意报错 :
如果对象没有实现 Comparable<对象> 会报错 java.lang. ClassCastException com.deng.set.Deng cannot be cast to java.lang.Comparable
TreeSet比较器代码:
Comparable和 Comparator都是java.util包下的两个接口,从字面上看这两个接口都是用来做比较用的,但是jdk里面不可能定义两个功能相同的接口,所以他们肯定有不同的用处。
1、Comparable:可以认为是一个内比较器,实现了Comparable接口的类有一个特点,就是这些 类是可以和自己比较的,至于具体和另一个实现了Comparable接口的类如何比较,则依赖compareTo方法的实现,compareTo方法也被称为自然比较方法。如果开发者add进入一个Collection的对象想要Collections的sort方法帮你自动进行排序的话,那么这个对象必须实现Comparable接口。compareTo方法的返回值是int。
- 1、比较者大于被比较者(也就是compareTo方法里面的对象),那么返回正整数
- 比较者等于被比较者,那么返回0;
- 比较者小于被比较者,那么返回负整数
package com.deng.set;
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;
/**
* 集合框架TreeSet(自然排序、数据结构二叉树、比较器排序)
* TerrSet容器是根据二叉树的排序规则对容器中元素进行排序的
* 自然排序(元素自身具有比较性)
*
* @author Aromanic150
*
*/
public class TreeSetDemo {
public static void main(String[] args) {
/* TreeSet<Deng> set=new TreeSet<>(new DengMoneyAgecom()); */
TreeSet<Deng> set=new TreeSet<>(new DengAgeMoneycom());
set.add(new Deng("qq", 12,5000));
set.add(new Deng("ww", 25,555));
set.add(new Deng("ee", 22,4040));
set.add(new Deng("rr", 33,4204));
set.add(new Deng("tt", 12,4500));
set.add(new Deng("qq", 100,5000));
Iterator it = set.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
/**
*
* 条件是:年青钱多
* @author Aromanic150
*
*/
class DengAgeMoneycom implements Comparator<Deng>{
@Override
public int compare(Deng o1, Deng o2) {
int num=o1.getAge()-o2.getAge();
if(num==0){
return o2.getMoney() - o1.getMoney();
}
return num;
}
}
/**
*
* 条件是:年青钱多
* @author Aromanic150
*
*/
class DengMoneyAgecom implements Comparator<Deng>{
@Override
public int compare(Deng o1, Deng o2) {
int num=o2.getMoney() - o1.getMoney();
if(num==0){
return o1.getAge()-o2.getAge();
}
return num;
}
}
class Deng implements Comparable<Deng>{
private String name;
private int age;
private int money;
public Deng(String name, int age,int money) {
super();
this.name = name;
this.age = age;
this.money=money;
}
public Deng() {
super();
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
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;
}
@Override
public String toString() {
return "Deng [name=" + name + ", age=" + age + ", money=" + money + "]";
}
@Override
public int hashCode() {
System.out.println("code————hashcode--" + this.name);
return this.name.hashCode() + this.age;
}
@Override
public boolean equals(Object obj) {
Deng d = (Deng) obj;
return this.name.equals(d.name) && this.age == d.age;
}
/**
* 让元素具备比较性
* 注意:
* 在做自然排序方法重写的时候,一定先判断主要条件、还有判断次要条件
*
*/
public int compareTo(Deng o) {
//主要条件:先判断谁有钱
//次要条件:如果金额相等在判断年龄的谁的大;
int num=o.money-this.money;
if(num==0) {
return o.age-this.age;
}
return num;
}
}
记得 TreeSet set=new TreeSet<>(new DengAgeMoneycom());
在参数里创建一个临时的对象DengAgeMoneycom;这样Comparator接口才会调用;
浅析 Comparable和 Comparator的区别!
https://blog.csdn.net/wlh2015/article/details/83959462
3、泛型<>
常用的被泛型化的集合类
1、 泛型:就是一种不确定的数据类型。
2、 比如:ArrayList ,就是泛型。 这种不确定的数据类型需要在使用这个类的时候才能够确定出来。
3、泛型可以省略,如果省略,默认泛型是Object类型。
4、 泛型的好处:
- 省略了强转的代码。
- 可以把运行时的问题提前到编译时期。
package com.deng.set;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* 泛型被规定了以后就只能放入规定的类型
* @author Aromanic150
*
*/
public class TestDemo {
public static void main(String[] args) {
List<Integer> l=new ArrayList<>();//数字只能放入引用数据类型,不能放int。
l.add(2);
l.add(1);
l.add(3);
l.add(4);
Iterator it=l.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
打印结果:
2
1
3
4
具体了解泛型!
https://blog.csdn.net/aimeizhewoye8/article/details/51124083