Java集合

集合

集合概念:

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

Collection接口

在这里插入图片描述

1.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() //将此集合转换成数组
/**
 *Collection接口的使用
 * @author chengcheng
 * 1.添加元素
 * 2.删除元素
 * 3.遍历元素
 * 4.判断
 *
 */
public class Demo1 {
	public static void main(String[] args) {
		//创建集合
		Collection collection = new ArrayList();
		collection.add("西瓜");
		collection.add("苹果");
		collection.add("榴莲");
		System.out.println("元素个数:"+collection.size());
		System.out.println(collection); //[西瓜, 苹果, 榴莲]
		
		//删除元素
//		collection.remove("西瓜");
//		collection.clear();
//		System.out.println("删除后:"+collection.size());
		
		//遍历元素
		//collection没有下标,不能用for遍历,但能用增强for
		//(1)使用增强for
		for (Object object : collection) {
			System.out.println(object);
		}
		//(2)使用迭代器(专门用来遍历集合的一种方式)
		Iterator iterator = collection.iterator();
		while (iterator.hasNext()) {
			String s=(String) iterator.next();
			System.out.println(s);
//			collection.remove(s);   //迭代的过程不能使用Collection中的remove这个方法,
//			iterator.remove();  //只能使用迭代器的这个方法
		}
		System.out.println(collection.size());
		//判断
		System.out.println(collection.contains("西瓜"));
		System.out.println(collection.isEmpty());
	}
}

使用Collection存储对象

创建一个Student类

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

    public String getName() {
        return name;
    }

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

    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 +
                '}';
    }
}
public class Demo2 {
    public static void main(String[] args) {
        //新建Collection对象
        Collection collection=new ArrayList();
        Student s1=new Student("张三",20);
        Student s2=new Student("李四",22);
        Student s3=new Student("王五",21);
        //添加数据
        collection.add(s1);
        collection.add(s2);
        collection.add(s3);
        collection.add(s3);
        System.out.println(collection.toString()); //[Student{name='张三', age=20}, Student{name='李四', age=22}, Student{name='王五', age=21}]
        //删除数据
//        collection.remove(s1);
//        collection.clear();
        //遍历
        for (Object object:collection
             ) {
            Student student=(Student)object;
            System.out.println(student.toString());
        }
        //迭代器
        Iterator iterator=collection.iterator();
        while (iterator.hasNext()){
            Object object= iterator.next();
            System.out.println(object.toString());
        }
        //判断
        System.out.println(collection.contains(s1));
        System.out.println(collection.isEmpty());
    }

}

2.List子接口

  • 贴点:有序、有下标、元素可以重复
  • 方法:
    • void add(int index,Object o)
    • boolean addAll(int index,Collection c) //将一个集合中的元素添加到此集合的index位置
    • Object get (int index)
    • List subList(int fromIndex,int toIndex) //返回fromIndex和toIndex之间的集合元素
public class Demo3 {
    public static void main(String[] args) {
        //1.创建集合对象
        List list = new ArrayList();
        list.add("苹果");
        list.add("小米");
        list.add(0,"华为");
        System.out.println(list); //[华为, 苹果, 小米]
        //2.删除元素
//        list.remove("苹果");
//        list.remove(0);
//        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只有hasNext,next,remove这三个方法
        Iterator iterator=list.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
        //3.4使用列表迭代器,比Iterator强大,ListIterator可以从前往后,从后往前的增加、删除,修改
        ListIterator listIterator = list.listIterator();
        while (listIterator.hasNext()){
            //从前往后
            System.out.println(listIterator.nextIndex()+":"+listIterator.next());
        }
        while (listIterator.hasPrevious()){
            //从后往前
            System.out.println(listIterator.previousIndex()+":"+listIterator.previous());
        }
        //4.判断
        System.out.println(list.contains("苹果"));
        //5.获取位置
        System.out.println(list.indexOf("华为"));

    }
}
public class Demo4 {
    public static void main(String[] args) {
        List list =new ArrayList();
        list.add(20);
        list.add(30);
        list.add(40);
        list.add(50);
        System.out.println("元素个数"+list.size());
        System.out.println(list.toString());
        //2.删除操作,
        //两种删除20的操作,不能直接使用list.remove(20),因为存入list中已经被封装过了
//        list.remove(0);
//        list.remove(new Integer(30));
//        System.out.println(list.toString());
        //3补充subList,返回集合,含头不含尾
        System.out.println(list.subList(1,3));  //[30, 40]

    }
}

