Java集合框架

Java集合框架

集合:对象的容器,定义了很多个对象进行操作的常用方法,可实现数组的功能。

和数组区别:

  1. 数组长度固定,集合长度不固定
  2. 数组可以存储基本数据类型和引用数据类型,而集合只能存储引用数据类型

Collection体系集合

在这里插入图片描述

List:有序、有下标、元素可重复
Set:无序、无下标、元素不可重复

方法说明
boolean add(Object obj)添加一个对象
boolean addAll(Collection c)将一个集合中的所有对象添加到此集合中
void clear()清空此集合的所有对象
boolean contains(Object o)检查此集合中是否包含o对象
boolean equals(Object o)比较此集合是否与指定的对象相等
boolean isEmpty()判断此集合是否为空
boolean remove(Object o)在此集合中移除对象o
int size()返回集合中元素的个数
Object[] toArray()将此集合转换为数组
Collection  collection = new ArrayList();
//1. 增加 add()
collection.add("苹果");
collection.add("香蕉");
collection.add("葡萄");
System.out.println("当前元素个数为:"+collection.size());
System.out.println(collection);
//2. 删除 remove()
collection.remove("苹果");
System.out.println("当前元素个数为"+collection.size());
System.out.println(collection);
//3.1 遍历集合 增强for
System.out.print("使用增强for循环:");
for (Object o : collection) {
    System.out.print(o+" ");
}
System.out.println();
//3.2 遍历结合 迭代器 iterator() 不能在迭代器中使用collection.remove
//hasNext():有没有下一个元素
//next():获取下一个元素
//remove():删除当前元素
System.out.print("使用迭代器:");
Iterator iterator = collection.iterator();
while(iterator.hasNext()){
    Object next = iterator.next();
    System.out.print(next+" ");
// iterator.remove();
}
//4. 判断 contains包含某一对象  isEmpty
System.out.println();
boolean b = collection.contains("香蕉");
System.out.println(b);
System.out.println(collection.isEmpty());

在这里插入图片描述

Student student1 = new Student("张三",12);
Student student2 = new Student("李四",23);
Student student3 = new Student("王五",25);
Collection collection = new ArrayList();
//1. 添加
collection.add(student1);
collection.add(student2);
collection.add(student3);
System.out.println("元素个数为:"+collection.size());
System.out.println(collection);
//2. 删除
collection.remove(student2);
System.out.println("元素个数为:"+collection.size());
System.out.println(collection);
//3.1 遍历----增强for
System.out.print("使用增强for遍历:");
for(Object obj:collection){
    Student s = (Student)obj;
    System.out.print(s+" ");
}
System.out.println();
//3.2 遍历----迭代器
System.out.print("使用迭代器遍历:");
Iterator iterator = collection.iterator();
while(iterator.hasNext()){
    Student s = (Student) iterator.next();
    System.out.print(s+" ");
}
//4. 清空 clear
System.out.println();
System.out.println("使用clear清空,对象并未清除,只是指针撤销");
// collection.clear();
// System.out.println(collection.size());
//5. 判断
System.out.println(collection.contains(student1));
System.out.println(collection.contains(new Student("张三", 20)));
System.out.println(collection.isEmpty());

在这里插入图片描述

List子接口

添加时可以指定添加元素的位置
删除 remove() 可以删除指定位置的元素
可以使用for循环遍历 list.get(i)
使用ListIterator 可以正序、倒序循环,也可以对元素进行增加、删除、修改,可以显示元素的位置 lit.nextIndex(),且进行倒序时,先进行正序把指针后移
可以获取某个元素的索引:list.indexOf(“苹果”)

