java集合框架

java集合框架

1.集合

1.1、什么是集合

概念

对象的容器,实现类对对象常用的操作

和数组的区别

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

位置

java.util.*;

1.2、Collection体系

在这里插入图片描述

1.2.1、Collection父接口

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

创建集合:Collection collection=new ArrayList();

常用方法:

1.添加元素 collection.add();

2.删除元素 collection.remove(),collection.clear()

3.遍历元素:

​ 1.使用增强for(因为无下标)

​ for(Object object : collection){ }

​ 2.使用迭代器

//haNext(); 有没有下一个元素
//next(); 获取下一个元素
//remove(); 删除当前元素
Iterator it = collection.iterator();
while(it.hasNext()){
  String object = (String)it.next(); //强转
  // 可以使用it.remove(); 进行移除元素
  // collection.remove(); 不能用collection其他方法 会报并发修改异常
}

4.判断 collection.contains(); collection.isEmpty();

代码测试1:

package com.me;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/**
 * Collection接口的使用
 * (1)添加元素
 * (2)删除元素
 * (3)遍历元素
 * (4)判断
 */
public class CollectionTest {
    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("榴莲");
//        System.out.println("删除之后:"+collection.size());

        //(3)遍历元素(重点)
        //3.1使用增强for
        System.out.println("----------------3.1使用增强for--------------");
        for (Object object : collection) {
            System.out.println(object);
        }

        //3.2使用迭代器(迭代器专门用来遍历集合的一种方式)
        //haNext(); 有没有下一个元素
        //next(); 获取下一个元素
        //remove(); 删除当前元素
        System.out.println("----------------3.2使用迭代器--------------");
        Iterator iterator = collection.iterator();
        while (iterator.hasNext()){
            String object = (String) iterator.next();
            System.out.println(object);  //强转
            //collection.remove(object);//不能用collection其他方法 会报并发修改异常
            //iterator.remove();//进行移除元素
        }
        System.out.println("元素个数:"+collection.size());

        //(4)判断
        System.out.println(collection.contains("西瓜"));
        System.out.println(collection.isEmpty());
    }
}

代码测试2:

package com.me;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
 * Collection的使用:保存学生信息
 */
public class CollectionTest2 {
    public static void main(String[] args) {
        //新建collection对象
        Collection collection=new ArrayList();
        Student s1=new Student("张三",10);
        Student s2=new Student("李四",18);
        Student s3=new Student("王五",20);
        //1,添加数据
        collection.add(s1);
        collection.add(s2);
        collection.add(s3);
        collection.add(s3);
        System.out.println("元素个数:"+collection.size());
        System.out.println(collection.toString());

        //2.删除
//        collection.remove(s1);
//        collection.remove(new Student("王五",22));
//        System.out.println("删除之后:"+collection.size());
//        System.out.println(collection.toString());

//        collection.clear(); //清除(只是删除了集合中的地址)

        //3.遍历
        //3.1增强for
        for (Object object : collection) {
            Student s= (Student) object;
            System.out.println(s.toString());
        }

        //3.2迭代器:hasNext() ; next() ; remove();  迭代过程中不能使用collection的删除方法
        Iterator iterator = collection.iterator();
        while (iterator.hasNext()){
            Student  s = (Student) iterator.next();
            System.out.println(s.toString());
        }

        //4.判断
        System.out.println(collection.contains(s1));
        System.out.println(collection.contains(new Student("张三",10)));
    }
}

Student类

package com.me;

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

1.2.2、List子接口

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

创建集合对象:List list=new ArrayList();

常用方法:

  1. 添加元素list.add();,会对基本类型进行自动装箱

  2. 删除元素,可以使用索引 list.remove(0)

    当删除数字与索引矛盾时对数字强转,或者new一个对象

    list.remove((Object) 10)list.remove(new Integer(10))

  3. 遍历

    1. 使用for遍历

      for (int i = 0; i < list.size(); i++) {
          System.out.println(list.get(i)); //返回object
      }
      
    2. 使用增强for

      for (Object object : list) {
          System.out.println(object);
      }
      
    3. 使用迭代器

      while (iterator.hasNext()){
          //可以使用it.remove(); 进行移除元素
        	// collection.remove(); 不能用collection其他方法 会报并发修改异常
          System.out.println(iterator.next());
      }
      
    4. 使用迭代器列表

      ListIterator li = list.listIterator();
      while(li.hasNext()){
        System.out.println(li.nextIndex() + ":" + li.next()); //从前往后遍历
      }
      
      while(li.hasPrevious()){
        System.out.println(li.previousIndex() + ":" + li.previous()); //从后往前遍历
      }
      
  4. 获取元素位置list.indexOf()

  5. 返回子集合sublist(x,y);左闭右开

    List subList = list.subList(1, 3); 返回索引 1、2的元素

