集合框架和泛型的学习(非常重要,day12)

集合框架 Collection和Map,泛型(Day12)

集合

  • 概念:对象的容器,定义了对多个对象进行操作的常用方法。可实现数组的功能。
  • 和数组的区别:1数组的长度固定 2集合的长度不固定
  • 区别:3数组可以存储基本类型和引用类型 4集合只能存储引用类型
  • 集合的位置 java.util.*

Collection体系集合

  • List接口:有序的,有下标,元素可重复
  • List接口的实现类有ArrayList(常用),LinkedList(常用),Vector(已经淘汰)
  • Set接口:无序的,无下标,元素不可重复

方法:

代码实现(重点关注迭代器iterator的使用):

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class Demo1 {
    public static void main(String[] args) {
        //创建集合
        Collection collection = new ArrayList();
        //1.添加元素
        collection.add("香蕉");
        collection.add("苹果");
        collection.add("西瓜");
        System.out.println("元素个数:"+collection.size());
        System.out.println(collection);

        //2.删除元素
        //collection.remove("香蕉");
        //collection.clear();//清除
        //System.out.println("删除之后:"+collection.size());

        //3.遍历元素(重点)
        System.out.println("==========================");
        //方法一:增强for
        for (Object object:collection) {
            System.out.println(object);
        }
        //方法二:使用迭代器(迭代器专门用来遍历集合的一种方式)
        //iterator3个方法
        //hasNext();有没有下一个元素
        //next();l获取下一个元素
        //remove();删除当前元素
        System.out.println("==========================");
        Iterator iterator = collection.iterator();
        while (iterator.hasNext()) {
            String s = (String) iterator.next();
            System.out.println(s);
            // collection.remove(s);//不允许使用collection删除会引发并发修改错误,只能使用以下方法移除
            //iterator.remove();
        }
        System.out.println("元素个数:"+collection.size());


        //4.判断
        System.out.println(collection.contains("香蕉"));
        System.out.println(collection.isEmpty());


    }
}

List接口

  • 特点:有序的,有下标,元素可重复

List接口实现类

  1. ArrayList(重点)

    ​ 数组的结构实现,查询快,增删慢

    ​ jdk1.2 ,运行效率快,线程不安全

  2. Vector

    ​ 数组的结构实现,查询快,增删慢

    ​ jdk1.0 ,运行效率慢,线程安全

  3. LinkedList(重点)

    ​ 链表的结构实现,查询快,增删慢

List接口代码使用

public class Demo3 {
    public static void main(String[] args) {
        //先创建一个集合对象
        List list = new ArrayList();
        //1.添加元素
        list.add("唱");
        list.add("跳");
        list.add(0,"打篮球");//下标为0,放在第一位
        System.out.println("元素个数:"+list.size());
        System.out.println(list.toString());

        //2.删除元素
//        list.remove("唱");
//        list.remove(1);
//        System.out.println("元素个数:"+list.size());
//        System.out.println(list.toString());


        //3.遍历
        //方法一:使用for遍历
        System.out.println("===========for遍历===============");
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }

        //方法二:使用增强for
        System.out.println("===========增强for===============");
        for (Object o:list) {
            System.out.println(o);
        }

        //方法三:使用迭代器
        System.out.println("===========迭代器===============");
        Iterator iterator = list.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
        //方法四:使用列表迭代器
        //和迭代器的区别:可以向前或向后遍历,添加、删除、修改元素
        System.out.println("===========列表迭代器===============");
        ListIterator lit = list.listIterator();

        System.out.println("===========列表迭代器从前往后===============");
        while (lit.hasNext()) {
            System.out.println(lit.nextIndex()+":"+lit.next());
        }

        System.out.println("===========列表迭代器从后往前===============");
        while (lit.hasPrevious()) {
            System.out.println(lit.previousIndex()+":"+lit.previous());
        }