3.List实现类

  • ArrayList[重点]:

    • 数组结构实现,查询快、增删慢;
    • JDK1.2版本,运行效率快,线程不安全。
  • Vector:

    • 数组结构实现,查询快、增删慢;
    • JDK1.0版本,运行效率慢、线程安全。
  • LinkedList:

    • 链表结构实现,增删快,查询慢。
public class Student {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

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

    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 +
                '}';
    }

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

    @Override
    public boolean equals(Object obj) {
        //判断是否同一个对象
        if(this==obj){
            return true;
        }
        if (obj ==null){
            return false;
        }
        //判断是否是Student类型
        if(obj instanceof Student){
            Student s=(Student)obj;
            //比较属性
            if(this.name.equals(s.getName())&&s.age==s.getAge()){
                return true;
            }
        }
        //不满足条件返回false
        return false;
    }
}
public class Student {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

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

    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 +
                '}';
    }

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

    @Override
    public boolean equals(Object obj) {
        //判断是否同一个对象
        if(this==obj){
            return true;
        }
        if (obj ==null){
            return false;
        }
        //判断是否是Student类型
        if(obj instanceof Student){
            Student s=(Student)obj;
            //比较属性
            if(this.name.equals(s.getName())&&s.age==s.getAge()){
                return true;
            }
        }
        //不满足条件返回false
        return false;
    }
}

ArrayList:(用的比较多)

​ 源码分析: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 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);   //扩容为1.5倍
        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);
    }

*Vector:(用的比较少)

  • 数组结构实现,查询快、增删慢;
  • JDK1.0版本,运行效率慢、线程安全。
package Collection;
import java.util.Enumeration;
import java.util.Vector;
/**
 * Vector集合的使用
 * 存储结构:数组
 * @author chengcheng
 */
public class Demo6 {
    public static void main(String[] args) {
        Vector vector = new Vector();
        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);
        }
        //4判断
        System.out.println(vector.contains("西瓜"));
        System.out.println(vector.isEmpty());
        //vector的其他方法firstElement();astElement();elementAt();
    }
}

LinkedList:

  • 链表结构实现,增删快,查询慢。
package Collection;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;

/**
 * LinkedList的使用
 * 存储结构:双向链表
 *
 */
public class Demo7 {
    public static void main(String[] args) {
        LinkedList linkedList=new LinkedList();
        Student s1=new Student("刘德华",18);
        Student s2=new Student("郭富城",19);
        Student s3=new Student("梁朝伟",20);
        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.remove(new Student("郭富城",19));//因为在equals中重写了方法,所以能正常删除
//        System.out.println(linkedList.size());
        //3遍历
        //for
        for (int i=0; i<linkedList.size();i++){
            System.out.println(linkedList.get(i));
        }
        //增强for
        for (Object o :linkedList) {
            Student s=(Student)o;
            System.out.println(s.toString());
        }
        //迭代器
        Iterator iterator=linkedList.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
        //ListIterator比Iterator功能更强大
        ListIterator listIterator = linkedList.listIterator();
        while (listIterator.hasNext()){
            System.out.println(listIterator.next());
        }
        //逆序遍历
        while (listIterator.hasPrevious()){
            System.out.println(listIterator.previous());
        }

        //4判断
        System.out.println(linkedList.contains(s1));
        System.out.println(linkedList.isEmpty());
        //5获取
        System.out.println(linkedList.indexOf(s2));
    }
}

在这里插入图片描述

void linkLast(E e) {
    final Node<E> l = last;
    final Node<E> newNode = new Node<>(l, e, null);
    last = newNode;
    if (l == null)
        first = newNode;
    else
        l.next = 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;
        }
    }

泛型

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

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

  • 语法:

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

    • 提高代码的重用性

    • 防止类型异常转化,提高代码的安全性

    *泛型类

package Collection;

/**
 * 泛型类
 * 语法:类名<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;
    }
}
package Collection;

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

        MyGeneric<Integer> myGeneric1=new MyGeneric<>();
        myGeneric1.t=10;
        myGeneric1.show(100);
        System.out.println(myGeneric1.getT());
    }
}

*泛型接口

package Collection;

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

}
package Collection;

public class MyInterfaceImpl implements MyInterface<String> {
    @Override
    public String server(String s) {
        System.out.println(s);
        return s;
    }

    public static void main(String[] args) {
        MyInterfaceImpl impl=new MyInterfaceImpl();
        impl.server("xxx");
    }
}
package Collection;

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

    public static void main(String[] args) {
        MyInterfaceImpl2<Integer> impl2=new MyInterfaceImpl2<>();
        impl2.server(1000);
    }
}

*泛型方法

package Collection;

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

    public static void main(String[] args) {
        MyGenericMethod myGenericMethod=new MyGenericMethod();
        myGenericMethod.show("zhangsan");
        myGenericMethod.show(200);
    }
}

泛型集合

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

Set子接口

  • 贴点:无序、无下标、元素不可重复。

  • Set实现类:

    • HashSet(重点):

      • 基于HashCode实现元素不重复。
      • 当存入元素的哈希码相同时,会调用equals进行确认,如结果为true,则拒绝后者存入。
    • TreeSet:

      • 基于排列顺序实现元素不重复
package set;

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

/**
 * 测试Set接口的使用
 * 特点:(1)无序、没有下标(2)不能重复
 */