测试代码1:

package com.me;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

/**
 * List子接口的使用
 * 特点:1.有序 有下标
 *      2.可以重复
 */
public class ListTest {
    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遍历
        System.out.println("=============3.1使用for遍历=================");
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i)); //返回object
        }

        //3.2使用增强for
        System.out.println("=============3.2使用增强for===================");
        for (Object object : list) {
            System.out.println(object);
        }

        //3.3使用迭代器
        Iterator iterator = list.iterator();
        System.out.println("============3.3使用迭代器=====================");
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }

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

        System.out.println("=========3.4使用列表迭代器从后往前===================");
        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("华为"));
    }
}

测试代码2:

package com.me;

import java.util.ArrayList;
import java.util.List;

/**
 * List的使用
 */
public class ListTest2 {
    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(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());
    }
}

1.2.3、List实现类

  • ArrayList 【重点】

    • DEFAULT_CAPACITY = 10 默认容量

      ​ 注意:如果没有向集合中添加任何元素时,容量为0;添加一个元素之后,容量10 ;每次扩容大小是原来的1.5倍

    • elementDat 存放元素的数组

    • size 实际的元素个数

    • add() 添加元素

      
      public boolean add(E e) {
          ensureCapacityInternal(size + 1);  // Increments modCount!!
          elementData[size++] = e;
          return true;
      }
      
      
      private static int calculateCapacity(Object[] elementData, int minCapacity) {
          if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
              return Math.max(DEFAULT_CAPACITY, minCapacity);
          }
          return minCapacity;
      }
      
      
      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);
      }
      
    • 数组结构实现,必须要连续空间,查询快、增删慢
    • jdk1.2版本,运行效率块、线程不安全

测试代码:

package com.me.List;

import com.me.Student;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;

/**
 * ArrayList的使用
 * 存储接口:数组,查找遍历速度快,增删慢
 */
public class ArrayListTest {
    public static void main(String[] args) {
        //创建集合  size 0  容量 0   扩容原来的1.5倍
        ArrayList arrayList=new ArrayList<>();
        //1.添加元素
        Student s1=new Student("刘德华",20);
        Student s2=new Student("郭富城",22);
        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);
//        arrayList.remove(new Student("刘德华",20));  //删不掉,可以重写equals方法
//        System.out.println("删除之后元素个数:"+arrayList.size());
//        System.out.println(arrayList.toString());



        //3.遍历元素
        //3.1使用迭代器
        System.out.println("============3.1使用迭代器================");
        Iterator it = arrayList.iterator();
        while (it.hasNext()){
            Student s = (Student) it.next();
            System.out.println(s.toString());
        }
        //3.2列表迭代器
        ListIterator lit = arrayList.listIterator();
        System.out.println("===============3.2列表迭代器(从前往后)============================");
        while (lit.hasNext()){
            Student s = (Student) lit.next();
            System.out.println(s.toString());
        }

        System.out.println("===============3.2列表迭代器(从后往前)============================");
        while (lit.hasPrevious()){
            Student s = (Student) lit.previous();
            System.out.println(s.toString());
        }

        //4判断
        System.out.println(arrayList.contains(s1));
        System.out.println(arrayList.contains(new Student("刘德华",20)));  //重写了equals方法
        System.out.println(arrayList.isEmpty());

        //5.查找
        System.out.println(arrayList.indexOf(s2));
    }
}
  • Vector
    • 数组结构实现,查询快、增删慢
    • jdk1.0版本,运行效率慢、线程安全

测试代码:

package com.me.List;

import java.util.Enumeration;
import java.util.Vector;

/**
 * 演示Vector集合的使用
 * 存储结构:数组
 */