        System.out.println("==========================");
        //4.判断
        System.out.println(list.contains("rap"));
        System.out.println(list.isEmpty());

        //5.获取位置
        System.out.println(list.indexOf(2));

    }

}

ArrayList

  • 默认容量 DEFAVLT_CAPACITY = 10
  • 存放元素的数组 elementDate
  • size 实际元素个数add()方法 如果没有向集合添加任何元素时容量为0 添加任一元素之后容量变为10 数组扩容时为原来的1.5倍

ArrayList类的使用代码

/**
 * ArrayList的使用
 * 特点:有序,有下标,可以重复
 * 存储结构:数组,查找遍历速度快,增删慢
 */

public class Demo5 {
    public static void main(String[] args) {
        //创建结合
        ArrayList arrayList = new ArrayList();

        //1.添加元素
        Student s1 = new Student("张三",20);
        Student s2 = new Student("李四",23);
        Student s3 = new Student("王五",19);
        arrayList.add(s1);
        arrayList.add(s2);
        arrayList.add(s3);
        System.out.println("元素个数:"+arrayList.size());
        System.out.println(arrayList.toString());

        //2.删除元素
//        arrayList.remove(0);
//        arrayList.remove(s2);
        arrayList.remove(new Student("ooof",12));//这样删除需要在Student中重写 equals(this == obj) 方法

        //3.遍历元素【重点】
        //使用迭代器
        System.out.println("========= 使用迭代器=========");
        Iterator it = arrayList.iterator();
        while (it.hasNext()) {
            Student s =(Student) it.next();
            System.out.println(s.toString());
        }
        //列表迭代器
        System.out.println("========= 列表迭代器=========");
        ListIterator lit = arrayList.listIterator();
        while (lit.hasNext()) {
            Student s =(Student) lit.next();
            System.out.println(s.toString());
        }


        System.out.println("========= 列表迭代器逆序=========");

        while (lit.hasPrevious()) {
            Student s =(Student) lit.previous();
            System.out.println(s.toString());
        }

        //4.判断
        System.out.println(arrayList.contains(new Student("王五",19)));
        System.out.println(arrayList.isEmpty());
        //5.查找
        System.out.println(arrayList.indexOf(new Student("王五",19)));
    }
}

Vector

  • 存储结构:数组
  • 使用很少
  • 创建集合 Vector vector = new Vector<>();
  • 增加(vector.add())、删除(vector.remove)、判断(vector.contains())同上
  • 遍历–枚举器遍历

枚举器遍历集合

Enumeration en = vector.elements();
while(en.hasMoreElements()){
  String s = (String)en.nextElement();
  sout(s);
}

LinkedList

  • int size :集合的大小
  • Node first :链表头节点
  • Node last :链表尾节点

LinkedList集合使用

/**
 *LinkedList的使用
 * 存储结构:双向链表
 * 可以重复添加
 */
public class LinkedListTest1 {
    public static void main(String[] args) {

        //创建集合
        LinkedList linkedList = new LinkedList<>();
        //1.添加元素
        Student s1 = new Student("张三",20);
        Student s2 = new Student("李四",23);
        Student s3 = new Student("王五",19);
        linkedList.add(s1);
        linkedList.add(s2);
        linkedList.add(s3);

        System.out.println("元素个数:"+linkedList.size());
        System.out.println(linkedList.toString());

        //2.删除
//        linkedList.remove(s1);
//        System.out.println("删除之后:"+linkedList.size());

        //3.遍历
        //for遍历
        System.out.println("========for=====");
        for (int i = 0; i < linkedList.size(); i++) {
            System.out.println(linkedList.get(i));
        }
        System.out.println("========增强for=====");
        for (Object object:linkedList) {
            Student s = (Student) object;
            System.out.println(s.toString());
        }
        //迭代器
        System.out.println("========迭代器=====");
        Iterator it = linkedList.iterator();
        while (it.hasNext()) {
            Student s =(Student) it.next();
            System.out.println(s.toString());
        }
        System.out.println("========列表迭代器=====");
        ListIterator lit = linkedList.listIterator();
        while (lit.hasNext()) {
            Student s =(Student) lit.next();
            System.out.println(s.toString());
        }

        //4.判断
        System.out.println(linkedList.contains(s1));
        System.out.println(linkedList.isEmpty());

        //5.获取
        System.out.println(linkedList.indexOf(s1));

    }
}

