集合框架笔记

集合

一:集合概念

对象的容器,实现了对对象常用的操作,类似数组功能。

二:集合和数组的区别

(1)数组长度固定,集合长度不固定。

(2)数组可以存储基本类型和引用类型,集合只能引用类型。

Collection体系集合

Collection父接口

特点

代表一组任意的类型的对象,无序、无下标、不能重复。

方法

  • 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()//将此集合转换成数组。

迭代器(专门用来遍历集合的一种方式)

Iterator接口提供了很多对集合元素进行迭代的方法。每一个集合类都包括了可以返回迭代器实例的迭代方法。

hasNext()判断有没有下一个元素。

next()获取下一个元素。

remove()删除当前元素。

Collection的使用(1)

/**
 * Collection接口的使用
 * (1)添加元素
 * (2)删除元素
 * (3)遍历元素
 * (4)判断
 */

public class Collection1 {
    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)遍历元素【重点】
        //3.1使用增强for
        for (Object object : collection) {
            System.out.println(object);
        }
        //3.2使用迭代器(迭代器专门用来遍历集合的一种方式)
        //hasNext();有没有下一个元素
        //next();获取下一个元素
        //remove();删除当前元素
        Iterator it = collection.iterator();
        while (it.hasNext()) {
            String s = (String) it.next();
            System.out.println(s);
            //collection.remove(s);  不能使用collection删除方法,并发修改异常
            it.remove();
        }
        System.out.println("元素个数:" + collection.size());

        //(4)判断
        System.out.println(collection.contains("香蕉"));//判断是否有"香蕉"
        System.out.println(collection.isEmpty());//判断是否为空
    }
}

Collection的使用(2)

/**
 * Collection的使用:保存学生信息
 */
public class Collection2 {
    public static void main(String[] args) {
        //新建Collection对象
        Collection collection = new ArrayList();
        Student s1 = new Student("张三", 20);
        Student s2 = new Student("李四", 21);
        Student s3 = new Student("王五", 22);
        
        //1.添加数据
        collection.add(s1);
        collection.add(s2);
        collection.add(s3);
        System.out.println("元素个数:" + collection.size());
        System.out.println(collection.toString());
        
        //2.删除数据
//        collection.remove(s3);
//        collection.clear();//清空
//        System.out.println("元素个数:" + collection.size());
        
        //3.遍历数据
        //3.1增强for
        for (Object object : collection) {
            Student s = (Student) object;
            System.out.println(s.toString());
        }
        //3.2迭代器:hasNext();  next();  remove();迭代过程中不能使用collection的删除方法
        Iterator it = collection.iterator();
        while (it.hasNext()) {
            Student s = (Student) it.next();
            System.out.println(s.toString());
        }
        
        //4.判断
        System.out.println(collection.contains(s1));
        System.out.println(collection.isEmpty());
    }
}

/**
 * 学生类
 */
public class Student {
    private String name;
    private int age;

    public Student() {
    }

    public Student(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 "Student [" +
                "name='" + name + '\'' +
                ", age=" + age +
                ']';
    }
}

List集合

List子接口

特点

有序、有下标、元素可以重复。

方法

  • 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之间的集合元素。

列表迭代器

hasNext()判断有没有下一个元素。

hasPrevious()判断有没有上一个元素。

next()获取下一个元素。

nextIndex()返回next调用的元素下标。

previous()获取上一个元素。

previousIndex()返回previous调用的元素下标。

remove()删除当前元素。

List接口的使用(1)

/**
 * List子接口的使用
 * 特点:1 有序 有下标  2 可以重复
 */
public class Demo01 {
    public static void main(String[] args) {
        //先创建集合对象
        List list = new ArrayList<>();

        //1添加元素
        list.add("苹果");
        list.add("小米");
        list.add(0, "华为");
        System.out.println("元素个数:" + list.size());
        System.out.println(list.toString());

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

        //3遍历
        //3.1使用for遍历
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
        //3.2使用增强for
        for (Object object : list) {
            System.out.println(object);
        }
        //3.3使用迭代器
        Iterator it = list.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }
        //3.4使用列表迭代器,与Iterator的区别,ListIterator可以向前或向后遍历,添加、删除、修改元素。
        ListIterator lit = list.listIterator();
        //3.4.1使用列表迭代器从前往后进行遍历
        while (lit.hasNext()) {
            System.out.println(lit.nextIndex() + ":" + lit.next());
        }
        //3.4.2使用列表迭代器从后往前进行遍历
        while (lit.hasPrevious()) {
            System.out.println(lit.previousIndex() + ":" + lit.previous());
        }