方法说明
void add(int index,Object o)在index位置插入对象o
boolean addAll(int index,Collection c)将一个集合中的元素添加到此集合中的index位置
Object get(int index)返回集合中指定位置的元素
List subList(int fromIndex,int toIndex)返回fromIndex和toIndex之间的集合元素
List list = new ArrayList();
//1. 添加 add()
list.add("小米");
list.add("华为");
//添加时可以指定添加元素的位置
list.add(0,"苹果");
list.add("三星");
System.out.println("元素个数为:"+list.size());
System.out.println(list);
//2. 删除 remove() 可以删除指定位置的元素
//list.remove("三星");
list.remove(2);
System.out.println("元素个数为:"+list.size());
System.out.println(list);
//3.1 使用增强for遍历
System.out.print("使用增强for遍历:");
for (Object o : list) {
    System.out.print(o+" ");
}
System.out.println();
//3.2 使用for循环遍历
System.out.print("使用for循环遍历:");
for(int i=0 ;i<list.size();i++){
    System.out.print(list.get(i)+" ");
}
System.out.println();
//3.3 使用iterator
System.out.print("使用iterator:");
Iterator it = list.iterator();
while(it.hasNext()){
    System.out.print(it.next()+" ");
}
System.out.println();
//3.4 使用ListIterator 可以正序、倒序循环,也可以对元素进行增加、删除、修改
System.out.print("使用ListIterator正序输出:");
ListIterator lit = list.listIterator();
while(lit.hasNext()){
    System.out.print(lit.nextIndex()+":"+lit.next()+" ");
}
System.out.println();
System.out.print("使用ListIterator倒序输出:");
while(lit.hasPrevious()){
    System.out.print(lit.previousIndex()+":"+lit.previous()+" ");
}
System.out.println();
//4. 判断
System.out.println(list.contains("苹果"));
System.out.println(list.isEmpty());
//5. 获取位置
System.out.println(list.indexOf("苹果"));

在这里插入图片描述

List list = new ArrayList();
//列表中添加数字,实际是包含了自动装箱操作,数字已经变为对象
list.add(10);
list.add(20);
list.add(30);
list.add(40);
System.out.println("当前元素个数为:"+ list.size());
System.out.println(list);
//不可直接这样操作 list.remove(20); 20会被认为是索引
boolean remove = list.remove((new Integer(20)));
System.out.println(list);
//subList  含头不含尾
List list1 = list.subList(1, 2);
System.out.println(list1);

在这里插入图片描述

List实现类

  1. ArrayList 重点
  • 数组结构实现,查询快、增删慢
  • JDK1.2版本,运行效率快,线程不安全
  1. Vector
  • 数据结构实现,查询快、增删慢
  • JDK1.0版本,运行效率慢、线程安全
  1. LinkedList
  • 链表结构实现,查询慢、增删快

ArrayList
存储结构:数组
默认容量:DEFAULT_CAPACITY = 10 当没有添加元素是容量为0,每次扩容为原来的1.5倍,即当添加第11个元素时,容量为15
存放元素的数组:elementData
实际元素个数:size
add():添加元素

ArrayList arrayList= new ArrayList<>();
Student s1 = new Student("小明", 20);
Student s2 = new Student("小红", 21);
Student s3 = new Student("小王", 18);
Student s4 = new Student("小张", 20);
//1. 添加元素
arrayList.add(s1);
arrayList.add(s2);
arrayList.add(s3);
arrayList.add(s4);
System.out.println("元素个数:"+arrayList.size());
System.out.println(arrayList);
//2. 删除元素
// Object remove = arrayList.remove(0);
// System.out.println(arrayList);
// boolean remove1 = arrayList.remove(s2);
// System.out.println(arrayList);
// arrayList.clear();
//3. 遍历元素
System.out.println("----------------使用iterator遍历:");
Iterator it = arrayList.iterator();
while(it.hasNext()){
    Student s =(Student) it.next();
    System.out.println(s+" ");
}
System.out.println("-------使用listIterator正序遍历:");
ListIterator lit = arrayList.listIterator();
while(lit.hasNext()){
    Student s = (Student) lit.next();
    System.out.println(s+" ");
}
System.out.println("-------使用listIterator倒序遍历:");
while(lit.hasPrevious()){
    Student s = (Student) lit.previous();
    System.out.println(s+" ");
}
//4. 判断
System.out.println(arrayList.contains(s2));
System.out.println(arrayList.isEmpty());
//5. 位置
System.out.println(arrayList.indexOf(s2));

在这里插入图片描述

Vector
存储结构:数组

新增方法

