java学习之旅(day.16)

集合框架

集合

集合:对象的容器,创建的对象就存储在集合中。集合定义了对多个对象进行操作的常用方法,可实现数组的功能

集合和数组的相同点:都是容器

集合和数组的区别:

  • 数组定义后长度固定,集合长度不固定
  • 数组可以存储基本类型和引用类型,集合只能存储引用类型(如果要想存储基本类型,需要用装箱操作:把基本类型装箱成引用类型后保存在集合中)

集合在:java.util.这个包中

Collection体系集合

19

有序:指添加的顺序和遍历的顺序要求一致,如添加的时候第一个元素是1,那么遍历的时候第一个元素还是1

有下标:指可以像数组一样通过角标来访问

接口在用的时候是不能直接创建对象的,必须要用实现类

Collection父接口

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

Collection中定义的一些方法:

  • boolean add(Object obj) 添加一个对象到Collection集合中
  • 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的使用

package com.zhang.kuangjia;

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

//Collection的使用:保存字符串
//1.添加元素
//2.删除元素
//3.遍历元素
//4.判断
public class Demo01 {
    public static void main(String[] args) {
        //创建一个集合
        Collection collection=new ArrayList();//因为接口无法实例化,只能实例化实现类Arraylist
        //1.添加元素
        collection.add("平果");
        collection.add("西瓜");
        collection.add("榴莲");
        System.out.println("元素个数:"+collection.size());// 元素个数:3 可以据此看有没有将元素添加进去
        System.out.println(collection);//[平果, 西瓜, 榴莲]
        //2.删除元素
        //collection.remove("榴莲");
        //collection.clear();//清空所有元素
        //System.out.println("删除之后"+collection.size());
        //3.遍历元素(有两种)
        //3.1使用增强for(for不行,因为此处无法用下标)
        for (Object object:collection) {//object就是每一个元素
            System.out.println(object);
        }
        //3.2使用迭代器(专门用来遍历集合的一种方法)
            //调用方法iterator() 其返回值类型为Iterator
            Iterator it=collection.iterator();
            //Iterator 中有三个方法
            //hasNext() 看有没有下一个元素
            //next() 获取下一个元素
            //remove()  删除当前元素
            while (it.hasNext()){
            String s=(String) it.next();//有的话取出来并返回一个值是Object类型的,已知给的是String类型的,所以可以做一个强制转换
                System.out.println(s);
                //collection.remove(s);
                //注意在迭代过程中,不允许使用collection的删除方法的。如:操作collection.remove(s);会报异常ConcurrentModification(并发修改异常)
                //迭代collection在用着呢,不允许并发修改(此时不能用collection.来删除)
                //要想删可以用remove
            //it.remove();
            }
            System.out.println("元素个数:"+collection.size());
        //4.判断
        System.out.println(collection.contains("西瓜"));
        System.out.println(collection.isEmpty());

    }
}
================================================================================
    package com.zhang.kuangjia;

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

//Collection的使用:保存学生信息,此时需要建个学生类
public class Demo02 {
    public static void main(String[] args) {
        //新建Collection对象
        Collection collection=new ArrayList();
        Student s1=new Student("zz",20);
        Student s2=new Student("xx",52);
        Student s3=new Student("rr",12);
        //1.添加数据
        collection.add(s1);
        collection.add(s2);
        collection.add(s3);
        collection.add(s3);//ArrayList可添加重复的
        System.out.println("元素个数:"+collection.size());
        System.out.println(collection.toString());
        //2.删除
        //collection.remove(s1);
        //collection.remove(new Student("xx",20));//这样删不掉,这个新new的与s2只是属性相同,但却是不同的对象
        //collection.clear();//清空,只是把上面几个对象从集合中移除了,但三个对象是存在的
        //System.out.println("删除之后的个数"+collection.size());
        //3.遍历(2种方式)
        //3.1增强for循环
        for (Object object:collection) {
            Student s=(Student) object;
            System.out.println(s.toString());
        }
        //3.2迭代器
        Iterator it=collection.iterator();
        while (it.hasNext()){
            Student s=(Student) it.next();
            System.out.println(s.toString());
        }
        //4.判断
        System.out.println(collection.contains(s1));//true
        System.out.println(collection.contains(new Student("xx",20)));//false
        System.out.println(collection.isEmpty());//false

    }
}

