双列集合
Map集合是Java中为了应对键值映射关系问题所提供的一种集合:Map<K,V>。其中k为键(key),v为值(value);一个集合中一个键只能出现一次,并且一个键只能对应一个值。
用Student类来演示HashMap
学生类:
public class Student {
private String name;
private int age;
public Student() { }//空参构造
public Student(String name, int age) {//有参构造
this.name = name;
this.age = age;
}
//IDE快捷键ALT+INSERT,生成相应的get、set方法
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;
}
//重写toString、equals、hashCode方法。
@Override
public String toString() {
return "Student{" + "name='" + name + '\'' + ", age=" + age + '}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age &&
Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
hashMap演示:
public class MyTest7 {
public static void main(String[] args) {
//双列集合,所有的数据结构,只跟键有关,跟值没关系
HashMap<Student, String> hashMap = new HashMap<>();
//录入建和值:hashMap.put(Student key,String value);
//key就是我们上面建立的student类型,value就是newhashMap时泛型中规定的类型数据
hashMap.put(new Student("张三0", 23), "s001");
hashMap.put(new Student("张三0", 23), "s0011");//如果键相同,值不会录入,
hashMap.put(new Student("张三1", 23), "s002");
hashMap.put(new Student("张三2", 23), "s003");
hashMap.put(new Student("张三3", 23), "s004");
hashMap.put(new Student("张三4", 23), "s005");
System.out.println(hashMap);
}
}
遍历hashMap集合
public class MyTest8 {
public static void main(String[] args) {
//遍历hashMap集合
HashMap<Integer, String> hashMap = new HashMap<>();//定义双列集合
//用put方法向集合中添加元素
hashMap.put(1, "one");
hashMap.put(2, "two");
hashMap.put(3, "three");
hashMap.put(4, "fore");
hashMap.put(5, "five");
//entrySet() 获取键值对,放到Set集合里面去
Set<Map.Entry<Integer, String>> entries = hashMap.entrySet();
//getKey ()返回与此项对应的键。
//getValue ()返回与此项对应的值。
for (Map.Entry<Integer, String> entry : entries) {//entries的新式for循环
Integer key = entry.getKey();//得到键
String value = entry.getValue();//得到值
System.out.println(key+" "+value);//拼接字符串并输出
}
}
}
public class MyTest8 {
public static void main(String[] args) {
HashMap<Integer, String> hashMap = new HashMap<>();
hashMap.put(1, "a");
hashMap.put(1, "b");
hashMap.put(2, "c");
hashMap.put(3, "d");
hashMap.put(4, "e");
hashMap.put(5, "f");
System.out.println(hashMap.remove(4));//remove 移除键对应的值
System.out.println(hashMap);
hashMap.clear(); //清空集合中所有的元素
boolean empty = hashMap.isEmpty();//判断集合是不是空集合
System.out.println(empty);
}
}
Set集合
set集合:一个不包含重复元素的collection。在set集合中:元素是无序(存储和取出的顺序)并且唯一的。
本文将介绍set集合的三个常用集合:HashSet、LinkedHashSet和TreeSet。
HashSet
HashSet其实使用HsahMap来存储元素的,基于哈希表的Map接口的实现。
HashSet底层数据结构是哈希表(哈希表:是一个元素为链表的数组,综合了数组和链表的优点。)
HashSet 集合能够保证元素的唯一性,是靠元素重写hashCode方法和equals()方法来保证的,如果不重写则无法保证。重写hashCode是为了确定该元素在哈希表中的位置,我们合理重写hashCode可以减少元素之间的碰撞;重写equals是为了比较内容。HashSet中,所有的数据结构只跟键有关,跟值没关系。当发生键相同的时候,值就会覆盖,返回的是旧值,所以就保证了元素的唯一性。
public class MyTest {
public static void main(String[] args) {
//创建Student元素
Student s1 = new Student("张三", 3);
Student s2 = new Student("李四", 4);
Student s3 = new Student("王五", 5);
Student s4 = new Student("赵六", 6);
Student s5 = new Student("田七", 7);
//建立hsahSet集合
HashSet<Student> hashSet = new HashSet<>();
//调用add方法添加元素
hashSet.add(s1);
hashSet.add(s2);
hashSet.add(s3);
hashSet.add(s4);
hashSet.add(s5);
//遍历hashSet集合
for (Student student : hashSet) {
System.out.println(student.getName()+" "+student.getAge());
}
}
}
LinkedHashSet
LinkedHashSet中的元素有序且唯一。LinkedHashSet用链表保证元素有序,用哈希表保证元素唯一。
public class MyTest8 {
public static void main(String[] args) {
// LinkedHashSet集合的底层数据结构是链表和哈希表,集合中元素有序且唯一。
// 链表保证了元素有序,哈希表保证了元素唯一。
Student david = new Student("David", 20);
Student kimi = new Student("Kimi", 15);
Student jack = new Student("Jack", 21);
Student petter = new Student("Petter", 18);
LinkedHashSet<Student> linkedHashSet = new LinkedHashSet<>();
linkedHashSet.add(david);
linkedHashSet.add(kimi);
linkedHashSet.add(jack);
linkedHashSet.add(petter);
System.out.println(linkedHashSet);
//遍历linkhashset集合
for (Student s : linkedHashSet) {
System.out.println(s);
}
}
}
TreeSet
TreeSet中的元素有唯一的特点,并且可以对元素进行排序。
TreeSet的特点
TreeSet的本质其实是使用二叉树来存元素:先存入一个树根,再存元素时每一个元素要和树根比较,小的放在左边,大的放在右边,如果新元素和旧元素相同就不储存,然后取出元素的时候按照左中右的顺序来取元素,就保证了元素的有序和唯一。
TreeSet的元素排序
-
自然排序:用空参构造,那么就使用的是自然排序。使用自然排序时:要求元素实现Comparable接口重写compareTo方法
public class MyTest8 { public static void main(String[] args) { // TreeSet 底层数据结构是二叉树,元素唯一,他最大的特点是能够对元素进行排序 TreeSet<Integer> treeSet = new TreeSet<>(); treeSet.add(20); treeSet.add(18); treeSet.add(23); treeSet.add(22); treeSet.add(17); treeSet.add(24); treeSet.add(19); treeSet.add(18); treeSet.add(24); for (Integer integer : treeSet) { System.out.println(integer); } } }
-
比较器排序:有参构造,可以使用比较器来排序。需要传入一个比较Comparator重写里面的compare这个比较方法,根据此方法返回值的正负0来决定元素的排列位置。
public class MyTest8 { //比较器给TreeSet集合排序 public static void main(String[] args) { //TreeSet可以用比较器排序,采用有参构造,给集合传入一个比较器: //TreeSet(Comparator<?super E>comparator) Student david = new Student("David", 20); Student kimi = new Student("Kimi", 15); Student jack = new Student("Jack", 21); Student petter = new Student("Petter", 18); //新建TreeSet集合,新建比较器接口,重写compare方法,实现比较器比较。 //接口 Comparator< T > // int compare (T o1, T o2)比较用来排序的两个参数 TreeSet<Student> treeSet = new TreeSet<>(new Comparator<Student>() { @Override public int compare(Student s1, Student s2) { //按照年龄大小排序 int num = s1.getAge() - s2.getAge(); int num2=num==0?s1.getName().compareTo(s2.getName()):num; return num2; } }); treeSet.add(david); treeSet.add(kimi); treeSet.add(jack); treeSet.add(petter); for (Student student : treeSet) { System.out.println(student); } } }