Enumeration en = vector.elements();
while(en.hasMoreElements()){
    System.out.print(en.nextElement()+" ");
}
System.out.println(vector.firstElement());
System.out.println(vector.lastElement());
System.out.println(vector.elementAt(1));
Vector vector = new Vector<>();
//1. 添加
vector.add("小明");
vector.add("小红");
vector.add("小张");
System.out.println(vector.size());
System.out.println(vector);
//2. 删除
//  boolean s = vector.remove("小红");
//  System.out.println(vector);
//  Object remove = vector.remove(2);
//  System.out.println(vector);
//  vector.clear();
//3. 遍历 使用枚举器
System.out.print("使用枚举器遍历:");
Enumeration en = vector.elements();
while(en.hasMoreElements()){
    System.out.print(en.nextElement()+" ");
}
System.out.println();
//4. 判断
System.out.println(vector.contains("小明"));
System.out.println(vector.isEmpty());
//5. 位置
System.out.println(vector.indexOf("小红"));
System.out.println(vector.firstElement());
System.out.println(vector.lastElement());
System.out.println(vector.elementAt(1));

在这里插入图片描述

LinkedList
存储结构:双向链表

LinkedList linkedList = new LinkedList<>();
Student s1 = new Student("小红", 20);
Student s2 = new Student("小明", 19);
Student s3 = new Student("小白", 21);
//1. 添加
linkedList.add(s1);
linkedList.add(s2);
linkedList.add(s3);
System.out.println("元素个数:"+linkedList.size());
System.out.println(linkedList);
//2. 删除
//        boolean remove = linkedList.remove(s1);
//        Object remove1 = linkedList.remove(0);
//        linkedList.clear();
//3.1 遍历---增强for
System.out.print("增强for:");
for(Object o:linkedList){
    System.out.print(o+" ");
}
System.out.println();
//3.2 遍历---for循环
System.out.print("for循环:");
for (int i=0;i<linkedList.size();i++){
    System.out.print(linkedList.get(i)+" ");
}
System.out.println();
//3.3 遍历---iterator迭代器
System.out.print("iterator迭代器:");
Iterator it = linkedList.iterator();
while(it.hasNext()){
    System.out.print(it.next()+" ");
}
System.out.println();
//3.4 遍历---列表迭代器
System.out.print("linkedList迭代器正序输出:");
ListIterator lit = linkedList.listIterator();
while(lit.hasNext()){
    System.out.print(lit.next()+" ");
}
System.out.println();
System.out.print("linkedList迭代器倒序输出:");
while(lit.hasPrevious()){
    System.out.print(lit.previous()+" ");
}
System.out.println();
//4. 判断
System.out.println(linkedList.isEmpty());
System.out.println(linkedList.contains(s2));
//5. 位置
System.out.println(linkedList.indexOf(s2));
System.out.println(linkedList.get(2));
System.out.println(linkedList.getFirst());
System.out.println(linkedList.getLast());

在这里插入图片描述

泛型

JDK1.5中引入的一个新特性,本质是参数化类型,把类型作为参数传递
常见形式有泛型类、泛型接口、泛型方法
语法:<T,…> T为类型占位符,表示一种引用类型
好处:

  1. 提高代码重用性
  2. 防止类型转换异常,提高代码的安全性

注:

  • 泛型只能是引用类型
  • 不同的泛型对象不能相互赋值
泛型类
//创建一个泛型类
public class MyGeneric<T> {
    //1. 使用泛型创建变量
     T t;
    //2. 泛型作为方法的参数
    public void show(T t){
        System.out.println(t);
    }
    //3. 泛型作为方法的返回值
    public T getT(){
        return this.t;
    }
}
public class testGeneric {
   public static void main(String[] args) {
       MyGeneric<String> smg = new MyGeneric<>();
       smg.t = "Java";
       smg.show("你好啊");
       System.out.println(smg.getT());

       MyGeneric<Integer> smg1 = new MyGeneric<>();
       smg1.t=120;
       smg1.show(560);
       System.out.println(smg1.getT());
   }
}
泛型接口
//创建泛型接口
public interface MyInterface<T> {
    String name= "java";
    T serve(T t);
}
//方式一
public class MyInterfaceImpl implements MyInterface<String>{
   @Override
   public String serve(String s) {
       System.out.println(s);
       return s;
   }
}
MyInterfaceImpl impl1 = new MyInterfaceImpl();
impl1.serve("hello");
//方式二
public class MyInterfaceImpl1<T> implements MyInterface<T>{
   @Override
   public T serve(T t) {
       System.out.println(t);
       return t;
   }
}
MyInterfaceImpl1<Integer> impl2 = new MyInterfaceImpl1<>();
impl2.serve(50);
泛型方法
public class demo1 {
   //泛型方法
   public <T> T show(T t){
       System.out.println(t);
       return t;
   }
}
//在调用泛型方法时不需要指定类型
demo1 demo1 = new demo1();
demo1.show("你好啊");
demo1.show(100);
demo1.show(3.14);
demo1.show(false);
泛型集合