List子接口

list Collection的子接口

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

方法:(除了collection中包含的方法外,还有以下方法)

  • 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之间的集合元素
package com.zhang.kuangjia;

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

//List子接口的使用
public class Demo03 {
    public static void main(String[] args) {
        //先创建集合对象
        List list=new ArrayList();
        //添加元素
        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种)
        //3.1 使用for进行遍历
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));//get返回的是Object类型
        }
        //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 使用列表迭代器listIterator
        //和Iterator的区别:ListIterator可以向前或向后遍历,还可以添加、删除、修改元素
        ListIterator lit= list.listIterator();
        System.out.println("使用列表迭代器从前往后");
        while (lit.hasNext()){
          System.out.println(lit.nextIndex()+":"+lit.next());//nextIndex()打印角标
        }
        System.out.println("使用列表迭代器从后往前");
        while (lit.hasPrevious()){
            System.out.println(lit.previousIndex()+":"+lit.previous());//nextIndex()打印角标
        }
        //4.判断
        System.out.println(list.contains("苹果"));
        System.out.println(list.isEmpty());
        //5.获取位置
        System.out.println(list.indexOf("华为"));//0  获取位置
    }
}
======================================================================
    package com.zhang.kuangjia;


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

//List的使用
public class Demo04 {
    public static void main(String[] args) {
        //创建集合
        List list=new ArrayList();
        //添加数字类型数据时,隐含了一个操作:自动装箱
        list.add(20);//给了基本类型20,实际上是包装类Integer 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);//此处调用remove是按下角标位置删除,而不是按元素
        //或者用: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);//下角标1-3,含左(1)不含右(3)
        System.out.println(subList.toString());
    }
}

List接口的常用实现类

  • ArrayList

源码分析:

DEFAULT_CAPACITY = 10 默认容量
    注:如果没有向集合中添加任何元素,容量为0 size也为0,添加任意一个元素之后,容量为10,每次扩容大小是原来的1.5倍
elementData 存放元素的数组
size 实际的元素个数(其一定是小于容量的)
add()方法 添加元素    

以数组结构实现(内部使用数组来保存数据),查询快,增删慢,运行效率快,线程不安全

  • Vector

以数组结构实现,查询快,增删慢,运行效率慢,线程安全

  • LinkedList

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

package com.zhang.kuangjia.demo;

import com.zhang.kuangjia.demo.Student;

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

//ArrayList的使用
public class Demo05 {
    public static void main(String[] args) {
        //创建集合
        ArrayList arrayList=new ArrayList();
        //1.添加元素
        Student s1=new Student("邢菲fei",26);
        Student s2=new Student("谭松yun",30);
        Student s3=new Student("李兰di",25);
        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("谭松yun",30));//无法删除,要想删除,重写equals
        //System.out.println("删除后与元素个数:"+arrayList.size());
        //3.遍历元素 增强for和for循环自己看,只写迭代器的
        //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();
        while (lit.hasNext()){
            Student s=(Student) lit.next();
            System.out.println(s.toString());
        }
        //列表迭代器逆序
        while (lit.hasPrevious()){
            Student s=(Student) lit.previous();
            System.out.println(s.toString());
        }
        //4.判断
        System.out.println(arrayList.contains(s1));//true
        System.out.println(arrayList.contains(new Student("谭松yun",30)));//true
        //因为已经重写了equals方法,此时只要属性相同就相同了
        System.out.println(arrayList.isEmpty());//false
        //5.查找
        System.out.println(arrayList.indexOf(s1));//0  s1的位置
    }
}
package com.zhang.kuangjia.demo;


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

    }
    //构造方法,getset

    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;
    }
    //打印时为了好看,重写toString方法

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

    @Override
    public boolean equals(Object obj) {
        //1.判断传递过来的对象和当前对象是不是同一个
        if(this==obj){
            return true;
        }
        //2.判断是不是为空
        if (obj==null){
            return false;
        }
        //3.判断obj是不是Student类型
        if(obj instanceof Student){
           Student s=(Student) obj;
        //4.比较属性,如果属性年龄,名字相同,就认为他们是同一人
            if(this.name.equals(s.getName())&&this.age==s.getAge()){
                return true;
            }
        }
        //5.不满足条件的话返回false
                return false;
    }
}