public class Demo1 {
    public static void main(String[] args) {
        //创建集合
        Set<String> set=new HashSet<>();
        set.add("小米");
        set.add("苹果");
        set.add("华为");
        set.add("华为");
        System.out.println("个数:"+set.size());
        System.out.println(set.toString());
        //删除
        set.remove("华为");
        //遍历,使用增强for,因为是无序的
        System.out.println("---------增强for---------");
        for(String s:set){
            System.out.println(s);
        }
        //迭代器
        Iterator<String> iterator=set.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
        //判断
        System.out.println(   set.contains("华为"));
        System.oHut.println(set.isEmpty());
    }
}

HashSet案例

package set;

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

/**
 * HashSet集合的使用,不重复
 * 存储结构:哈希表(数组+链表+红黑树)
 */
public class Demo2 {
    public static void main(String[] args) {
        HashSet<String> hashSet=new HashSet<>();
        hashSet.add("刘德华");
        hashSet.add("梁朝伟");
        hashSet.add("林志玲");
        hashSet.add("周润发");
//        hashSet.add("周润发");
        System.out.println("元素个数:"+hashSet.size());
        System.out.println(hashSet.toString());
        //删除
        hashSet.remove("周润发");
        //遍历
        Iterator<String> iterator = hashSet.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
        System.out.println(hashSet.contains("郭富城"));
        System.out.println(hashSet.isEmpty());
    }
}

案列2

package set;

import java.util.Objects;

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 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 int hashCode() {
        int n1=this.name.hashCode();
        int n2=this.age;
        return n1+n2;
    }
}
package set;

import java.util.HashSet;

/**
 * HashSet集合的使用,不重复
 * 存储结构:哈希表(数组+链表+红黑树)
 * 存储过程(重复依据)
 * (1)根据hashcode计算保存的位置,如果位置为空,则直接保存,如果不为空执行第二步。
 * (2)再执行equals方法,如果equals方法为true,则认为是重复,否则,形成链表
 */
public class Demo3 {
    public static void main(String[] args) {
        HashSet<Person> persons=new HashSet<>();
        Person p1=new Person("刘德华",22);
        Person p2=new Person("梁朝伟",23);
        Person p3=new Person("郭富城",24);
        persons.add(p1);
        persons.add(p2);
        persons.add(p3);
        persons.add(p3);//重复不能添加
        persons.add(new Person("郭富城",24));//失败,因为重写了hashcode和equals
        System.out.println("元素个数:"+persons.size());
        System.out.println(persons.toString());
         persons.remove(new Person("刘德华",22));//也能删除成功,因为重写了hashcode和equals

    }
}

在这里插入图片描述

拓展:源码中的hascode

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

    int result = 1;

    for (Object element : a)
    //31是一个质素,减少散列冲突(尽量存储到不同的位置)(2)31提高执行效率 31*i=(i<<5)-i 这样可以用位移
        result = 31 * result + (element == null ? 0 : element.hashCode());

    return result;
}

TreeSet:(红黑树)

  • 基于排列顺序实现元素不重复
  • 实现了SortedSet接口,对集合元素自动排序。
  • 元素对象的类型必须实现Comparable接口,指定排序规则。
  • 通过CompareTo方法确定是否为重复元素。
    在这里插入图片描述

例子:

package set;
import java.util.Iterator;
import java.util.TreeSet;
/**
 * TreeSet的使用
 * 存储结构:红黑树
 */
public class Demo4 {
    public static void main(String[] args) {
        TreeSet<String> treeSet=new TreeSet<>();
        treeSet.add("xyz");
        treeSet.add("abc");
        treeSet.add("hello");
        System.out.println("元素个数:"+treeSet.size());
        System.out.println(treeSet.toString());
        //删除
        treeSet.remove("xyz");
        System.out.println(treeSet.toString());

        //遍历
        for (String s :treeSet) {
            System.out.println(s);
        }
        System.out.println("---------");
        Iterator<String> iterator = treeSet.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
        //4判断
    System.out.println(treeSet.contains("abc"));
    }
}