ArrayList与LinkedList的区别

  • ArrayList:数组,必须开辟连续空间,查询快,增删慢
  • LinkedList:双向链表,无需开辟连续空间,查询慢,增删快

泛型

  • Java泛型是JDK1.5中引入的一个新特性,其本质是參数化类型,把类型作为参数传递
  • 常见形式有泛型类、泛型接口、泛型方法
  • 好处:
    • (1)提高代码的重用性
    • (2)防止类型转换异常,提高代码的安全性

泛型类

/**
 * 泛型类
 * 语法:<T>
 * T表示类型占位符,表示一种引用类型,如果编写多个用逗号隔开
 * */
public class MyGeneric<T> {
    //使用泛型T
    //1.创建变量,不能new T()因为T数据类型不确定
    T t;

    //2.创建一个方法,作为方法的参数
    public void show(T t){
        System.out.println(t);
    }

    //3.使用泛型作为方法的返回值
    public T getT(){
        return t;
    }
}

泛型接口

/**
 *泛型接口
 * 语法:接口名<T>
 * 注意:不能使用泛型来创建静态常量
 */

public interface MyInterface<T> {
    String name = "张三";

    T server(T t);
}

泛型方法

/**
 *泛型方法
 * 语法:<T>返回值类型
 */


public class MyGenericMethod {
    //泛型方法
    public <T> void show(T t){
        System.out.println("泛型方法"+t);
    }
}

泛型集合

  • 概念:参数化类型、类型安全的集合,强制集合元素的类型必须一致。
  • 特点:
    • 编译时即可检查,而非逐行时抛出异常。
    • 访问时,不必类型转换(拆箱)。
    • 不同泛型之间引用不能相互赋值,泛型不存在多态。

代码演示

public class DemoCollect {
    public static void main(String[] args) {
        ArrayList<String> arrayList = new ArrayList<String>();
        arrayList.add("xxx");
        arrayList.add("yyy");
        //指定String类型一下两条数据就不能添加进去
//        arrayList.add(10);
//        arrayList.add(20);

        for (String str:arrayList) {
            System.out.println(str);
        }


        ArrayList<Student> arrayList2 = new ArrayList<Student>();
        Student s1 = new Student("张三",18);
        Student s2 = new Student("李四",19);
        Student s3 = new Student("王五",21);
        arrayList2.add(s1);
        arrayList2.add(s2);
        arrayList2.add(s3);

        Iterator<Student> iterator = arrayList2.iterator();
        while (iterator.hasNext()) {
            Student s = iterator.next();
            System.out.println(s.toString());
        }


    }
}

Set接口

  • 特点:无序的,无下标,元素不可重复
  • 方法:全部继承Collection中的方法

Set代码使用

/**
 * 测试Set接口的使用
 * 特点:无序,无下标,元素不可重复
 */


public class Demo1 {
    public static void main(String[] args) {
        //创建集合
        HashSet<String> set = new HashSet<>();
        //1.添加数据
        set.add("唱");
        set.add("跳");
        set.add("rap");
        //set.add("rap");重复添加不进去
        System.out.println("数据个数:"+set.size());
        System.out.println(set.toString());

        //2.删除
        set.remove("唱");
        System.out.println(set.toString());

        //3.遍历【重点】
        System.out.println("----增强for----");
        for (String str:set) {
            System.out.println(str);
        }
        System.out.println("----迭代器----");
        Iterator<String> iterator = set.iterator();
        while (iterator.hasNext()) {
            String s = iterator.next();
            System.out.println(s);
        }

        //4.判断
        System.out.println(set.contains("打篮球"));
        System.out.println(set.isEmpty());

        

    }
}