=================================================================================
    package com.zhang.kuangjia;

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

//Vector集合的使用(了解即可,用的少了)
public class Demo06 {
    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.遍历,同样也能用for和增强for,迭代器,这个多了个枚举器
        //3.1使用枚举器,用elements()方法,该方法返回值为Enumeration
        //得到枚举器
        Enumeration en=vector.elements();
        //遍历
        while (en.hasMoreElements()){
            Object o=en.nextElement();//如果向变成原来的字符串类型,用String做一个强转:String o=(String)en.nextElement;
            //String o1=(String)en.nextElement();
            System.out.println(o);
        }
        //4.判断:和之前一样
        System.out.println(vector.contains("西瓜"));
        System.out.println(vector.isEmpty());
        //补充vector的其他方法
        Object c=vector.firstElement();//获取集合的第一个元素
        System.out.println(c);//草莓
        Object d=vector.lastElement();//获取集合的最后一个元素
        System.out.println(d);//芒果
        System.out.println(vector.elementAt(1));// 西瓜 获取某个位置的元素
        //获取某个位置的元素也可以用get
        System.out.println(vector.get(1));//西瓜
    }
}
===============================================================================
    package com.zhang.kuangjia.Demo1;

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

//LinkedList的使用
public class Demo07 {
    public static void main(String[] args) {
        //创建集合
        LinkedList linkedList=new LinkedList();
        //1.添加元素
        Student s1=new Student("李",25);
        Student s2=new Student("谭",30);
        Student s3=new Student("邢",26);
        linkedList.add(s1);
        linkedList.add(s2);
        linkedList.add(s3);
        //linkedList.add(s2);//可以重复
        System.out.println("元素个数:"+linkedList.size());
        System.out.println(linkedList.toString());
        //2.删除
        //linkedList.remove(s2);
        //也可以像下行这样,因为Student中的equals方法已经过重写
        //linkedList.remove(new Student("谭",30));
        //System.out.println("删除之后元素个数:"+linkedList.size());
        //3.遍历
        //3.1使用for遍历
        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());
        }
        //3.4列表迭代器
        ListIterator lit=linkedList.listIterator();
        while (lit.hasNext()){
            Student s=(Student)lit.next();
            System.out.println(s.toString());
        }
        //4.判断
        System.out.println(linkedList.contains(s1));//true
        System.out.println(linkedList.isEmpty());//false
        //5.获取位置
        System.out.println(linkedList.indexOf(s1));// 0 获取s1在集合中的位置

    }
}

package com.zhang.kuangjia.Demo1;

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

    }
    //构造方法,getset

    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;
    }
    //打印时为了好看,重写toString方法

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

    @Override
    public boolean equals(Object obj) {
        //1.判断传递过来的对象和当前对象是不是同一个
        if(this==obj){
            return true;
        }
        //2.判断是不是为空
        if (obj==null){
            return false;
        }
        //3.判断obj是不是Student类型
        if(obj instanceof Student){
           Student s=(Student) obj;
        //4.比较属性,如果属性年龄,名字相同,就认为他们是同一人
            if(this.name.equals(s.getName())&&this.age==s.getAge()){
                return true;
            }
        }
        //5.不满足条件的话返回false
                return false;
    }
}