        //4判断
        System.out.println(list.contains("苹果"));
        System.out.println(list.isEmpty());

        //5获取位置
        System.out.println(list.indexOf("华为"));
    }
}

List接口的使用(2)

/**
 * List的使用
 */
public class Demo02 {
    public static void main(String[] args) {
        //创建集合
        List list = new ArrayList<>();
        //1添加数字数据(自动装箱)
        list.add(20);
        list.add(30);
        list.add(40);
        list.add(50);
        list.add(60);
        System.out.println("元素个数:" + list.size());
        System.out.println(list.toString());
        
        //2删除操作
        //list.remove(0);
        //list.remove(list.indexOf(20));
        //list.remove((Object) 20);
        //list.remove(new Integer(20));
        System.out.println("元素个数:" + list.size());
        System.out.println(list.toString());
        
        //3补充方法subList:返回子集合,左闭右开
        List subList = list.subList(1, 3);
        System.out.println(subList.toString());
    }
}

List常见实现类

  • ArrayList【重点】:

    • 数组结构实现,查询快、增删慢。

    • JDK1.2版本,运行效率快、线程不安全。

    • 源码分析:DEFAULT_CAPACITY=10;默认容量。

      注意:如果没有向集合中添加任何元素时,容量0,添加一个元素之后 容量10。

      ​ 每次扩容大小是原来的1.5倍。

      elementData 存放元素的数组。

      size 实际元素个数。

      add()添加元素。

          public boolean add(E e) {
              ensureCapacityInternal(size + 1);  // Increments modCount!!
              elementData[size++] = e;
              return true;
          }
      
          private void ensureCapacityInternal(int minCapacity) {
              ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
          }
      
          private void ensureExplicitCapacity(int minCapacity) {
              modCount++;
      
              // overflow-conscious code
              if (minCapacity - elementData.length > 0)
                  grow(minCapacity);
          }
      
          private void grow(int minCapacity) {
              // overflow-conscious code
              int oldCapacity = elementData.length;
              int newCapacity = oldCapacity + (oldCapacity >> 1);
              if (newCapacity - minCapacity < 0)
                  newCapacity = minCapacity;
              if (newCapacity - MAX_ARRAY_SIZE > 0)
                  newCapacity = hugeCapacity(minCapacity);
              // minCapacity is usually close to size, so this is a win:
              elementData = Arrays.copyOf(elementData, newCapacity);
          }
      
  • Vertor:

    • 数组结构实现,查询快、增删慢。

    • JDK1.0版本,运行效率慢、线程安全。

  • Linked List:

    • 链表结构实现,增删快、查询慢。

    • 源码分析:

      int size:集合的大小。

      Node first;链表的头节点。

      Node last;链表的尾节点。

          private void linkFirst(E e) {
              final Node<E> f = first;
              final Node<E> newNode = new Node<>(null, e, f);
              first = newNode;
              if (f == null)
                  last = newNode;
              else
                  f.prev = newNode;
              size++;
              modCount++;
          }
      
          private static class Node<E> {
              E item;
              Node<E> next;
              Node<E> prev;
      
              Node(Node<E> prev, E element, Node<E> next) {
                  this.item = element;
                  this.next = next;
                  this.prev = prev;
              }
          }
      

ArrayList的使用

/**
 * ArrayList的使用
 * 存储结构:数组,查找遍历速度快,增删慢
 */
public class Demo03 {
    public static void main(String[] args) {
        //创建集合
        ArrayList arrayList = new ArrayList();

        //1添加元素
        Student s1 = new Student("刘德华", 22);
        Student s2 = new Student("郭富城", 21);
        Student s3 = new Student("周杰伦", 18);
        arrayList.add(s1);
        arrayList.add(s2);
        arrayList.add(s3);
        System.out.println("元素个数:" + arrayList.size());
        System.out.println(arrayList.toString());

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

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

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

        //5查找
        System.out.println(arrayList.indexOf(s1));
    }
}