存储对象实例:

package 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 compareTo(Person o) {
        int n1=this.getName().compareTo(o.getName());
        int n2=this.age-o.getAge();
        return n1==0?n2:n1;
    }
}
package set;

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

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

        Person p1=new Person("刘德华",22);
        Person p2=new Person("梁朝伟",23);
        Person p3=new Person("郭富城",24);
        Person p4=new Person("郭富城",20);

        persons.add(p1);
        persons.add(p2);
        persons.add(p3);
        persons.add(p4);
        System.out.println("元素个数:"+persons.size());

        //
        persons.remove(new Person("刘德华",22));//比的是姓名和年龄,所以能删除。不要搞混淆与equals和hashcode.
        System.out.println(persons.size());
    }
}

拓展:

package set;

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

/**
 * TreeSet集合的使用
 * comparator:实现定制比较(比较器)
 * comparable:可比较的
 */
public class Demo6 {
    public static void main(String[] args) {
        //创建集合,并指定比较规则,这样在写Person类时可以不不用实现Comparable接口
        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("刘德华",22);
        Person p2=new Person("梁朝伟",23);
        Person p3=new Person("郭富城",24);
        Person p4=new Person("郭富城",20);

        persons.add(p1);
        persons.add(p2);
        persons.add(p3);
        persons.add(p4);
        System.out.println(persons);
    }
}

拓展2:

package set;

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

/**
 * 要求,使用TreeSet集合实现字符串按照长度进行排序,默认按照字母顺序排序
 * helloworld zhang lisi wangwu beijing xian nanjing
 * 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("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);//[cat, lisi, xian, beijing, nanjing, pingguo, zhangsan, helloworld]
    }
}

Map集合

在这里插入图片描述

Map父接口

  • 特点:存储一对数据(Key-Value),无序,无下标,键不可重复,值可重复。
  • 方法:
    • V put(K key,V value) //将对象存入到集合中,关联键值。key重复则覆盖原值。
    • Object get(Object key) //根据键获取对应的值。
    • keySet //返回所有key。
    • Collection value() //返回包含所有值的Collection集合。
    • entrySet<Map.Entry<K,V>> //键值匹配的Set集合。
package map;

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

/**
 * Map接口的使用
 * 特点:(1)存储键值对(2)键不能重复,值可以重复(3)无序
 */
public class Demo1 {
    public static void main(String[] args) {
        //创建Map集合
        Map<String,String > map=new HashMap<>();
        map.put("cn","中国");
        map.put("uk","英国");
        map.put("usa","美国");
        map.put("cn","zhongguo"); //key重复,会覆盖之前的

        System.out.println(map.toString());
        //删除
        map.remove("usa");
        //遍历
        //使用keySet();
//        Set<String> keySet = map.keySet();
        for (String key:map.keySet()){
            System.out.println(key+"---------"+map.get(key));
        }
        //使用entrySet()方法
        Set<Map.Entry<String, String>> entries = map.entrySet();
        for(Map.Entry<String,String> entry: entries){
            System.out.println(entry.getKey()+"------"+entry.getValue());
        }
        //判断
        System.out.println(map.containsKey("cn"));
        System.out.println(map.containsValue("泰国"));
    }
}

在这里插入图片描述

Map集合的实现类:

hashMap(重点):

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

​ 构造方法hashMap() 构造一个具有默认初始容量(16)和默认加载因子(0.75)的空HashMap.

在这里插入图片描述

实例:

package map;

import java.util.Objects;

public class 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 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);
    }
}
package map;

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

/**
 * HashMap集合的使用
 * 存储结构:哈希表(数组+链表+红黑树)
 * 使用key的hashcode和equals作为重复
 * @author chengcheng
 */

public class Demo2 {
    public static void main(String[] args) {
        //创建集合K,V
        HashMap<Student,String> students=new HashMap<Student,String>();
        //添加元素
        Student s1=new Student("孙悟空",100);
        Student s2=new Student("猪八戒",101);
        Student s3=new Student("沙和尚",102);
        Student s4=new Student("唐生",103);
        students.put(s1,"北京");
        students.put(s2,"上海");
        students.put(s3,"杭州");
        students.put(s4,"重庆");
        students.put(new Student("孙悟空",100),"北京");
        System.out.println(students.size());
        System.out.println(students.toString());

        //删除
        students.remove(s1);

        //使用keySet();
        for(Student key:students.keySet()){
            System.out.println(key.toString()+"------------"+students.get(key));
        }
        //entrySet()
        System.out.println("----------entrySet-----------------");
        for(Map.Entry<Student,String> entry:students.entrySet()){
            System.out.println(entry.getKey()+"------"+entry.getValue());
        }
        //判断
        System.out.println(students.containsKey(s2));

    }
}