ArrayList与LinkedList的区别

ArrayList:里面是数组,开辟连续空间,查询快,增删慢

LinkedList:里面是双向链表,无需开辟连续空间,查询慢,增删快

泛型

泛型的本质是参数化类型,把类型(数据类型)作为参数传递

常见的是哦那个形式有:

  • 泛型类
  • 泛型接口
  • 泛型方法

语法: <T(大写)> T为类型占位符,表示一种引用类型

好处:

  • 提高代码的重用性
  • 防止类型转换异常,提高代码的安全性
package com.zhang.kuangjia.generic;
//泛型类
//语法:类名后加<T>,即:类名<T>  T泛型的类型占位符,表示一种引用类型。可以写多个泛型:<T,E>
public class Demo08<T> {
    //使用泛型T
    //1.创建变量
    T t;
    //2.泛型作为方法的参数
    public void show(T t){
        //T t1=new T();  泛型可以创建变量,但不能实例化
        System.out.println(t);
    }
    //3.泛型作为方法的返回值
    public T getT(){
        return t;
    }
}
/*
package com.zhang.kuangjia.generic;

public class TestGeneric {
    public static void main(String[] args) {
        //使用泛型创建对象
        //注意:1.泛型只能使用引用类型 2.不同的泛型类型对象之间不能相互赋值(Demo08<String> demo083=demo08;不能这样赋值)
        Demo08<String> demo08=new Demo08<String>();
        demo08.t="hello";
        demo08.show("java,你好呀");//调用show并传参
        String string=demo08.getT();

        Demo08<Integer> demo081=new Demo08<Integer>();
        demo081.t=100;
        demo081.show(200);
        Integer integer=demo081.getT();

    }

}

 */
package com.zhang.kuangjia.generic;
//泛型接口
//语法:接口名<T>  T表示数据类型
//注意:在使用泛型接口的时候,不能使用泛型创建静态常量
public interface MyInterface<T> {
    //接口里面可以包含抽象方法,静态常量等
    String name="张三";//静态常量
    T sever(T t);//抽象方法
    //接口不能实例化,要想用的话必须添加一个实现类
}


package com.zhang.kuangjia.generic;
//实现类1
public class MyInterfaceImpl implements MyInterface<String>{//实现接口的时候必须把泛型T的类型告诉它

    @Override
    public String sever(String s) {
        System.out.println(s);
        return s;
    }
}


package com.zhang.kuangjia.generic;
//实现类2
public class MyInterfaceImpl2<T> implements MyInterface<T>{//此处T未给定确定的类型
    //把类变成泛型的即:类后加<>,两个T类型一致。泛型类中的T是什么类型,接口中的T就是什么类型


    @Override
    public T sever(T t) {
        System.out.println(t);
        return t;
    }
}


package com.zhang.kuangjia.generic;
//泛型方法
//语法:泛型放在方法返回值类型之前,即:<T>返回值类型  T是在调用方法的时候具体传给它的类型
public class MyGenericMethod {
    public <T> void show(T t){
        System.out.println("泛型方法");
    }

}


package com.zhang.kuangjia.generic;
//测试类
public class TestGeneric {
    public static void main(String[] args) {
        //使用泛型创建对象
        //注意:1.泛型只能使用引用类型 2.不同的泛型类型对象之间不能相互赋值(Demo08<String> demo083=demo08;不能这样赋值)
        Demo08<String> demo08=new Demo08<String>();
        demo08.t="hello";
        demo08.show("java,你好呀");//调用show并传参
        String string=demo08.getT();

        Demo08<Integer> demo081=new Demo08<Integer>();
        demo081.t=100;
        demo081.show(200);
        Integer integer=demo081.getT();


        //泛型接口
        MyInterfaceImpl impl=new MyInterfaceImpl();
        impl.sever("xxxxxx");



        MyInterfaceImpl2<Integer> impl2=new MyInterfaceImpl2<>();
        impl2.sever(1000);
        //泛型方法
        MyGenericMethod myGenericMethod=new MyGenericMethod();
        myGenericMethod.show("java好难");//调用泛型方法的时候,T的类型不需传递,T的类型由传入的参数类型决定     String
        myGenericMethod.show(200);    //Integer
        //上面两行说明泛型方法可以提高代码的重用性,用普通方法的话,想输入不同类型的参数就得用到重载了
    }

}