Vector的使用

/**
 * Vector集合的使用
 * 存储结构:数组
 */
public class Demo04 {
    public static void main(String[] args) {
        //创建集合
        Vector vector = new Vector<>();

        //1添加元素
        vector.add("草莓");
        vector.add("苹果");
        vector.add("香蕉");
        System.out.println("元素个数:" + vector.size());

        //2删除元素
//        vector.remove(0);
//        vector.remove("西瓜");
//        vector.clear();

        //3遍历元素
        //使用枚举器
        Enumeration en = vector.elements();
        while (en.hasMoreElements()) {
            String o = (String) en.nextElement();
            System.out.println(o);
        }

        //4判断
        System.out.println(vector.contains("草莓"));
        System.out.println(vector.isEmpty());

        //5vector其他方法
        //firstElement、lastElement、elementAt();
    }
}

LinkedList的使用

/**
 * LinkedList的使用
 * 存储结构:双向列表
 */
public class Demo05 {
    public static void main(String[] args) {
        //创建集合
        LinkedList linkedList = new LinkedList<>();

        //1添加元素
        Student s1 = new Student("刘德华", 22);
        Student s2 = new Student("郭富城", 21);
        Student s3 = new Student("周杰伦", 18);
        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());
//        linkedList.clear();

        //3遍历元素
        //3.1for遍历
        for (int i = 0; i < linkedList.size(); i++) {
            System.out.println(linkedList.get(i));
        }
        //3.2增强for
        for (Object object : linkedList) {
            Student s = (Student) object;
            System.out.println(s.toString());
        }
        //3.3使用迭代器
        Iterator it = linkedList.iterator();
        while (it.hasNext()) {
            Student s = (Student) it.next();
            System.out.println(s.toString());
        }
        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(s2));
    }
}

泛型(Generic)

  • Java泛型是JDK1.5中引入的一个新特性,其本质是参数化类型,把类型作为参数传递。

  • 常见形式有泛型类、泛型接口、泛型方法。

  • 语法:<T…> T称为类型占位符,表示一种引用类型。

  • 好处:(1)提高代码的重用性。

    ​ (2)防止类型转换异常,提高代码的安全性。

泛型类

/**
 * 泛型类
 * 语法:类名<T>
 * T是类型占位符,表示一种引用类型,如果编写多个使用逗号隔开
 */
public class MyGeneric<T> {
    //使用泛型T
    //1创建变量
    T t;

    //2泛型作为方法参数
    public void show(T t) {
        System.out.println(t);
    }

    //3泛型作为方法的返回值
    public T getT() {
        return t;
    }
}
public class TestGeneric {
  public static void main(String[] args) {
      //使用泛型类创建对象
      //注意:1泛型只能使用引用类型。2不同泛型对象之间不能相互赋值。
      MyGeneric<String> myGeneric = new MyGeneric<>();
      myGeneric.t = "hello";
      myGeneric.show("大家好,加油!");
      String string = myGeneric.getT();
      System.out.println(string);

      MyGeneric<Integer> myGeneric2 = new MyGeneric<>();
      myGeneric2.t = 100;
      myGeneric2.show(200);
      Integer integer = myGeneric2.getT();
      System.out.println(integer);
  }
}

泛型接口

/**
 * 泛型接口
 * 语法:接口名<T>
 * 注意:不能使用泛型创建静态常量
 *
 * @param <T>
 */
public interface MyInterface<T> {
    String name = "张三";

    T Server(T t);
}
public class MyInterfaceImpl implements MyInterface<String>{

    @Override
    public String Server(String t) {
        System.out.println(t);
        return t;
    }
}
public class MyInterfaceImpl2<T> implements MyInterface<T> {

    @Override
    public T Server(T t) {
        System.out.println(t);
        return t;
    }
}
        MyInterfaceImpl impl=new MyInterfaceImpl();
        impl.Server("xxxxxx");

        MyInterfaceImpl2<Integer> impl2=new MyInterfaceImpl2<>();
        impl2.Server(1000);

泛型方法

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

