Day14_数据结构和集合(下)
HashSet
底层:数组+链表
优点
查询,删除,增加快
JDK1.8之后,链表长度超过8时,变成红黑树,目的是为了查询效率高
import java.util.HashSet;
public class Demo01 {
public static void main(String[] args) {
//数据类型是Integer时,直接将数值大小取余,根据余数的值选择对应的存储位置,
//然后比较是否有相同的值,若有相同的值,就不新增;若无相同的值,就新增。
//数据类型是其他数据类型时,通过函数将数据转成整型的值,然后进行取余,存储等操作。
//数据类型是自定的类是,重写hashCode()和equals(),然后进行取余,存储等操作。
HashSet<Integer> hs=new HashSet<Integer>();
hs.add(12);
hs.add(9);
hs.add(12);
hs.add(4);
hs.add(27);
hs.add(8);
System.out.println(hs);
System.out.println(hs.size());
}
}
输出
//无序(不按输入顺序输出),唯一
[4, 8, 9, 27, 12]
5
TreeSet
底层:二叉树(红黑树)
自定义的类放入集合中,要实现内部比较器或者外部比较器
import java.util.TreeSet;
public class Demo01 {
public static void main(String[] args) {
TreeSet<Integer> ts=new TreeSet<Integer>();
ts.add(12);
ts.add(6);
ts.add(15);
ts.add(3);
ts.add(12);
ts.add(1);
//无序(没有按照输入顺序输出),有序(按照从大到小的顺序输出),唯一
System.out.println(ts);
System.out.println(ts.size());
}
}
输出
[1, 3, 6, 12, 15]
5
TreeSet
自定义类放入集合中,要实现内部比较器或者外部比较器。
内部比较器
Student类:
import java.util.Comparator;
public class Student implements Comparable<Student>{
private String name;
private int age;
private double height;
public Student(String name, double height,int age) {
this.setName(name);
this.setAge(age);
this.setHeight(height);
}
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 double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
//重写toString方法
@Override
public String toString() {
return "Student{" +name +"," + age + "," +height + '}';
}
@Override
public int compareTo(Student o) {
//定义规则
//按照年龄
//return this.getAge()-o.getAge();
//按照身高
//return ((Double)this.getHeight()).compareTo((Double)o.getHeight());
//按照姓名
return this.getName().compareTo(o.getName());
}
}
测试:
import java.util.TreeSet;
public class Demo02 {
public static void main(String[] args) {
TreeSet<Student> ts = new TreeSet<Student>();
ts.add(new Student("blili",150.9,15));
ts.add(new Student("clili",190.9,19));
ts.add(new Student("blili",170.9,14));
ts.add(new Student("alili",160.9,21));
System.out.println(ts);
System.out.println(ts.size());
}
}
输出:
[Student{alili,21,160.9}, Student{blili,15,150.9}, Student{clili,19,190.9}]
3
外部比较器
Student类
import java.util.Comparator;
public class Student implements Comparable<Student>{
private String name;
private int age;
private double height;
public Student(String name, double height,int age) {
this.setName(name);
this.setAge(age);
this.setHeight(height);
}
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 double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
//重写toString方法
@Override
public String toString() {
return "Student{" +name +"," + age + "," +height + '}';
}
}
class Compare01 implements Comparator<Student> {
@Override
//根据身高
public int compare(Student o1, Student o2) {
com.shan.TreeSet.Student s1=(com.shan.TreeSet.Student) o1;
com.shan.TreeSet.Student s2=(com.shan.TreeSet.Student) o2;
return ((Double)s1.getHeight()).compareTo((Double)s2.getHeight());
}
}
class Compare02 implements Comparator<Student> {
@Override
//根据年龄
public int compare(Student o1, Student o2) {
com.shan.TreeSet.Student s1=(com.shan.TreeSet.Student) o1;
com.shan.TreeSet.Student s2=(com.shan.TreeSet.Student) o2;
return s1.getAge()-s2.getAge();
}
}
测试
import java.util.Comparator;
import java.util.TreeSet;
public class Demo03 {
public static void main(String[] args) {
//新建一个比较器
Comparator<Student> com=new Compare02();
//将新建的比较器传进去
TreeSet<Student> ts=new TreeSet<Student>(com);
ts.add(new Student("blili",150.9,15));
ts.add(new Student("clili",190.9,19));
ts.add(new Student("blili",170.9,14));
ts.add(new Student("alili",160.9,21));
System.out.println(ts);
System.out.println(ts.size());
}
}
输出
//按照年龄排序
[Student{blili,14,170.9}, Student{blili,15,150.9}, Student{clili,19,190.9}, Student{alili,21,160.9}]
4
匿名内部类
Student类只须有基本的属性即可,直接在新建TreeSet对象时将方法compareTo()重写。
import java.util.Comparator;
import java.util.TreeSet;
public class Demo04 {
public static void main(String[] args) {
TreeSet<Student> ts=new TreeSet<Student>(new Comparator<Student>(){
@Override
public int compare(Student o1, Student o2) {
return o1.getName().compareTo(o2.getName());
}
});
ts.add(new Student("blili",150.9,15));
ts.add(new Student("clili",190.9,19));
ts.add(new Student("blili",170.9,14));
ts.add(new Student("alili",160.9,21));
System.out.println(ts);
System.out.println(ts.size());
}
}
输出:
按照姓名排序
[Student{alili,21,160.9}, Student{blili,15,150.9}, Student{clili,19,190.9}]
3
Map
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Demo05 {
public static void main(String[] args) {
//HashMap特点:按照key来说的,key底层遵照的是哈希表(散列表)原理---key唯一,无序(不按输入顺序输出)
//如果将一个自定义类放入key中,这个类要重写hashCode()方法和equals()方法
Map<Integer,String> m=new HashMap<Integer,String>();
m.put(1001,"lili");
m.put(340,"lulu");
m.put(980,"nana");
m.put(1001,"feifei");
m.put(580,"mingming");
System.out.println(m);
System.out.println(m.size());
//对集合遍历
//对key进行遍历:
Set<Integer> keySet=m.keySet();
for (Integer i:keySet) {
System.out.print(i+" ");
}
System.out.println();
//对value进行遍历:
Collection<String> values=m.values();
for (String s:values) {
System.out.print(s+" ");
}
System.out.println();
//通过对key进行遍历,输出所有的value
for (Integer i:keySet) {
System.out.print(m.get(i)+" ");
}
System.out.println();
//对key,value成对遍历
Set<Map.Entry<Integer,String>> es=m.entrySet();
for (Map.Entry<Integer,String> en:es) {
System.out.println(en.getKey()+":"+en.getValue());
}
}
}
输出:
//1001=feifei是由于1001是唯一的,故1001是语句`m.put(1001,"lili");`中的1001,
//但后面的值不是唯一的,故lili被feifei替换掉,feifei是语句`m.put(1001,"feifei")`中的feifei.
{340=lulu, 980=nana, 580=mingming, 1001=feifei}
4
340 980 580 1001
lulu nana mingming feifei
lulu nana mingming feifei
340:lulu
980:nana
580:mingming
1001:feifei
HashMap:效率高,线程不安全,key或者value允许为空。
Hashtable:效率低,线程安全,key或者value都不允许为空。
LinkedHashMap:有序(按输入顺序输出),唯一。
HashSet是以HashMap为基础。
TreeMap
底层:key遵照二叉树(红黑树原理)。
如果是自定义类作为key存放的话,要实现内部比较器或者外部比较器。
Collections类
构造器是private类型,不能创建对象。