泛型集合

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

特点:

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

Set集合的使用

Set子接口

  • 特点:无序,无下标,元素不可重复
  • 方法:全部继承自Collection中的方法
package com.zhang.kuangjia.generic;
//测试set接口的使用
//特点:无序、无下标、不能重复
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

//类型转换异常
public class Demo09 {
    public static void main(String[] args) {
       //创建集合
        Set<String> set=new HashSet<>();//set时接口,不可new 接口,要new set接口的实现类
        //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<String> it=set.iterator();
        while (it.hasNext()){
            System.out.println(it.next());
        //4.判断
            System.out.println(set.contains("华为"));
            System.out.println(set.isEmpty());
        }
    }
}

Set实现类

  • HashSet

存储结构:哈希表

基于HashCode值计算元素存放位置

当存入元素的哈希码相同时,会调用equals进行确认,如结果为true,则认为这个元素是重复的,就不能再存了,拒绝后者存入,结果为false的话,则可以继续存储。

package com.zhang.kuangjia.generic;

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

//HasSet集合的使用
//存储结构:哈希表(数组+链表+红黑树)
public class Demo11 {
    public static void main(String[] args) {
        HashSet<String> hashSet=new HashSet<String>();
        //1.添加元素
        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
        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("tan"));
        System.out.println(hashSet.isEmpty());
    }
}
==========================================================
    package com.zhang.kuangjia.generic;

import com.zhang.Student;

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

//HashSet集合的使用2
//存储结构:哈希表
//存储过程
//1.根据hashcode计算保存的位置,如果此位置为空(没有数据),则直接保存。反之,执行2
//2.再执行equals方法,如果equals方法为true,则认为重复,就不再存储,若返回值为false,则形成链表
public class Demo12 {
    public static void main(String[] args) {
        //创建集合
        HashSet<Person> person=new HashSet<>();
        //添加数据
        Person p1=new Person("谭",30);
        Person p2=new Person("李",25);
        Person p3=new Person("邢",25);
        person.add(p1);
        person.add(p2);
        person.add(p3);
        person.add(new Person("谭",30));//这里可以加进去,也就是会输出4个元素,
        //但是现在想认为只要名字和年龄相同就不让他再加进集合中,如何实现?重写hasCode方法和equals方法
        System.out.println("元素个数:"+person.size());
        System.out.println(person.toString());
        //2.删除操作
        //person.remove(p1);
        //person.remove(new Person("谭",30));
        //System.out.println("删除之后元素个数:"+person.size());
        //3.遍历
        //3.1使用增强for
        for (Person person1:person) {
            System.out.println(person1.toString());
        }
        //3.2使用迭代器
        Iterator it=person.iterator();
        while (it.hasNext()){
            System.out.println(it.next());
        //4判断
            System.out.println(person.contains(p1));
            System.out.println(person.contains(new Person("李",26)));
            System.out.println(person.isEmpty());
        }
    }
}


/*
package com.zhang.kuangjia.generic;

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

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

 */
  • TreeSet

存储结构:红黑树

基于排列顺序实现元素不重复,往里面添加元素时会进行排序

实现了SortedSet接口,对集合元素自动排序

元素对象的类型必须实现Comparable接口,指定排序规则

Comparable中有个CompareTo方法,可以确定元素是否重复

package com.zhang.kuangjia.generic;

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