源码:

static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16  //数组初始长度
static final int MAXIMUM_CAPACITY = 1 << 30;  //数组最大长度
static final float DEFAULT_LOAD_FACTOR = 0.75f;  //默认加载因子
static final int TREEIFY_THRESHOLD = 8; //JDK1.8链表最大长度,超过8且数组长度大圩等于64会变成红黑树,这样会提高查询效率
static final int UNTREEIFY_THRESHOLD = 6;  //JDK1.8链表长度小于6时,调整成链表
static final int MIN_TREEIFY_CAPACITY = 64;
transient Node<K,V>[] table;//哈希表中的数组
transient int size;//元素个数

//hashMap刚创建时,table是null,为了节省空间,当添加第一个元素时,table容量调整为16
//JDK1.8以前,链表是头插入,JDK1.8以后是为插入

实际上HashSet里面使用了HashMap来存储

  • Hashtable:(用的不多了)

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

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

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

实例:

package map;

import java.util.Objects;

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 n2=this.stuNo-o.getStuNo();
        return n2;
    }
}
package map;

import java.util.Map;
import java.util.TreeMap;

/**
 * TreeMap的使用
 * 存储结构:红黑树
 * @author chengcheng
 */
public class Demo3 {
    public static void main(String[] args) {
        //新建集合
        TreeMap<Student,String> students=new TreeMap<>();
        //添加元素
        Student s1=new Student("孙悟空",100);
        Student s2=new Student("猪八戒",101);
        Student s3=new Student("沙和尚",102);
        Student s4=new Student("唐生",103);
        students.put(s1,"北京");
        students.put(s2,"上海");
        students.put(s3,"杭州");
        students.put(s4,"重庆");
        students.put(new Student("孙悟空",100),"北京1"); //也能添加
        System.out.println(students.size());
        System.out.println(students.toString());
        //删除
        students.remove(s1);
        students.remove(new Student("唐生",103));//也能删除
        System.out.println(students.size());
        //遍历
        for(Student key:students.keySet()){
            System.out.println(key+"=========="+students.get(key));
        }
        for (Map.Entry<Student,String> entry:students.entrySet()){
            System.out.println(entry.getKey()+"=========="+entry.getValue());
        }
        //判断
        System.out.println(students.containsKey(new Student("沙和尚",102)));
    }
}

Exception in thread “main” java.lang.ClassCastException: map.Student cannot be cast to java.lang.Comparable
at java.util.TreeMap.compare(TreeMap.java:1294)
at java.util.TreeMap.put(TreeMap.java:538)
at map.Demo3.main(Demo3.java:19)

这种错误注意:要实现 Comparable<>接口

Colletions工具类

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

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * 演示Collections工具类的使用
 */
public class Demo4 {
    public static void main(String[] args) {
        List<Integer>  list=new ArrayList<>();
        list.add(200);
        list.add(300);
        list.add(6);
        list.add(580);
        list.add(23);
        //sort排序
        System.out.println("排序之前:"+list.toString());
        Collections.sort(list);
        System.out.println("排序之后:"+list.toString());
        //binarySearch 二分查找
        int i = Collections.binarySearch(list, 6);
        System.out.println(i);
        //copy复制
//        List<Integer> dest=new ArrayList<>(); //这样创建出来大小为0
//        Collections.copy(dest,list);
//        System.out.println(dest);  //Exception in thread "main" java.lang.IndexOutOfBoundsException: Source does not fit in dest

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

        //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));

        //数组变集合
        String[] names={"zhangshan","lisi","wangwu "};
        //集合是受限集合,不能添加和删除
        List<String> lists = Arrays.asList(names);
//        lists.add("zhaoliu");  会报错
//        lists.remove("lisi");  会报错
        System.out.println(lists);

//        int[] nums={100,300,399};
//        List<int[]> ints = Arrays.asList(nums);
//        for (int[] s:ints){
//            System.out.println(Arrays.toString(s));
//        }

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

    }
}

集合总结:

  • 集合的概念:
    • 对象的容器,和数组类似,定义了对多个对象进行操作的常用方法。
  • List集合:
    • 有序、有下标、元素可以重复。(ArrayList、LinkedList、Vector)
  • Set集合:
    • 无序、无下标、元素不可重复。(HashSet、TreeSet)
  • Map集合:
    • 存储一对数据,无序、无下标,键不可重复,值可重复。(HashMap、HashTable、TreeMap)
  • Collections:
    • 集合工具类,定义了除了存取以外的集合常用方法。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值