Set接口实现类

  • HashSet【重点】:
    1.基于HashCode实现元素不重复,通过HashCode计算元素存放位置
    2.当存入元素的哈希码相同时,会调用equalsi进行确认,如结果为true,则拒绝后者存入。
  • TreeSet:
    1.基于排列顺序实现元素不重复。
    2.实现了SortedSet接口,对集合元素自动排序
    3.元素对象的类型必须实现Comparable接口,指定排序规则
    4.通过CompareTo方法确定是否为重复元素

HashSet

代码演示

/***
 * HashSet集合的使用
 * 存储结构:哈希表(数组+链表+红黑树)
 * 存储过程:
 * (1)根据hashcode计算保存位置,如果位置为空,则直接保存,如果不为空,执行第二步
 * (2)再执行equals方法,如果equals方法为true,则认为是重复,否则形成链表
 */
public class Demo3 {
    public static void main(String[] args) {


    //新建集合
    HashSet<Person> persons = new HashSet<>();
    //1.添加元素
    Person p1 = new Person("乔纳森-乔斯达",20);
    Person p2 = new Person("乔瑟夫-乔斯达",19);
    Person p3 = new Person("空条承太郎",16);

    persons.add(p1);
    persons.add(p2);
    persons.add(p3);
    persons.add(new Person("空条承太郎",16));//重写hashCode()形成链表,再重写equals()就不能添加进来了

    System.out.println("元素个数:"+persons.size());
    System.out.println(persons.toString());

    //2.删除

//    persons.remove(p1);
//    persons.remove( new Person("乔纳森-乔斯达",20));//这时可以删除
//    System.out.println("删除之后:"+persons.toString());

    //3.遍历
        System.out.println("------for----");
        for (Person person:persons) {
            System.out.println(person.toString());
        }
        System.out.println("------迭代器----");
        Iterator<Person> iterator = persons.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }

    //4.判断
        System.out.println(persons.contains(p1));
        System.out.println(persons.isEmpty());

    }
}

person类

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

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", 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;
    }

    public Person() {
    }

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



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

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;

        if (o == null || getClass() != o.getClass()) return false;

        if(o instanceof Person){
        Person person = (Person) o;
        if(this.name.equals(person.getName())&&this.age == person.getAge()){
            return true;
        }
        }
        return false;
    }   
}

TreeSet

代码演示

/**
 * 使用TreeSet保存数据
 * 存储结构:红黑树
 * 要求:元素必须要实现Comparable接口,compareTo方法返回值为0,认为是重复元素
 */

public class Demo5 {
    public static void main(String[] args) {
        //创建集合
        TreeSet<Person> persons = new TreeSet<>();
        //1.添加元素
        Person p1 = new Person("7乔纳森-乔斯达",20);
        Person p2 = new Person("5乔瑟夫-乔斯达",19);
        Person p3 = new Person("3东方仗助",16);
        Person p4 = new Person("3东方仗助",17);

        //直接添加不能添加进去,因为没有比较规则,即没有实现Comparable接口,需要在Person类中实现
        persons.add(p1);
        persons.add(p2);
        persons.add(p3);
        persons.add(p4);

        System.out.println("元素个数:"+persons.size());
        System.out.println(persons.toString());

        //2.删除
        persons.remove(p4);
        System.out.println("元素个数:"+persons.size());

        //3.遍历
        Iterator<Person> iterator = persons.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }

        //4.判断
        System.out.println(persons.contains(p1));
    }
}

person类必须实现Comparable接口