//TreeSet的使用
public class Demo13 {
    public static void main(String[] args) {
        //创建集合
        TreeSet<String> treeSet=new TreeSet<>();
        //1.添加元素
        treeSet.add("xyz");
        treeSet.add("abc");
        treeSet.add("hello");
        System.out.println("元素个数:"+treeSet.size());
        System.out.println(treeSet.toString());//这里输出的时候有个排序。如果时字符串,按自检表中的顺序排
        //2.删除元素
        treeSet.remove("xyz");
        System.out.println(treeSet.toString());
        //3.遍历
        //3.1增强for
        for (String string:treeSet) {
            System.out.println(string);
        }
        //3.2迭代器
        Iterator it=treeSet.iterator();
        while (it.hasNext()){
            System.out.println(it.next());
        }
        //4.判断
        System.out.println(treeSet.contains("abc"));
    }
}
================================================================
    package com.zhang.kuangjia.de;

import com.zhang.kuangjia.de.Person;

import java.util.TreeSet;

//使用TreeSet保存数据
//要求元素必须实现Comparable接口,若接口中的compareTo方法的返回值为0,则被认为是重复元素
public class Demo14 {
    public static void main(String[] args) {
        //创建集合
        TreeSet<Person> person=new TreeSet<>();
        //1.添加元素
        Person p1=new Person("李",25);
        Person p2=new Person("谭",30);
        Person p3=new Person("邢",26);
        person.add(p1);
        person.add(p2);
        person.add(p3);
        System.out.println(person.size());//这样会报错ClassCastException(类型转换异常),必须实现comparable接口
        System.out.println(person.toString());
        //2.删除
        //person.remove(p1);
        //person.remove (new Person("李",25));
        //3.遍历
        //4.判断   和之前的差不多
    }
}
/*
package com.zhang.kuangjia.de;

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

    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 int compareTo(Person o) {
        //比一下姓名,年龄(比较规则:先按姓名比,再按年龄比)
        int n1=this.getName().compareTo(o.getName());//拿当前对象的名字和传递过来的o进行比较
        int n2=this.age-o.getAge();
        return n1==0?n2:n1;//若n1==0,则表示姓名是一样的
    }
}

 */
package com.zhang.kuangjia.DEDE;


import com.zhang.kuangjia.DEDE.Person;

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

//TreeSet集合的使用
//接口Comparator:实现定制比较(比较器),在treeSet中添加数据的时候可以不用实现comparable接口,而是自己取定制一些比较规则
public class Demo15 {
    public static void main(String[] args) {
        //创建集合并指定规则 实例化的时候,TreeSet有个构造方法
        TreeSet<Person> person=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("邢",26);
        Person p2=new Person("谭",30);
        Person p3=new Person("李",25);
        person.add(p1);
        person.add(p2);
        person.add(p3);
        System.out.println(person.toString());
    }

}
/*
package com.zhang.kuangjia.DEDE;

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

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

 */


================================================================package com.zhang.kuangjia;

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

//使用TreeSet集合实现字符串按长度进行排序
//要用到Comparator接口实现定制比较
public class Demo16 {
    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());//[cat, lisi, xian, beijing, nanjing, pingguo, zhangsan, helloworld]
    }

}

Map集合

21

将键映射到值的对象

Map父接口

  • 特点:存储一对数据(Key-Value),无序、无下标、键不可重复,值可重复
  • 方法

V put(K key,V value) //将对象存入到集合中,关联键值,key重复则覆盖原值

Object get(Object key) 根据键获取对应的值

keySet //返回所有key

Collectionvalues() //返回包含所有值的Collection集合

Set<Map.Entry<>K,Y> //键值匹配的Set集合

package com.zhang.kuangjia.Map;

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