public class VectorTest {
    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()){
            Object o = en.nextElement();
            System.out.println(o.toString());
        }

        //4.判断
        System.out.println(vector.contains("西瓜"));
        System.out.println(vector.isEmpty());

        //5.Vector其他的方法
        //firstElement、lastElement、elementAt
    }
}
  • LinkedList
    • 双向链表结构实现,无需连续空间,增删快,查询慢
package com.me.List;
import com.me.Student;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;

/**
 * LinkList的使用
 * 存储结构:双向链表
 */
public class LinkListTest {
    public static void main(String[] args) {
        //创建集合
        LinkedList linkedList=new LinkedList<>();
        //1.添加元素
        Student s1=new Student("刘德华",20);
        Student s2=new Student("郭富城",22);
        Student s3=new Student("梁朝伟",18);
        linkedList.add(s1);
        linkedList.add(s2);
        linkedList.add(s3);
        linkedList.add(s3);
        System.out.println("元素个数:"+linkedList.size());
        System.out.println(linkedList.toString());

        //2.删除
//        linkedList.remove(s1);
//        linkedList.remove(new Student("刘德华",20)); //可以删除,因为重写了equals方法
//        System.out.println("删除之后:"+linkedList.size());

        //3.遍历
        //3.1for遍历
        System.out.println("================for=================");
        for (int i = 0; i < linkedList.size(); i++) {
            System.out.println(linkedList.get(i));
        }

        //3.2增强for
        System.out.println("=============增强for====================");
        for (Object object : linkedList) {
            Student s= (Student) object;
            System.out.println(s);
        }

        //3.3使用迭代器
        System.out.println("==============使用迭代器===================");
        Iterator iterator = linkedList.iterator();
        while (iterator.hasNext()){
            Student s= (Student) iterator.next();
            System.out.println(s);
        }

        //3.4使用列表迭代器
        System.out.println("==============使用列表迭代器===================");
        ListIterator listIterator = linkedList.listIterator();
        while (listIterator.hasNext()){
            Student s= (Student) listIterator.next();
            System.out.println(s);
        }

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

        //5获取位置
        System.out.println(linkedList.indexOf(s1));
        System.out.println(linkedList.indexOf(s2));
    }
}

1.3、泛型

  • 本质是参数化类型,把类型作为参数传递
  • 常见形式有泛型类、泛型接口、泛型方法
  • 语法< T,…>成为类型占位符,表示一种引用类型,可以写多个逗号隔开
  • 好处 1. 提高代码重用性 2. 防止类型转换异常,提高代码安全性

1.3.1、泛型类

// 写一个泛型类
public class MyGeneric<T>{
  //使用泛型T
  //1 创建变量
  T t;
  //2 泛型作为方法的参数
  public void show(T t){
    sout(t);
  }
  //3 泛型作为方法的返回值
  public T getT(){
    return t;
  }
}
// 使用泛型类
public class TestGeneric{
  public static void main(String[] args){
    //使用泛型类创建对象
    // 注意: 1. 泛型只能使用引用类型
    //			 2. 不用泛型类型对象之间不能相互赋值
    MyGeneric<String> myGeneric = new MyGeneric<String>();
    myGeneric.t = "hello";
    myGeneric.show("hello world!");
    String string = myGeneric.getT();
    
    MyGeneric<Integer> myGeneric2 = new MyGeneric<Integer>();
    myGeneric2.t = 100;
    myGeneric2.show(200);
    Integer integer = myGeneric2.getT();
    
  }
}

1.3.2、泛型接口

语法:接口名

注意:不能泛型静态常量

package com.me.generic;

/**
 * 泛型接口
 * 语法:接口名<T>
 * 注意:不能泛型静态常量
 */
public interface MyGenericInterface<T> {
    String name="张三";

    T server(T t);
}
package com.me.generic;

public class MyGenericInterfaceImpl implements MyGenericInterface<String> {
    @Override
    public String server(String t) {
        System.out.println(t);
        return t;
    }
}
package com.me.generic;

public class MyGenericInterfaceImpl2<T> implements MyGenericInterface<T> {
    @Override
    public T server(T t) {
        System.out.println(t);
        return t;
    }
}

测试:

package com.me.generic;