如果不使用泛型的话,当集合中添加不同类型的数据,需要遍历而进行强制转换时就有可能会出错。

ArrayList arrayList = new ArrayList();
arrayList.add("zzz");
arrayList.add("xxx");
arrayList.add(200);
arrayList.add(100);
for(Object o:arrayList){
    String s =(String)o;
    System.out.print(s+" ");
}

在这里插入图片描述

当引入泛型后,集合中就只能添加具体类型的数据,从而不会出现强制类型转换错误

ArrayList<String> arrayList = new ArrayList();
arrayList.add("zzz");
arrayList.add("xxx");
for(Object o:arrayList){
    String s =(String)o;
    System.out.print(s+" ");
}

这里将泛型指定为Student,所以集合中只能添加Student类的对象,同时迭代器也可以使用泛型,这样在之后的遍历中就不用进行强制类型转换了

Student s1 = new Student("小红", 20);
Student s2 = new Student("小明", 19);
Student s3 = new Student("小白", 21);
ArrayList<Student> arrayList1 = new ArrayList<>();
arrayList1.add(s1);
arrayList1.add(s2);
arrayList1.add(s3);
Iterator<Student> it = arrayList1.iterator();
while(it.hasNext()){
    Student s = it.next();
    System.out.println(s+" ");
}

Set集合

set子接口:无序、无下标、元素不能重复
方法:全部继承于Collection

 //创建set对象
Set<String> set = new HashSet<>();
//添加
set.add("华为");
set.add("小米");
set.add("三星");
set.add("OPPO");
System.out.println(set.size());
System.out.println(set);
//删除 没有下标,只能输入对象
set.remove("小米");
System.out.println(set);
//遍历
System.out.print("增强for循环:");
for(String s:set){
    System.out.print(s+" ");
}
System.out.println();
System.out.print("迭代器遍历:");
Iterator<String> it = set.iterator();
while(it.hasNext()){
    System.out.print(it.next()+" ");
}
//判断
System.out.println();
System.out.println(set.contains("OPPO"));
System.out.println(set.isEmpty());

在这里插入图片描述

Set实现类

1. HashSet 重点 存储结构:哈希表

  • 基于HashCode计算元素存放位置
  • 当存入元素的哈希值相同时,会调用equals确认,如结果为true,则拒绝后者引入
HashSet<String> hashSet = new HashSet<>();
//添加
hashSet.add("中国");
hashSet.add("英国");
hashSet.add("美国");
hashSet.add("法国");
System.out.println(hashSet.size());
System.out.println(hashSet);
//删除
hashSet.remove("美国");
System.out.println(hashSet);
//遍历
System.out.print("使用增强for:");
for (String s : hashSet) {
   System.out.print(s+" ");
}
System.out.println();
System.out.print("使用迭代器:");
Iterator<String> it = hashSet.iterator();
while(it.hasNext()){
   String s = it.next();
   System.out.print(s+" ");
}
//判断
System.out.println();
System.out.println(hashSet.contains("日本"));
System.out.println(hashSet.isEmpty());

在这里插入图片描述

package Set;