//Map接口的使用
//特点:存储键值对、键不能重复、值可以重复、无序
public class Demo17 {
    public static void main(String[] args) {
       //创建Map集合
        Map<String,String> map=new HashMap<>();//map是接口,只能new其实现类
        //1.添加元素
        map.put("cn","中国");
        map.put("usa","美国");
        map.put("uk","英国");
        map.put("cn","zhogguo");//第一个与这个的键是相同的,书橱时,中国被zhongguo覆盖了,即键重复时,值被覆盖
        System.out.println(map.size());
        System.out.println(map.toString());//{usa=美国, uk=英国, cn=zhogguo}
        //2.删除,使用键来删除
        //map.remove("cn");
        //System.out.println(map.toString());//{usa=美国, uk=英国}
        //3.遍历
        //3.1使用keySet() 该方法返回值是所有key的set集合
        Set<String> keyset=map.keySet();//先拿到所有key的set集合,再遍历key
        for (String key:keyset) {//遍历的是key
            //System.out.println(key);//usa uk cn
            //get() 通过key来获取value
            System.out.println(key+":"+map.get(key));//usa:美国  uk:英国  cn:zhogguo
        }
        //3.2使用entrySet()方法,返回值为类型为entry(映射对或键值对,把map集合中的key和value封装成一个entry对象,一个entry代表一个映射对,既有key又有value)
        Set<Map.Entry<String,String>> entries=map.entrySet();//也是一个set集合,Map.Entry是一个内部接口,是在map里写了一个内部接口,entry代表一个映射对
        for (Map.Entry<String,String> entry:entries) {
            System.out.println(entry.getKey()+":"+entry.getValue());
        //entrySet的效率高于keySet
        }
        //4.判断
        System.out.println(map.containsKey("cn"));
        System.out.println(map.containsValue("riben"));
    }
}

Map集合的实现类

  • HashMap
package com.zhang.kuangjia.Map;


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

import com.zhang.kuangjia.Map.Student;
//HashMap集合的使用
//存出结构:哈希表(数组+链表+红黑树)
public class Demo18 {
    public static void main(String[] args) {
        //创建集合
        //hashMap刚创建时,为了节省空间,数组table=null,当添加第一个元素时,table的容量调整为16
        //当元素个数大于阈值时(容量的75%),扩容为原容量的2倍,
        HashMap<Student,String> student=new HashMap<Student,String>();//Student作为key,String作为value
        //1.添加元素
        Student s1=new Student("张三",12);
        Student s2=new Student("李四",8);
        Student s3=new Student("王五",10);
        student.put(s1,"北京");//key不可重复   value可重复
        student.put(s2,"山海");
        student.put(s3,"上海");
        student.put(new Student("张三",12),"上海");
        //想只要姓名学号相同就代表同一个人,不再添加,此时要用到key的hashcodes和equals作为重复的判断,重写hashcode和equals
        System.out.println(student.size());
        System.out.println(student.toString());
        //2.删除
        student.remove(s1);
        System.out.println(student.size());
        //3.遍历
        //3.1使用keySet
        for (Student key:student.keySet()) {
            System.out.println(key.toString()+":"+student.get(key));
        }
        //3.2使用entrySet
        for (Map.Entry<Student,String> entry:student.entrySet()) {
            System.out.println(entry.getKey()+":"+entry.getValue());
        }
        //4.判断
        System.out.println(student.containsKey(s1));
        System.out.println(student.containsKey(new Student("张三",25)));
        System.out.println(student.containsValue("上海"));
    }
}
/*
package com.zhang.kuangjia.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 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);
    }

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

}

 */

  • Hashtable(基本不用了,了解)

线程安全,运行效率慢,不允许null作为key或value

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

  • map集合的另一个实现类:TreeMap

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

package com.zhang.kuangjia;