public class TestGeneric {
    public static void main(String[] args) {
        //使用泛型类创建对象
        //注意:1.泛型只能使用引用类型
        //2.不用泛型类型对象之间不能相互赋值
        MyGeneric<String> myGeneric=new MyGeneric<>();
        myGeneric.t="hello";
        myGeneric.show("hello world!");
        String s = myGeneric.getT();
        System.out.println(s);

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


        //泛型接口
        MyGenericInterfaceImpl impl = new MyGenericInterfaceImpl();
        impl.server("hello");

        MyGenericInterfaceImpl2<Integer> impl2 = new MyGenericInterfaceImpl2<>();
        impl2.server(1000);


        //泛型方法
        MyGenericMethod myGenericMethod = new MyGenericMethod();
        myGenericMethod.show("字符串"); //自动类型为字符串
        myGenericMethod.show(2000);
        myGenericMethod.show(3.14);

    }
}

1.3.3、泛型方法

语法: 返回值类型

package com.me.generic;

/**
 * 泛型方法
 * 语法:<T>返回值类型
 */
public class MyGenericMethod {
    //泛型方法
    public <T> T show(T t){
        System.out.println("泛型方法:"+t);
        return t;
    }
}

1.3.4、泛型集合

概念:参数化类型、类型安全的集合,强制集合元素的类型必须一致

特点:

  • 编译时即可检查,而非运行时抛出异常
  • 访问时,不必类型转换(拆箱)
  • 不同泛型之间应用不能相互赋值,泛型不存在多态

1.4、Set集合

特点:无序、无下标、元素不可重复

方法:全部继承自Collection中的方法

增、删、遍历、判断与collection一致

1.4.1、HashSet

存储结构:哈希表(数组+链表+红黑树)

存储过程(重复依据)

  1. 根据hashCode计算保存的位置,如果位置为空,直接保存,若不为空,进行第二步
  2. 再执行equals方法,如果equals为true,则认为是重复,否则形成链表

特点:

  • 基于HashCode计算元素存放位置
    • 利用31这个质数,减少散列冲突
      • 31提高执行效率 31 * i = (i << 5) - i 转为移位操作
    • 当存入元素的哈希码相同时,会调用equals进行确认,如果结果为true,则拒绝后者存入

新建集合 HashSet<String> hashSet = new HashSet<String>();

添加元素 hashSet.add( );

删除元素 hashSet.remove( );

遍历操作

  1. 增强for for( type type : hashSet)

  2. 迭代器 Iterator<String> it = hashSet.iterator( );

判断 hashSet.contains( ); hashSet.isEmpty();

测试代码1:

package com.me.set;

import java.util.HashSet;
import java.util.Iterator;

/**
 * HashSet集合的使用
 * 存储结构:哈希表(数组+链表+红黑树)
 */
public class HashSetTest {
    public static void main(String[] args) {
        //新建集合
        HashSet<String> hashSet=new HashSet<String>();
        //1.添加元素
        hashSet.add("刘德华");
        hashSet.add("梁朝伟");
        hashSet.add("林志玲");
        hashSet.add("周润发");
        hashSet.add("刘德华");
        System.out.println("元素的个数:"+hashSet.size());
        System.out.println(hashSet.toString());

        //2.删除数据
        hashSet.remove("刘德华");
        System.out.println("删除之后:"+hashSet.size());
        System.out.println(hashSet.toString());


        //3.遍历
        //3.1增强for
        System.out.println("=========使用增强for===========");
        for (String s : hashSet) {
            System.out.println(s);
        }

        //3.2使用迭代器
        System.out.println("===========使用迭代器============");
        Iterator<String> iterator = hashSet.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }

        //4.判断
        System.out.println(hashSet.contains("梁朝伟"));
        System.out.println(hashSet.isEmpty());
    }
}

测试代码2:

package com.me.set;
import com.me.Person;
import java.util.HashSet;
import java.util.Iterator;

/**
 * HashSet的使用
 * 存储结构:哈希表(数组+链表+红黑树)
 * 存储过程(重复的依据)
 * (1)根据hashcode计算保存的位置,如果此位置,则直接保存,如果不为空执行第二步
 * (2)再执行equals方法,如果equals方法为true,则认为重复,否则,形成链表
 *
 */