public class Person implements Comparable<Person>{
    private String name;
    private int age;

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", 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;
    }

    public Person() {
    }

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



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

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;

        if (o == null || getClass() != o.getClass()) return false;

        if(o instanceof Person){
        Person person = (Person) o;
        if(this.name.equals(person.getName())&&this.age == person.getAge()){
            return true;
        }
        }
        return false;
    }

    //先按姓名比再按年龄比
    @Override
    public int compareTo(Person o) {
        int n1 = this.getName().compareTo(o.getName());
        int n2 = this.age - o.getAge();
        return n1==0?n2:n1;
    }
}

Comparator接口实现定制比较(不需要元素实现Comparable接口)

/**
 * 使用TreeSet保存数据
 * 存储结构:红黑树
 * Comparator:实现定制比较(比较器)
 */
public class Demo6 {
    public static void main(String[] args) {
        //创建集合,并指定比较规则(匿名内部类)
        TreeSet<Person> persons = new TreeSet<>(new Comparator<Person>() {
            @Override
            //先比较年龄再比较姓名
            public int compare(Person o1, Person o2) {
                int n1 = o1.getAge() - o2.getAge();
                int n2 = o1.getName().compareTo(o2.getName());
                return n1==0?n2:n1;
            }
        });

        //1.添加元素
        Person p1 = new Person("7乔纳森-乔斯达",20);
        Person p2 = new Person("5乔瑟夫-乔斯达",19);
        Person p3 = new Person("3东方仗助",16);
        Person p4 = new Person("4东方仗助",16);


        persons.add(p1);
        persons.add(p2);
        persons.add(p3);
        persons.add(p4);

        System.out.println(persons.toString());

    }
}

TreeSet案例

/**
 * 要求:使用TreeSet集合实现字符串按照长度进行排序
 * Comparator实现定制比较
 *
 */
public class Demo7 {
    public static void main(String[] args) {
        //创建集合并指定比较规则
        TreeSet<String> treeSet = new TreeSet<>(new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {

                int n1 = o1.length() - o2.length();
                int n2 = o1.compareTo(o2);

                return n1==0?n2:n1;
            }
        });
        //添加数据
        treeSet.add("hello");
        treeSet.add("hello,world");
        treeSet.add("dalian");
        treeSet.add("kunkun");
        treeSet.add("ikun");
        treeSet.add("cat");
        treeSet.add("beijing");

        System.out.println(treeSet.toString());

    }
}

Map集合框架

Map接口的特点:

  1. 用于存储任意键值对(Key-Value)
  2. 键:无序、无下标、不允许重复(唯一)
  3. 值:无序、无下标、允许重复

Map接口的使用

/**
 * Map接口的使用
 * 特点:(1)存储键值对(2)键不能重复,值可以重复(3)无序
 */
public class Demo1 {
    public static void main(String[] args) {
        //创建Map集合

        Map<String, String> map = new HashMap<>();
        //1.添加元素
        map.put("tom","汤姆");
        map.put("jack","杰克");
        map.put("rose","露丝");

        //map.put("rose","ooo");value会被替换

        System.out.println("元素个数:"+map.size());
        System.out.println(map.toString());

        //2.删除
//        map.remove("tom");
//        System.out.println("删除后元素个数:"+map.size());

        //3.遍历
        //3.1使用keySet()
        System.out.println("-------keySet()遍历---------");
        //Set<String> keySet = map.keySet();
        for(String key:map.keySet()){
            System.out.println(key+"---"+map.get(key));
        }
        //3.2使用entrySet()
        System.out.println("-------entrySet()遍历---------");
        //Set<Map.Entry<String, String>> entries = map.entrySet();
        for (Map.Entry<String, String> entry: map.entrySet()) {
            System.out.println(entry.getKey()+"---"+entry.getValue());

        }

        //4.判断
        System.out.println(map.containsKey("jack"));
        System.out.println(map.containsValue("杰克"));


    }
}

keySet()与entrySet()比较