import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;
import com.zhang.kuangjia.Map.Student;
//TreeMap的使用
public class Demo19 {
    public static void main(String[] args) {
        //新建集合
        TreeMap<Student,String> treeMap=new TreeMap<Student,String>();
        /*//或在新建集合的时候就用比较器,就不用实现接口了
        TreeMap<Student,String> treeMap=new TreeMap<Student,String>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                //在里面指定比较规则,和之前的差不多
                return 0;
            }
        });*/
        //1.添加元素
        Student s1=new Student("张三",12);
        Student s2=new Student("李四",8);
        Student s3=new Student("王五",10);
        treeMap.put(s1,"北京");
        treeMap.put(s2,"上海");
        treeMap.put(s3,"山海");
        System.out.println(treeMap.size());
        System.out.println(treeMap.toString());
        //运行出现了异常ClassCastException(类型转换异常),得让student类实现一个comparable接口,并重写compareto,制定比较规则
        //也可以采用比较强comparator  定制比较,就不用去实现compatable接口了
        //2.删除
        treeMap.remove(s2);
        //3.遍历
        //3.1使用keySet
        for (Student key:treeMap.keySet()) {
            System.out.println(key+":"+treeMap.get(key));
        }
        //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.containsValue("上海"));
        System.out.println(treeMap.containsKey(new Student("王五",10)));
    }
}
/*
package com.zhang.kuangjia.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 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);
    }

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

    @Override
    public int compareTo(Student o) {
        //先比姓名,再比年龄
        int n1=this.name.compareTo(o.name);
        int n2=this.stuNo-o.stuNo;
        return n1==0?n2:n1;
    }
}

 */

Collctions工具类

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

方法:

reverse() 反转集合中元素的顺序

shuffle() 随机充值集合元素的顺序

sort() 升序排序(元素类型必须实现Comparable接口)

package com.zhang.kuangjia;

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

//Collections工具类的使用
public class Demo20 {
    public static void main(String[] args) {
        //创建一个list集合
        List<Integer> list=new ArrayList<>();
        //添加一些元素
        list.add(20);
        list.add(5);
        list.add(12);
        list.add(1);
        list.add(23);
        //sort排序
        System.out.println("排序之前:"+list.toString());//排序之前:[20, 5, 12, 1, 23]
        Collections.sort(list);
        System.out.println("排序之后:"+list.toString());//排序之后:[1, 5, 12, 20, 23]
        //binarySearch二分查找(使用该方法前要排序)
        int i=Collections.binarySearch(list,12);
        System.out.println(i);//2  i是位置
        //copy 复制
        //再新建一个目标集合dest
        List<Integer> dest=new ArrayList<>();
        for (int k = 0; k < list.size(); k++) {
            dest.add(0);
        }
        Collections.copy(dest,list);//直接这样会报错:IndexOutOfBoundsException,dest(0)和list(5)的大小不一致,list复制到dest是要求两集合的大小要一样,只能做一个循环操作,使list和dest大小一样
        System.out.println(dest.toString());
        //reverse反转
        Collections.reverse(list);
        System.out.println("反转之后:"+list.toString());//反转之后:[23, 20, 12, 5, 1]
        //shuffle 将集合中的元素打乱
        Collections.shuffle(list);
        System.out.println("打乱之后:"+list.toString());//打乱之后:[12, 5, 23, 20, 1] 当然,每次运行打乱都不一样
        //补充:
        //list集合转为数组
        Integer[] arr=list.toArray(new Integer[0]);  //[0]数组长度  这个长度由你给定,若该长度小于list的长度,则取list的长度,若大于list的长度,就取这个大的长度//返回值是一个数组
        System.out.println(arr.length);//5
        System.out.println(Arrays.toString(arr));//[5, 12, 23, 1, 20]
        //数组转为集合,转为集合后的集合是一个受限集合,不能添加或删除
        //建个数组
        String[] name={"张三","李四","王五"};
        List<String> list1=Arrays.asList(name);//返回值为list集合
        //list1.add("zhao");//报错
        //list1.remove("王五");//报错
        System.out.println(list1);
        //特殊的  将基本类型的数组转为集合时,需要修改类型为包装类型
        /*int[] nums={200,300,400};
        List<Integer> list2=Arrays.asList(nums);报错*/
        //写为这样就不报错了
        Integer[] nums={200,300,400};
        List<Integer> list2=Arrays.asList(nums);
        System.out.println(list2);
    }

}

posted on 2021-01-22 16:31  懵逼的程序小白  阅读(66)  评论(0)    收藏  举报