public class HashSetTest2 {
    public static void main(String[] args) {
        //创建集合
        HashSet<Person> persons=new HashSet<>();
        Person p1=new Person("刘德华",20);
        Person p2=new Person("林志玲",22);
        Person p3=new Person("梁朝伟",25);
        //1.添加数据
        persons.add(p1);
        persons.add(p2);
        persons.add(p3);
//        persons.add(p3); //重复
        persons.add(new Person("梁朝伟",25));//需要重写hashcode和equals方法
        System.out.println("元素的个数:"+persons.size());
        System.out.println(persons.toString());

        //2.删除操作
//        persons.remove(p1);
//        persons.remove(new Person("刘德华",20));//重写了hashcode和equals方法后可以删除,不重写则不能删除
//        System.out.println("删除之后:"+persons.size());

        //3.遍历

        //3.1增强for
        System.out.println("==========3.1增强for===============");
        for (Person person : persons) {
            System.out.println(person.toString());
        }
        //3.2使用迭代器
        System.out.println("==========3.2使用迭代器===========");
        Iterator<Person> iterator = persons.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }

        //4.判断
        System.out.println(persons.contains(p1));
        System.out.println(persons.contains(new Person("刘德华",20))); //返回了true,因为重写了hashcode和equals方法
        System.out.println(persons.isEmpty());

    }
}

附Person类

package com.me.set;

import java.util.Objects;

/**
 * 人类
 */
public class Person implements Comparable<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 int hashCode() {
//        int n1=this.name.hashCode();
//        int n2=this.age;
//        return n1+n2;
//    }
//
//    @Override
//    public boolean equals(Object obj) {
//        if (this==obj){
//            return true;
//        }
//        if (obj==null){
//            return false;
//        }
//        if (obj instanceof Person){
//            Person p= (Person) obj;
//            if (this.name.equals(p.getName()) && this.age==p.getAge()){
//                return true;
//            }
//        }
//        return false;
//    }


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

    @Override
    public int hashCode() {
        return Objects.hash(getName(), getAge());
    }

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

    /*
        public static int hashCode(Object a[]) {
        if (a == null)
            return 0;

        int result = 1;

        for (Object element : a)
        (1)31是一个质数,减少散列冲突
        (2) 31提高执行效率  31*i=(i<<5)-i
            result = 31 * result + (element == null ? 0 : element.hashCode());

        return result;
    }
     */
}

1.4.2、TreeSet

特点

  • 基于排列顺序实现元素不重复
  • 实现SortedSet接口,对集合元素自动排序
  • 元素对象的类型必须实现Comparable接口,指定排序规则
  • 通过CompareTo方法确定是否为重复元素

存储结构:红黑树

创建集合 TreeSet<String> treeSet = new TreeSet<>()

添加元素 treeSet.add();

删除元素 treeSet.remove();

遍历 1. 增强for 2. 迭代器

判断 treeSet.contains();

补充:TreeSet集合的使用

Comparator 实现定制比较(比较器)

Comparable 可比较的

测试代码1:

package com.me.set;

import java.util.Iterator;
import java.util.TreeSet;

/**
 * TreeSet的使用
 * 存储结构:红黑树
 */
public class TreeSetTest {
    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
        System.out.println("==========3.1增强for==================");
        for (String s : treeSet) {
            System.out.println(s);
        }
        //3.2使用迭代器
        System.out.println("============3.2使用迭代器=============");
        Iterator<String> iterator = treeSet.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }

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

测试代码2:

package com.me.set;

import com.me.Person;

import java.util.Iterator;
import java.util.TreeSet;

/**
 * 使用treeSet保存数据
 * 存储结构:红黑树
 * 要求:元素必须要实现Comparable接口,compareTo()方法返回值为0,认为是重复元素
 */
public class TreeSetTest2 {
    public static void main(String[] args) {
        //创建集合
        TreeSet<Person> persons=new TreeSet<>();
        Person p1=new Person("xyz",20);
        Person p2=new Person("hello",22);
        Person p3=new Person("zhangsan",25);
        Person p4=new Person("zhangsan",20);

        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(p1);
//        persons.remove(new Person("zhangsan",25)); //可以删除
//        System.out.println("删除之后:"+persons.size());

        //3.遍历
        //3.1使用增强for
        System.out.println("=============3.1增强for================");
        for (Person person : persons) {
            System.out.println(person.toString());
        }

        //3.2使用迭代器
        System.out.println("==============3.2使用迭代器=============");
        Iterator<Person> iterator = persons.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }

        //4.判断
        System.out.println(persons.contains(p1));
        System.out.println(persons.contains(new Person("zhangsan",25)));
        System.out.println(persons.isEmpty());
    }
}