public class MyGenericMethod {
    //泛型方法
    public <T> T show(T t) {
        System.out.println("泛型方法" + t);
        return t;
    }
}
        MyGenericMethod myGenericMethod = new MyGenericMethod();
        myGenericMethod.show("加油!");
        myGenericMethod.show(200);
        myGenericMethod.show(3.14);

泛型集合

  • 概率:参数化类型、类型安全的集合,强制集合元素的类型必须一致。
  • 特点:
    • 编译时即可检查,而非运行时抛出异常。
    • 访问时,不必类型转换(拆箱)。
    • 不同泛型之间引用不能相互赋值,泛型不存在多态。
public class Demo01 {
    public static void main(String[] args) {
        ArrayList<String> arrayList = new ArrayList<>();
        arrayList.add("xxx");
        arrayList.add("zzz");

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

        ArrayList<Student> arrayList2 = new ArrayList<>();
        Student s1 = new Student("刘德华", 22);
        Student s2 = new Student("郭富城", 21);
        Student s3 = new Student("周杰伦", 18);
        arrayList2.add(s1);
        arrayList2.add(s2);
        arrayList2.add(s3);

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

Set集合

Set子接口

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

Set实现类

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

Set接口的使用

/**
 * 测试Set接口的使用
 * 特点:(1)无序、没有下标 (2)不能重复
 */
public class Demo01 {
    public static void main(String[] args) {
        //创建集合
        Set<String> set = new HashSet<>();

        //1添加数据
        set.add("小米");
        set.add("苹果");
        set.add("华为");
        System.out.println("元素个数:" + set.size());
        System.out.println(set.toString());

        //2删除数据
//        set.remove("苹果");
//        System.out.println(set.toString());

        //3遍历数据【重点】
        //3.1增强for
        for (String string : set) {
            System.out.println(string);
        }
        //3.2使用迭代器
        Iterator it = set.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }
        
        //4判断
        System.out.println(set.contains("华为"));
        System.out.println(set.isEmpty());
    }
}

HashSet的使用(1)

/**
 * HashSet集合的使用
 * 存储结构:哈希表(数组+链表+红黑树)
 */
public class Demo02 {
    public static void main(String[] args) {
        //创建集合
        HashSet<String> hashSet = new HashSet<>();

        //1添加元素
        hashSet.add("周杰伦");
        hashSet.add("陈冠希");
        hashSet.add("周慧敏");
        hashSet.add("王祖贤");
        System.out.println("元素个数:" + hashSet.size());
        System.out.println(hashSet.toString());

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

        //3遍历元素
        //3.1增强for
        for (String string : hashSet) {
            System.out.println(string);
        }
        //3.2迭代器
        Iterator<String> it = hashSet.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }
        
        //4判断
        System.out.println(hashSet.contains("王祖贤"));
        System.out.println(hashSet.isEmpty());
    }
}

HashSet的使用(2)

/**
 * 人类
 */
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 +
                '}';
    }

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

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}
/**
 * HashSet的使用
 * 存储结构:哈希表(数组+链表+红黑树)
 * 存储过程(重复依据)
 * (1)根据hashcode计算保存的位置,如果此位置为空,则直接保存,如果不为空执行第二步。
 * (2)再执行equals方法,如果equals方法为true,则认为是重复,否则,形成列表。
 */
public class Demo03 {
    public static void main(String[] args) {
        //创建集合
        HashSet<Person> hashSet=new HashSet<>();

        //1添加数据
        Person p1 = new Person("王祖贤",18);
        Person p2 = new Person("周慧敏",24);
        Person p3 = new Person("周杰伦",20);
        hashSet.add(p1);
        hashSet.add(p2);
        hashSet.add(p3);
        hashSet.add(new Person("周杰伦",20));
        System.out.println("元素个数:"+hashSet.size());
        System.out.println(hashSet.toString());

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

        //3遍历数据
        //3.1使用增强for
        for (Person person:hashSet) {
            System.out.println(person);
        }
        //3.2迭代器
        Iterator<Person> it= hashSet.iterator();
        while (it.hasNext()){
            System.out.println(it.next());
        }

        //4判断
        System.out.println(hashSet.contains(new Person("周杰伦",20)));
        System.out.println(hashSet.isEmpty());
    }
}

TreeSet的使用(1)

/**
 * TreeSet的使用
 * 存储结构:红黑树
 */