public class Person {
    private String name;
    private int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    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 "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
Person p1 = new Person("小李", 21);
Person p2 = new Person("小王", 21);
Person p3 = new Person("小张", 21);
HashSet<Person> hashSet = new HashSet<>();
//添加
hashSet.add(p1);
hashSet.add(p2);
hashSet.add(p3);
hashSet.add(new Person("小张",21));
System.out.println(hashSet);

在这里插入图片描述

可以发现,当add一个p3名字年龄相同的对象时,也会添加成功,原因如下:
1.根据hashCode计算保存的值,如果值为空,则直接保存,如果不为空,则执行第2步
2.再执行equals方法,如果返回为true,则认为重复,否则,形成链表
所以如果想要上述行为不发生,需要重写hashCode方法和equals方法

@Override
public int hashCode() {
    int a = this.name.hashCode();
    int b = this.age;
    return a+b;
}

@Override
public boolean equals(Object obj) {
    if(this==obj)
        return true;
    if(obj==null)
        return false;
    if(obj instanceof  Person){
        Person person = (Person) obj;
        if(this.name.equals(person.getName())&&this.age==person.getAge())
            return true;
    }
    return false;
}

在这里插入图片描述

Person p1 = new Person("小李", 21);
Person p2 = new Person("小王", 21);
Person p3 = new Person("小张", 21);
HashSet<Person> hashSet = new HashSet<>();
//添加
hashSet.add(p1);
hashSet.add(p2);
hashSet.add(p3);
hashSet.add(new Person("小张",21));
System.out.println(hashSet);
//删除
hashSet.remove(new Person("小张",21));
System.out.println(hashSet);
//遍历
System.out.print("增强for:");
for (Person person : hashSet) {
   System.out.print(person+" ");
}
System.out.println();
System.out.print("iterator:");
Iterator<Person> it = hashSet.iterator();
while(it.hasNext()){
   Person p = it.next();
   System.out.print(p+" ");
}
//判断
System.out.println();
System.out.println(hashSet.contains(new Person("小李", 21)));
System.out.println(hashSet.isEmpty());

在这里插入图片描述

2. TreeSet 存储结构:红黑树

  • 基于排列顺序实现元素不重复
  • 实现了SortedSet接口,对集合元素自动排序
  • 元素对象的类型必须实现Comparable接口,指定排序规则
  • 通过compareTo方法确定是否有重复元素
Person p1 = new Person("小李", 21);
Person p2 = new Person("小王", 21);
Person p3 = new Person("小张", 21);
TreeSet<Person> treeSet= new  TreeSet<>();
treeSet.add(p1);
treeSet.add(p2);
treeSet.add(p3);
System.out.println(treeSet);

在这里插入图片描述

如果直接将对象添加到treeSet集合中,就会报错,原因是无法进行比较大小,需要重写比较规则,实现接口中的compareTo方法
即当return的值为0时,则认为是相同的,不能添加

public class Person implements Comparable<Person>{
	@Override
   public int compareTo(Person o) {
       int a = this.name.compareTo(o.getName());
       int b = this.age-o.getAge();
       return a==0? b:a;
   }
}
Person p1 = new Person("hello", 21);
Person p2 = new Person("xyz", 21);
Person p3 = new Person("xyz", 18);
Person p4 = new Person("abc",20);
TreeSet<Person> treeSet= new  TreeSet<>();
treeSet.add(p1);
treeSet.add(p2);
treeSet.add(p3);
treeSet.add(p4);
System.out.println(treeSet);
treeSet.remove(p2);
System.out.println(treeSet);
for(Person p:treeSet){
   System.out.print(p+" ");
}
System.out.println();
Iterator<Person> it = treeSet.iterator();
while(it.hasNext()){
   Person p = it.next();
   System.out.print(p+" ");
}
System.out.println();
System.out.println(treeSet.contains(p3));
System.out.println(treeSet.isEmpty());

在这里插入图片描述

另:也可以直接用Compartor比较器重写比较方法(TreeSet构造方法中存在参数为Compartor)
在这里插入图片描述

下面方法为先比较年龄,年龄相同比较名字

TreeSet<Person> treeSet = new TreeSet<>(new Comparator<Person>() {
    @Override
    public int compare(Person o1, Person o2) {
       int a = o1.getAge()-o2.getAge();
       int b = o1.getName().compareTo(o2.getName());
       return a==0?b:a;
     }
 });
Person p1 = new Person("hello", 21);
Person p2 = new Person("xyz", 21);
Person p3 = new Person("xyz", 18);
Person p4 = new Person("abc",20);
treeSet.add(p1);
treeSet.add(p2);
treeSet.add(p3);
treeSet.add(p4);
System.out.println(treeSet);

在这里插入图片描述

小案例
实现集合里的字符串按长度由短变长排序,若长度相同,则按字母顺序

TreeSet<String> treeSet = new TreeSet<>(new Comparator<String>() {
   @Override
   public int compare(String o1, String o2) {
        int a = o1.length()-o2.length();
        int b = o1.compareTo(o2);
        return a==0?b:a;
     }
 });
String s1 = "hello world";
String s2 = "hello";
String s3 = "lisi";
String s4 = "helloworld";
String s5= "zhang";
treeSet.add(s1);
treeSet.add(s2);
treeSet.add(s3);
treeSet.add(s4);
treeSet.add(s5);
System.out.println(treeSet);

在这里插入图片描述

Map集合

在这里插入图片描述

特点:

  1. 用于存储任意键值对 key-value
  2. 键是无序、无下标、不重复的 使用相同的key不同的value会对之前的value进行更改
  3. 值是无序、无下标、可重复的
方法说明
V put(K key,V value)将对象存入到集合,key重复则覆盖原值
Object get(Object key)根据键获取对应的值
Set keySet()返回所有的Key
Collection values返回包含所有值的Collection集合
Set<Map.Entry<K,V>>键值匹配的Set集合
Map<String,String> map = new HashMap<>();
map.put("CN","中国");
map.put("US","美国");
map.put("UK","英国");
System.out.println(map.size());
System.out.println(map);
//  map.remove("CN");
//  System.out.println(map);
//遍历  keySet
Set<String> strings = map.keySet();
for (String string : strings) {
    System.out.println(string+" "+map.get(string));
}
System.out.println("============");
//遍历 entrySet
Set<Map.Entry<String, String>> entries = map.entrySet();
for (Map.Entry<String, String> entry : entries) {
    System.out.println(entry.getKey()+" "+entry.getValue());
}
System.out.println("================");
System.out.println(map.containsKey("UN"));
System.out.println(map.containsValue("日本"));

在这里插入图片描述

Map集合的实现类

1. HashMap
存储结构:哈希表 红黑树
JDK1.2版本,线程不安全,运行效率快,允许使用null作为key或者value
默认初始容量为16、默认加载因子为0.75,如当前容量为100,当装满75时进行扩容

与HashSet类似,这里用key的HashCode与equals进行比较
总结:

  1. HashMap刚创建时,table是null,为了节省空间,当添加第一个元素后,table调整为16

  2. 当元素个数大于阈值(16*0.75=12)时,会进行扩容,扩容后的大小为原来的2倍

  3. jdk1.8 当每个链表的长度>8时,且数组元素个数≥64时,调整为红黑树,提高效率

  4. jdk1.8 当链表长度<6时,调整为链表

  5. jdk1.8之前是链表是头插法,jdk1.8之后是尾插法