测试代码3:

package com.me.set;

import com.me.Person;

import java.util.Comparator;
import java.util.TreeSet;

/**
 * TreeSet集合的使用
 * Comparator:实现定制比较(比较器)
 * Comparable:可比较的
 */
public class TreeSetTest3 {
    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;
            }
        });

        Person p1=new Person("xyz",20);
        Person p2=new Person("hello",22);
        Person p3=new Person("zhangsan",25);
        Person p4=new Person("zhangsan",18);
        persons.add(p1);
        persons.add(p2);
        persons.add(p3);
        persons.add(p4);
        System.out.println(persons.toString());
    }
}

测试代码4:

package com.me.set;

import java.util.Comparator;
import java.util.TreeSet;

/**
 * 要求:使用TreeSet集合实现字符串按照长度进行排序
 * helloworld zhang lisi wangwu beijing xian nanjing
 * Comparator接口实现定制比较
 */
public class TreeSetTest4 {
    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("helloworld");
        treeSet.add("pingguo");
        treeSet.add("lisi");
        treeSet.add("zhangsan");
        treeSet.add("beijing");
        treeSet.add("cat");
        treeSet.add("nanjing");
        treeSet.add("xian");

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

1.5、Map

Map接口的特点

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

方法:

1. V put(K key, V value) 将对象存到集合中,关联键值
2. Object get(Object key) 根据键获得对应的值
3. Set<K> 返回所有的Key
4. Collection<V> values() 返回包含所有值的Collection集合
5. Set<Map.Entry<K, V>> 键值匹配的Set集合

1.5.1、Map接口的使用

package com.me.map;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * Map接口的使用
 * 特点:(1)存储键值对 (2)键不能重复,值可以重复  (3)无序
 */
public class MapTest {
    public static void main(String[] args) {
        //创建map集合
        Map<String,String> map=new HashMap<>();
        //1添加元素
        map.put("CN","中国");
        map.put("UK","英国");
        map.put("USA","美国");
        System.out.println("元素个数:"+map.size());
        System.out.println(map.toString());

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

        //3.遍历
        //3.1 使用KeySet
        System.out.println("===============3.1 使用KeySet==================");
        Set<String> keySet = map.keySet();
        for (String key : map.keySet()) {
            System.out.println(key+"-----"+map.get(key));
        }

        //3.2 使用entrySet方法
        System.out.println("==================3.2 使用entrySet方法======================");
        Set<Map.Entry<String, String>> entries = map.entrySet();
        for (Map.Entry<String, String> entry : map.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key+"-----"+value);
        }
        

        //4.判断
        System.out.println(map.containsKey("CN"));
        System.out.println(map.containsValue("泰国"));
    }
}

1.5.2、HashMap

JDK1.2版本,线程不安全,运行效率快,允许用null作为key或者value

存储结构:哈希表(数组+链表+红黑树)

使用key可使hashcode和equals作为重复

增、删、遍历、判断与上述一致

源码分析总结:

  1. HashMap刚创建时,table是null,节省空间,当添加第一个元素时,table容量调整为16
  2. 当元素个数大于阈值(16*0.75 = 12)时,会进行扩容,扩容后的大小为原来的两倍,目的是减少调整元素的个数
  3. jdk1.8 当每个链表长度 >8 ,并且数组元素个数 ≥64时,会调整成红黑树,目的是提高效率
  4. jdk1.8 当链表长度 <6 时 调整成链表
  5. jdk1.8 以前,链表时头插入,之后为尾插入
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // hashMap初始容量大小
static final int MAXIMUM_CAPACITY = 1 << 30;//hashMap的数组最大容量
static final float DEFAULT_LOAD_FACTOR = 0.75f;//默认加载因子
static final int TREEIFY_THRESHOLD = 8;//jdk1.8 当每个链表长度 >8 ,会调整成红黑树
static final int UNTREEIFY_THRESHOLD = 6;//jdk1.8 当链表长度 <6 时 调整成链表
static final int MIN_TREEIFY_CAPACITY = 64;//jdk1.8 当每个链表长度 >8 ,并且数组元素个数 ≥64时,会调整成红黑树
transient Node<K,V>[] table; //哈希表中的数组
size;//元素个数

测试代码:

package com.me.map;
import com.me.Person;
import java.util.HashMap;
import java.util.Map;

/**
 * HashMap集合的使用
 * 存储结构:哈希表(数组+链表+红黑树)
 * 使用key的hashcode和equals作为重复
 */
public class HashMapTest {
    public static void main(String[] args) {
        //创建集合
        HashMap<Student,String> students=new HashMap<Student,String>();
        //刚创建hashmap之后没有添加元素table=null,size=0  目的是节省空间
        //添加元素
        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,"南京");
        students.put(new Student("沙和尚",102),"杭州"); //为了加不进来,可以重写hashcode和equals方法
        System.out.println("元素的个数:"+students.size());
        System.out.println(students.toString());

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

        //3.遍历
        //3.1使用keySet()
        System.out.println("==============3.1使用keySet()================");
        for (Student key : students.keySet()) {
            System.out.println(key.toString()+"-------"+students.get(key));
        }

        //3.2使用entrySet()
        System.out.println("==============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.containsKey(new Student("孙悟空",100)));
        System.out.println(students.containsValue("杭州"));
        System.out.println(students.isEmpty());
    }
}

1.5.3、HashTable

JDK1.0版本,线程安全呢,允许效率慢,不允许null为key或者value

1.5.4、Properties

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

1.5.5、TreeMap

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

测试代码:

package com.me.map;

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

/**
 * TreeMap的使用
 * 存储结构:红黑树
 */
public class TreeMapTest {
    public static void main(String[] args) {
        //创建集合(定制比较)
        TreeMap<Student, String> treeMap = new TreeMap<Student,String>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return 0;
            }
        });
        Student s1=new Student("孙悟空",100);
        Student s2=new Student("猪八戒",101);
        Student s3=new Student("沙和尚",102);
        //1.添加元素
        treeMap.put(s1,"北京");
        treeMap.put(s2,"上海");
        treeMap.put(s3,"深圳");
        treeMap.put(new Student("沙和尚",102),"南京");
        System.out.println("元素个数:"+treeMap.size());
        System.out.println(treeMap.toString());  //需要实现Comparable接口

        //2.删除
//        treeMap.remove(s3);
//        treeMap.remove("猪八戒",101);//可以删除
//        System.out.println("删除之后:"+treeMap.size());

        //3遍历
        //3.1使用keySet
        System.out.println("=============3.1使用keySet============");
        for (Student key : treeMap.keySet()) {
            System.out.println(key+"------"+treeMap.get(key));
        }

        //3.2使用entrySet
        System.out.println("============3.2使用entrySet==========");
        for (Map.Entry<Student, String> entry : treeMap.entrySet()) {
            System.out.println(entry.getKey()+"-----"+entry.getValue());
        }

        //4判断
        System.out.println(treeMap.containsKey(s1));
        System.out.println(treeMap.containsKey(new Student("沙和尚",102)));
        System.out.println(treeMap.isEmpty());
    }
}

1.6、Collections工具类

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

直接二分查找int i = Collections.binarySearch(list, x); 成功返回索引

其他方法 : copy复制、reverse反转、shuffle打乱

package com.me.Collections工具类;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * Collections工具类的使用
 */
public class CollectionsTest {
    public static void main(String[] args) {
        List<Integer> list=new ArrayList<>();
        list.add(20);
        list.add(5);
        list.add(12);
        list.add(30);
        list.add(6);
        System.out.println("排序之前:"+list.toString());
        //sort排序
        Collections.sort(list);//默认是升序
        System.out.println("排序之后"+list.toString());

        //binarySearch 二分查找
        int i = Collections.binarySearch(list, 132);
        System.out.println(i);

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


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

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

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


        //数组转为list
        System.out.println("=============数组转为list==========");
        String[] names={"张三","李四","王五"};
        List<String> stringList = Arrays.asList(names); //这个集合是一个受限集合,不能添加和删除
        System.out.println(stringList.toString());

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

1.7、总结

集合的概念

对象的容器,和数组相似,定义了对多个对象进行操作的常用方法

List集合

有序、有下标、元素可以重复、(ArrayList、LinkList、Vector)

Set集合

无序、无下标、元素不可重复。(HashSet,TreeSet)

Map集合

存储一对数据,无序,无下标,键不可重复,值可以重复(HashMap,HashTable,TreeMap)

Collections

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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值