Map接口的实现类

  • HashMap【重点】

    ​ 1.jdk1.2版本,线程不安全,运行效率快

    ​ 2.允许使用null作为key或value

    ​ 3.初始容量为16,加载因子为0.75

  • TreeMap【重点】

    ​ 1.实现了SortedMap接口(是Map的子接口),可以对key自动排序

  • Hashtable

    ​ 1.jdk1.0版本 ,线程安全,运行效率慢,不允许null作为key或者value

    ​ 2.子类Properties,要求key和value都是String,通常用于配置文件的读取

HashMap

HashMap的使用

/**
 * HashMap集合的使用
 * 存储结构:哈希表(数组+链表+红黑树)
 * 存储过程:
 *  (1)根据hashcode计算保存位置,如果位置为空,则直接保存,如果不为空,执行第二步
 *  (2)再执行equals方法,如果equals方法为true,则认为是重复,否则形成链表
 */

public class Demo2 {
    public static void main(String[] args) {
        //创建集合
        HashMap<Student,String> students = new HashMap<>();
        //1.添加元素
        Student s1 = new Student("张三",503);
        Student s2 = new Student("李四",509);
        Student s3 = new Student("王五",505);
        students.put(s1,"3班");
        students.put(s2,"7班");
        students.put(s3,"8班");
        //students.put(s3,"9班");键重复不能添加进去,但是值会覆盖
        students.put(new Student("张三",503),"3班");
        //会添加进去,new会在堆中新创建一个对象,如果要让它添加不进去,要在Student中重写hashcode和equals方法

        System.out.println("元素个数:"+students.size());
        System.out.println(students.toString());
        
        //2.删除
//        students.remove(s1);
//        System.out.println("删除之后:"+students.size());

        //3.遍历
        
        //keySet()
        System.out.println("-------keySet()遍历---------");
        for (Student key: students.keySet()) {
            System.out.println(key.toString()+"========="+students.get(key));
        }
        System.out.println("-------entrySet()遍历---------");
        for (Map.Entry<Student,String> entry: students.entrySet()) {
            System.out.println(entry.getKey()+"========="+entry.getValue());
        }
        
        //4.判断
        System.out.println(students.containsKey(s1));
        
    }
}

Student类:

public class Student {
    private String name;
    private int stuNo;

    public Student(String name, int stuNo) {
        this.name = name;
        this.stuNo = stuNo;
    }

    public Student() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getStuNo() {
        return stuNo;
    }

    public void setStuNo(int stuNo) {
        this.stuNo = stuNo;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", stuNo=" + stuNo +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return stuNo == student.stuNo && Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, stuNo);
    }
}

HashMap源码分析

static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;       // aka 16  HashMap初始容量大小

static final int MAXIMUM_CAPACITY = 1 << 30;              // HashMap数组的最大容量
 
static final float DEFAULT_LOAD_FACTOR = 0.75f;           //默认加载因子为0.75(到75%时扩容)

static final int TREEIFY_THRESHOLD = 8;                  //链表长度大于8时,调整成红黑树
 
static final int UNTREEIFY_THRESHOLD = 6;                //链表长度小于6时,调整成链表

static final int MIN_TREEIFY_CAPACITY = 64;             //链表长度大于8,并且集合元素个数大于等于64时,调整成红黑树

transient Node<K,V>[] table;                            //哈希表中的数组

transient int size;                                     //元素个数

HashMap源码

  • HashMap刚创建时,table是null,为了节省空间,当添加第一个元素时,table容量调整为16
  • 当元素个数大于阈值(16*0.75=12)时,会进行扩容,扩容后大小为原来的2倍,目的是减少调整元素的个数
  • jdk1.8,当每个链表长度大于8,并且数组元素个数大于等于64时,会调整为红黑树,日的提高执行效率
  • jdk1.8当链表长度小于6时,调整成链表
  • jdk1.8以前,链表是头插入,jdk1.8以后是尾插入

TreeMap

  • 实现了SortedMap接口(SortedMap是map的子接口),可以对key自动排序!
  • 存储结构:红黑树