public class Demo04 {
    public static void main(String[] args) {
        //创建集合
        TreeSet<String> treeSet = new TreeSet<>();

        //1添加元素
        treeSet.add("xyz");
        treeSet.add("abc");
        treeSet.add("hello");
        treeSet.add("xyz");//重复不再添加
        System.out.println("元素个数:" + treeSet.size());
        System.out.println(treeSet.toString());

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

        //3遍历元素
        //3.1增强for
        for (String string : treeSet) {
            System.out.println(string);
        }
        //3.2迭代器
        Iterator<String> it = treeSet.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }

        //4判断
        System.out.println(treeSet.contains("xyz"));
        System.out.println(treeSet.isEmpty());
    }
}

TreeSet的使用(2)

public class Person implements Comparable<Person> {    
    //先按姓名比,然后再按年龄比
    @Override
    public int compareTo(Person o) {
        int n1 = this.getName().compareTo(o.getName());
        int n2 = this.age - o.getAge();

        return n1==0?n2:n1;
    }
}
/**
 * 使用TreeSet保存数据
 * 存储结构:红黑树
 * 要求:元素必须要实现Comparable接口,compareTo()方法返回值为0,认为是重复元素
 */
public class Demo05 {
    public static void main(String[] args) {
        //创建集合
        TreeSet<Person> treeSet = new TreeSet<>();

        //1添加数据
        Person p1 = new Person("xyz", 18);
        Person p2 = new Person("hello", 24);
        Person p3 = new Person("abc", 20);
        Person p4 = new Person("abc", 22);
        treeSet.add(p1);
        treeSet.add(p2);
        treeSet.add(p3);
        treeSet.add(p4);
        System.out.println("元素个数:" + treeSet.size());
        System.out.println(treeSet.toString());

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

        //3遍历数据
        //3.1增强for
        for (Person person : treeSet) {
            System.out.println(person);
        }
        //3.2迭代器
        Iterator<Person> it = treeSet.iterator();
        while (it.hasNext()){
            System.out.println(it.next());
        }

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

Comparator接口

/**
 * TreeSet集合的使用
 * Comparator:实现定制比较(比较器)
 * Comparable:可比较的
 */
public class Demo06 {
    public static void main(String[] args) {
        //创建集合,并指定比较规则
        TreeSet<Person> treeSet=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;
            }
        });

        Person p1 = new Person("xyz", 18);
        Person p2 = new Person("hello", 24);
        Person p3 = new Person("abc", 20);
        Person p4 = new Person("cba", 20);

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

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

    }
}

TreeSet案例

/**
 * 要求:使用TreeSet集合实现字符串按照长度进行排序
 * Comparator接口实现定制比较
 */
public class Demo07 {
    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("one");
        treeSet.add("lisi");
        treeSet.add("cat");
        treeSet.add("zhangsan");
        treeSet.add("chongqing");
        System.out.println(treeSet.toString());
    }
}

Map集合

Map父接口

特点

存储一对数据(Key-Value),无序、无下标,键不可重复,值可重复。

方法

  • V put(K key,V value)//将对象存入到集合中,关键键值。key重复则覆盖原值。
  • Object get(Object key)//根据键获取对应的值。
  • keySet //返回所有的key。
  • Collection values()//返回包含所有值的Collection集合。
  • entrySet<Map.Entry<K,V>> //键值匹配的Set集合。

entrySet效率高于keySet。

Map接口使用

/**
 * Map接口的使用
 * 特点:(1)存储键值对(2)键不能重复,值可以重复(3)无序
 */
public class Demo01 {
    public static void main(String[] args) {
        //创建Map集合
        Map<String, String> map = new HashMap<>();
        //1添加元素
        map.put("cn", "中国");
        map.put("uk", "英国");
        map.put("usa", "美国");
//        map.put("cn","zhongguo");后添加不会增加元素个数,但会替换value值。

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

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

        //3遍历元素
        //3.1使用keySet()
        //Set<String> keyset = map.keySet();
        for (String key : map.keySet()) {
            System.out.println(key + "-" + map.get(key));
        }
        //3.2使用entrySet()  Map.Entry 映射对(键值对)
        //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("cn"));
        System.out.println(map.containsValue("泰国"));
    }
}