  6. HashSet用的就是HashMap的key

Student s1 = new Student("小明", 123);
Student s2 = new Student("小张", 456);
Student s3 = new Student("小红", 789);
HashMap<Student,String> hashMap= new HashMap<>();
hashMap.put(s1,"南京");
// hashMap.put(s2,"北京");
hashMap.put(s3,"上海");
hashMap.put(new Student("小红",189),"上海");
System.out.println(hashMap);

在这里插入图片描述

重写HashCode和equals方法

@Override
public int hashCode() {
    int a = this.name.hashCode();
    int b = this.Sno;
    return a+b;
}

@Override
public boolean equals(Object obj) {
    if(this==obj)
        return true;
    if(obj==null)
        return false;
    if(obj instanceof Student){
        Student s = (Student) obj;
        if(this.name.equals(((Student) obj).getName())&&this.Sno==((Student) obj).getSno())
            return true;
    }
    return false;
}
Set<Student> set= hashMap.keySet();
for(Student s:set){
    System.out.println(s+" "+hashMap.get(s));
}
 System.out.println();
 Set<Map.Entry<Student,String>> entrySet = hashMap.entrySet();
 for(Map.Entry<Student,String> s:entrySet){
     System.out.println(s.getKey()+" "+s.getValue());
 }
 System.out.println(hashMap.isEmpty());
 System.out.println(hashMap.containsKey(s2));
 System.out.println(hashMap.containsValue("杭州"));

在这里插入图片描述

2. Hashtable
JDK1.0版本,线程安全,运行效率慢;不允许null作为key或者value。
3. Properties
HashTable的子类,要求Key和Value都是String,通常用于配置文件的读取。
4. TreeMap
实现了SortedMap接口,可以对key进行自动排序。
TreeSet用的就是TreeMap的key

Student s1 = new Student("小明", 102);
Student s2 = new Student("小张", 101);
Student s3 = new Student("小红", 103);
TreeMap<Student,String> treeMap = new TreeMap<>();
treeMap.put(s1,"南京");
treeMap.put(s2,"北京");
treeMap.put(s3,"上海");
System.out.println(treeMap);

在这里插入图片描述

此时跟但是TreeSet一样产生类转换异常,虽然重写了HashCode和equals方法,但是这两方法对他没用,所以得继承Comparable重写compareTo方法。因为学号是唯一标识,所以只需比较学号即可。

@Override
public int compareTo(Student o) {
    int a = this.Sno-o.getSno();
    return a;
}

在这里插入图片描述

Student s1 = new Student("小明", 102);
Student s2 = new Student("小张", 101);
Student s3 = new Student("小红", 103);
TreeMap<Student,String> treeMap = new TreeMap<>();
treeMap.put(s1,"南京");
treeMap.put(s2,"北京");
treeMap.put(s3,"上海");
System.out.println(treeMap);
// treeMap.remove(s1);
// System.out.println(treeMap);
Set<Student> set =treeMap.keySet();
for(Student s:set){
    System.out.println(s+"  "+treeMap.get(s));
}
System.out.println("================");
Set<Map.Entry<Student,String>> entries = treeMap.entrySet();
for(Map.Entry<Student,String> map:entries){
    System.out.println(map.getKey()+" "+map.getValue());
}
System.out.println(treeMap.containsKey(s2));
System.out.println(treeMap.containsValue("山东"));

在这里插入图片描述

Collections工具类

方法说明
public static void reverse(List<?> list)反转集合中的元素顺序
public static void shuffle(List<?> list)随机重置集合元素的顺序
public static void sort(List<?> list)升序排列(元素类型必须实现Comparable接口)
List<Integer> list = new ArrayList<>();
list.add(2);
list.add(50);
list.add(23);
list.add(41);
list.add(15);
System.out.println("排序之前:"+list);
//sort 排序
Collections.sort(list);
System.out.println("排序之后:"+list);
//binarySearch 二分查找 查找之前元素必须为有序的
System.out.println(Collections.binarySearch(list, 41));
//copy复制 要求目的集合必须与原集合大小一致
List<Integer> list1 = new ArrayList<>();
for(int i =0;i<list.size();i++){
    list1.add(0);
}
Collections.copy(list1,list);
System.out.println("目的集合:"+list1);
//reverse 反转
Collections.reverse(list);
System.out.println("反转之后:"+list);
//shuffle 打乱
Collections.shuffle(list);
System.out.println("打乱之后:"+list);

在这里插入图片描述

补充知识:

//集合转为数组
Integer[] arr = list.toArray(new Integer[0]);
System.out.println("集合转为数组:"+Arrays.toString(arr));
//数组转为集合 在这里转成的集合是不能进行增加删除操作的,因为数组是一个固定的
String[] arr1 = {"张三","李四","王五"};
List<String> list2 = Arrays.asList(arr1);
System.out.println("字符串数组转为集合:"+list2);
//当基本类型要转为集合时,需要使用包装类,即不能使用 int[] arr2 ={1,5,4,7,9};
Integer[] arr2 ={1,5,4,7,9};
List<Integer> integers = Arrays.asList(arr2);
System.out.println("数字转为集合:"+integers);

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值