TreeMap代码演示

package com.Map.TreeMapclass;

import com.Map.HashMapClass.Student;

import java.util.Comparator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

/***
 *
 * TreeMap使用
 * 存储结构:红黑树
 * @author lxt
 */
public class TreemapDemo01 {
    public static void main(String[] args) {
        //创建TreeMap集合
        TreeMap<Student,String> treeMap = new TreeMap<>(new Comparator<Student>() {
            @Override   //需要使用比较器,因为学生类不能直接转成Comparable。因为Treemap的存储结构是红黑树,需要制定一个规则进行比较!
            // 所以需要使用Comparator比较器,才可正常遍历
            public int compare(Student o1, Student o2) {
                int n = o1.getId()-o2.getId();   //使用学号进行比较
                return n;
            }
        });
        //1、添加元素

        Student s1 = new Student("张飞",101);
        Student s2 = new Student("关羽",102);
        Student s3 = new Student("曹操",103);
        Student s4 = new Student("小猴子",100);

        treeMap.put(s1,"广西");
        treeMap.put(s2,"玉林");
        treeMap.put(s3,"河池");
        treeMap.put(s4,"广东");

        System.out.println("元素个数:"+treeMap.size());
        System.out.println(treeMap.toString());

        //2、遍历元素
        //2.1使用KeySet来遍历元素
        System.out.println("-------------2.1使用KeySet来遍历元素---------------");
        for (Student sss: treeMap.keySet()
             ) {
            System.out.println(sss+treeMap.get(sss));
        }
        //2.2使用EnkeySet来遍历元素
        System.out.println("-------------2.2使用EnkeySet来遍历元素---------------");
        for (Map.Entry<Student,String> entry:treeMap.entrySet()
             ) {
            System.out.println(entry);
        }
        //3、删除元素
        treeMap.remove(s1);
        System.out.println("删除后元素个数:"+treeMap.size());
    }
}


总结:需要注意的就是,在使用Treemap集合的时候,由于Treemap的存储结构是红黑树,所以在使用Student类作为key遍历的时候,不能直接进行遍历,因为需要一个比较结果,所以必须要调用到比较器,也就是Comparator,否则会提示异常

Collections工具类

  • 概念:集合工具类,定义了除存取以外的集合常用方法
  • 方法:

演示代码

/**
 * Collections工具类的使用
 *
 */
public class Demo4 {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(20);
        list.add(77);
        list.add(23);
        list.add(89);
        list.add(12);

        //sort排序
        System.out.println("排序前:"+list.toString());
        Collections.sort(list);//升默认序
        System.out.println("排序后:"+list.toString());


        //binarySearch二分查找, 找到为下标,没找到为负数
        int i = Collections.binarySearch(list, 12);
        System.out.println(i);

        //copy复制
        List<Integer> dest = new ArrayList<>();
        for (int j = 0; j < list.size(); j++) {
            dest.add(0);
        }
        Collections.copy(dest,list);
        System.out.println(dest.toString());


        //reverse反转
        Collections.reverse(list);
        System.out.println("反转之后:"+list);

        //shuffle  打乱
        Collections.shuffle(list);
        System.out.println("打乱之后:"+list);


        //补充:list 转成数组
        System.out.println("=======list 转成数组========");
        Integer[] integers = list.toArray(new Integer[0]);
        System.out.println(integers.length);
        System.out.println(Arrays.toString(integers));


        //数组转成集合
        System.out.println("=======数组转成集合========");
        String[] names = {"小明","小红","小王"};
        //集合是一个受限集合,不能添加和删除
        List<String> list1 = Arrays.asList(names);
        System.out.println(list1);

        //把基本类型数组转成集合时,需要修改为包装类
        Integer[] nums = {100,200,300,400,500};
        List<Integer> integerList = Arrays.asList(nums);
        System.out.println(integerList);


    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值