HashMap使用

  • HashMap【重点】

    • JDK1.2版本,线程不安全,运行效率快;允许用null作为key或是value。
  • Hashtable:

    • JDK1.0版本,线程安全,运行效率慢;不允许用null作为key或是value。
  • Properties:

    • Hashtable的子类,要求key和value都是String。通常用于配置文件的读取。
  • TreeMap:

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

    HashMap():构造一个具有默认初始容量(16)和默认加载因子(0.75)的空HashMap。

package Map学习;

public class Student implements Comparable<Student>{
    private String name;
    private int stuNo;

    public Student() {
    }

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

    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 int compareTo(Student o) {
        int n1=this.stuNo-o.getStuNo();
        return n1;
    }
}
/**
 * HashMap集合的使用
 * 存储结构:哈希表(数组+链表+红黑树)
 * 使用key可hashcode和equals作为重复
 */
public class Demo02 {
    public static void main(String[] args) {
        //创建集合
        //刚创建hashmap之后没有添加元素table=null  size=0  目的节省空间
        HashMap<Student, String> students = new HashMap<Student, String>();

        //1添加元素
        Student s1 = new Student("孙悟空", 100);
        Student s2 = new Student("猪八戒", 101);
        Student s3 = new Student("沙和尚", 102);
        students.put(s1, "重庆");
        students.put(s2, "上海");
        students.put(s3, "北京");
        //students.put(s3,"南京");
        System.out.println("元素个数:" + students.size());
        System.out.println(students.toString());

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

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

        //4判断
        System.out.println(students.containsKey(s1));
        System.out.println(students.containsValue("重庆"));
    }
}

HashMap源码分析

源码分析

1 static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;//hashMap初始容量大小
2 static final int MAXIMUM_CAPACITY = 1 << 30;//hashMap的数组最大容量
3 static final float DEFAULT_LOAD_FACTOR = 0.75f;//默认加载因子
4 static final int TREEIFY_THRESHOLD = 8;//jdk1.8 当链表长度大于8时,调整成红黑树
5 static final int UNTREEIFY_THRESHOLD = 6;//jdk1.8 当链表长度小于6时,调整成链表
6 static final int MIN_TREEIFY_CAPACITY = 64;//jdk1.8 当链表长度大于8时,并且集合元素个数大于等于64时,调整成红黑树
7 transient Node<K,V>[] table;//哈希表中的数组
8 size;//元素个数

无参构造

public HashMap(){
    this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
}

put方法

public V put(K key,V value){
    return putVal(hash(key),key,value,false.true);
}

总结

(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以后时是尾插入

TreeMap的使用

/**
 * TreeMap的使用
 * 存储结构:红黑树
 */
public class Demo03 {
    public static void main(String[] args) {
        //创建集合
        TreeMap<Student,String> treeMap=new TreeMap<Student,String>();

        //1添加元素
        Student s1 = new Student("孙悟空", 100);
        Student s2 = new Student("猪八戒", 101);
        Student s3 = new Student("沙和尚", 102);
        treeMap.put(s1, "重庆");
        treeMap.put(s2, "上海");
        treeMap.put(s3, "北京");
        System.out.println("元素个数:"+treeMap.size());
        System.out.println(treeMap.toString());

        //2删除
//        treeMap.remove(s3);
//        System.out.println(treeMap.size());

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

        //4判断
        System.out.println(treeMap.containsKey(s1));
    }
}

Collections工具类

  • 概念:集合工具类,定义了除了存取以外的集合常用方法。
  • 方法:
    • public static void reverse(List<?> list) //反转集合中元素的顺序
    • public static void shuffle(List<?> list) //随机重置集合元素的顺序
    • public static void sort(List list) //升序排序(元素类型必须实现Comparable接口)

集合总结

  • 集合的概念:
    • 对象的容器,和数组类似,定义了对多个对象进行操作的常用方法。
  • List集合:
    • 有序、有下标、元素可以重复。(ArrayList、LinkenList、Vertor)
  • Set集合:
    • 无序、无下标、元素不可重复。(HashSet、TreeSet)
  • Map集合:
    • 存储一对数据,无序、无下标,键不可重复,值可重复。(HashMap、HashTable、TreeMap)
  • Collections:
    • 集合工具类,定义了除了存取以外的集合常用方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值