JAVA学习day08

Java集合框架详解

day08所看的视频来源

【千锋】最新版 Java集合框架详解

集合的概念

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

Collection接口

Collection体系集合

Collection体系集合

Collection父接口

  • 特点:代表一组任意类型的对象,无需、无下标、不能重复
  • 方法
    • boolean add(Object obj) //添加一个对象
    • boolean addAll(Collection c) //将一个集合中的所有对象添加到此集合中
    • void clear() //清空此集合中的所有对象
    • boolean contains(object o) //检查此集合中是否包含o对象
    • boolean equals(Object o) //比较此集合是否与指定对象相等
    • boolean isEmpty() //判断此集合是否为空
    • boolean remove(Object o) //在此集合中移除o对象
    • int size() //返回此集合中的元素个数
    • Object[] toArray() //将此集合抓换成数组
package com.jihe.demo01;

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

/**
 * Collection接口的使用
 * 1.添加元素
 * 2.删除元素
 * 3.遍历元素
 * 4.判断
 * @author wgy
 */

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

//        // * 2.删除元素
//        collection.remove("榴莲");
//        collection.clear();
//        System.out.println("删除之后:"+collection.size());

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

        System.out.println("------------------------");
        //3.2迭代器(迭代器专门用来迭代集合的一种方式)
        //hasNext();有没有下一个元素
        //next();获取下一个元素
        //remove();删除当前元素
        Iterator it = collection.iterator();
        while(it.hasNext()){
            String s = (String)it.next();
            System.out.println(s);
//            it.remove();//删除元素,不能使用collection.remove(s);
        }
//        System.out.println("元素个数:"+collection.size());//若删除后元素个数:0

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

}

List接口与实现类

List子接口

  • 特点:有序、有下表、元素可以重复
  • 方法:
    • void add(int index, Objext o) //在index位置插入对象o
    • boolean addAll(int index, Collection c) //将一个集合中的元素添加到此集合中的index位置
    • Objext get(int index) //返回集合中指定位置的元素
    • List subList(int fromIndex, int toIndex) //返回fromIndex和toIndex之间的集合元素
package com.jihe.demo01;

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

/**
 * List子接口的使用
 * 特点:1.有序有下标 2.可以重复i
 */

public class Demo03 {
    public static void main(String[] args) {
        //先创建集合对象
        List list = new ArrayList<>();
        //1.添加元素
        list.add("苹果");
        list.add("小米");
        list.add(0,"华为");
        System.out.println("元素个数:"+list.size());//元素个数:3
        System.out.println(list.toString());//[华为, 苹果, 小米]

//        //2.删除元素
//        list.remove(0);
//        System.out.println("删除之后:"+list.size());//删除之后:2
//        System.out.println(list.toString());//[苹果, 小米]

        //3.遍历
        //3.1使用for遍历
        System.out.println("---------使用for---------");
        for(int i=0; i
package com.jihe.demo01;

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

/**
 * list的使用
 */

public class Demo04 {
    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());//元组个数5
        System.out.println(list.toString());//[20, 30, 40, 50, 60]

        //2.删除操作
        list.remove(new Integer(20));//如果想要删除值为20的就要先new Interger把基本类型转成引用类型
        System.out.println("删除元素:"+list.size());//删除元素:4
        System.out.println(list.toString());//[30, 40, 50, 60]

        //3.补充方法subList,返回自己和
        List sublist = list.subList(1,3);//包含1不包含3
        System.out.println(sublist.toString());//[40, 50]
    }

}

List实现类

  • ArrayList[重点]:
    • 数组结构实现,查询快、增删慢
    • JDK1.2版本加入的,运行效率快、线程不安全
  • Vector:
    • 数组结构实现,查询快、增删慢
    • JDK1.0版本的,运行效率慢、线程安全
  • LinkedList:
    • 链表结构实现,增删快,查询慢

ArrayList使用

  • 特点:有序、有下表、元素可以重复
  • 使用remove()方法的时候,想要做到用相同数值来删除对象,就需要重写方法equals()比较两者数值return true,否则比较的是地址无法用相同数值为条件remove()对象

ArrayList源码分析

  • 源码分析:
    • DEFAULT_CAPACITY = 10; 默认容量
      • 注意:如果没有向集合中添加任何元素时,容量为0,添加一个元素之后,容量为10,扩容原来的1.5倍
    • elementData 存放元素的数组
    • size 实际的元素个数
    • add()添加元素

Vector使用(使用频率不高)

//枚举器遍历
Enumeration en = vector.elements();
while(en.hasMoreElements()){
  String o = (String)en.nextElement();
  sout(o);
}

LinkedList使用

  • 链表结构实现,增删快,查询慢(双向链表)
package com.jihe.demo01;

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

/**
 * LinkedList的使用
 * 存储结构:双向链表
 */

public class Demo02 {
    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(new Student("刘德华",20));
//        System.out.println("删除之后:"+linkedList.size());
//        linkedList.clear();

        //3.遍历
        //3.1for遍历
        System.out.println("----------------for--------------");
        for(int i=0; i

泛型和工具类

泛型概念

  • Java泛型是JDK1.5中引入的一个新特性,其本质是参数化类型,把类型作为参数传递
  • 常见类型有泛型类、泛型接口、泛型方法
  • 语法:
    • T成为类型占位符,表示一种引用类型
  • 好处:
    • 提高代码的重用性
    • 防止类型转换异常,提高代码的安全性
//MyGeneric.java
package com.jihe.demo03;

/**
 * 泛型类
 * 语法:类名
 * T是类型占位符,表示一种引用类型,如果编写多个使用都好隔开
 */

public class MyGeneric {
    //使用泛型T
    //1.创建变量
    T t;

    //2.作为方法的参数,不能T t1 = new T();,因为不知道他是不是私有的
    public void show(T t){
        System.out.println(t);
    }

    //3.泛型作为方法的返回值
    public T getT(){
        return t;
    }
}
//TestGeneric
package com.jihe.demo03;

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

        MyGeneric myGeneric2 = new MyGeneric();
        myGeneric2.t = 100;
        myGeneric2.show(200);//200
        Integer integer = myGeneric2.getT();
    }
}

泛型接口

//MyInterface.java
package com.jihe.demo03;

/**
 * 泛型接口
 * 语法:接口名
 * 注意:不能泛型静态常量
 */

public interface MyInterface {
    String name = "张三";

    T server(T t);
}

两种泛型接口实现

//MyInterfaceImpl.java
//先定义泛型类型,如下定义为String型
package com.jihe.demo03;

public class MyInterfaceImpl implements MyInterface {
    @Override
    public String server(String s) {
        System.out.println(s);
        return null;
    }
}
//MyInterfaceImpl2.java
//使用对象定义泛型类型,也就是实例化的时候,泛型类型和对象类型一直,TestGeneric里可以看出
package com.jihe.demo03;

public class MyInterfaceImpl2 implements MyInterface{
    @Override
    public T server(T t) {
        System.out.println(t);
        return t;
    }
}
//TestGeneric.java
package com.jihe.demo03;

public class TestGeneric {
    public static void main(String[] args) {

        MyInterfaceImpl impl = new MyInterfaceImpl();
        impl.server("xxxxxx");//因为是String定义,所以只能传入String

        MyInterfaceImpl2 impl2 = new MyInterfaceImpl2<>();////泛型T传入Interger类型
        impl2.server(1000);
    }
}

泛型集合

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

import java.util.ArrayList;

public class TestGeneric {
    public static void main(String[] args) {
        //泛型集合
        ArrayList arrayList = new ArrayList();//泛型限定了必须是String才能add
        arrayList.add("xxx");
        arrayList.add("yyy");
        for (String string : arrayList){//因此这里只能是String,而不会出现强制类型转换的问题
            System.out.println(string);
        }

    }
}

Set接口与实现类

Set集合概述

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

Set接口的使用

一般都用HashSet

package com.jihe.demo04;

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

/**
 * 测试Set接口的使用
 * 特点:1.无序、没有下表 2.不能重复
 */

public class Demo01 {
    public static void main(String[] args) {
        //创建集合
        Set set = new HashSet<>();
        //1.添加数据
        set.add("苹果");//add不能加两个一样的,也就是不能重复
        set.add("小米");
        set.add("华为");

        //2.删除
        set.remove("小米");

        //3.遍历【充电】
        //3.1增强for
        System.out.println("-----------增强for---------");
        for(String string : set){
            System.out.println(string);
        }
        System.out.println("-----------使用迭代器---------");
        //3.2使用迭代器
        Iterator it = set.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }

        //4.判断
        System.out.println(set.contains("华为"));
        System.out.println(set.isEmpty());


    }
}

Set实现类

  • HashSet【重点】:
    • 基于HashCode实现元素不重复
    • 当存入元素的哈希码(HashCode)相同时,会调用equals进行确认,如结果为true,则拒绝后者存入
  • TreeSet:
    • 基于排序顺序实现元素不重复
    • 实现了SortedSet接口,对集合元素自动排序
    • 元素对象的类型必须实习Comparable接口,指定排序规则
    • 通过CompareTo(重写后可以比较对象)方法确定是否为重复元素
    • 可以通过两种重写方法如下
//Person.java
package com.jihe.demo04;

import java.util.Objects;

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

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

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

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

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

    @Override
    public int hashCode() {
        return Objects.hash(name, 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;//如果n1不为0则是n1,如果为0就是n2
    }
}
package com.jihe.demo04;

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

/**
 * 使用TreeSet保存数据
 * 存储结构:红黑树
 * 要求:要素必须要实现Comparable接口
 */

public class Demo05 {
    public static void main(String[] args) {
        //创建集合
        TreeSet persons = new TreeSet<>();
        //1.添加元素
        Person p1=new Person("刘德华",20);
        Person p2=new Person("林志玲",22);
        Person p3=new Person("梁朝伟",25);

        persons.add(p1);
        persons.add(p2);
        persons.add(p3);
        System.out.println("元素个数:"+persons.size());
        System.out.println(persons.toString());
        
        
        //直接重写也可以,这样子类里就不用implements Comparable
        TreeSet persons2 = new TreeSet<>(new Comparator() {
            @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 p4=new Person("刘德华",20);
        Person p5=new Person("林志玲",22);
        Person p6=new Person("梁朝伟",25);
        persons2.add(p1);
        persons2.add(p2);
        persons2.add(p3);
        System.out.println(persons.toString());
    }

}

Map接口与实现类

  • 特点:
    • 存储键值对
    • 键不能重复,值可以重复
    • 无序
//Map方法
package com.jihe.demo05;

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

/**
 * Map接口的使用
 * - 特点:
 *   - 存储键值对
 *   - 键不能重复,值可以重复
 *   - 无序
 * -
 */

public class Demo01 {
    public static void main(String[] args) {
        //创建Map集合
        Map map = new HashMap<>();
        //1.添加元素,注意如果key一样,value不一样,会吧value替换掉,也就是覆盖
        map.put("cn","中国");
        map.put("uk","英国");
        map.put("usa","美国");
//        map.put("cn","zhongguo");

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

        //3.遍历
        //3.1使用keySet();
        System.out.println("-----------使用keySet(),增强for--------");
//        Set keyset = map.keySet();
        for (String key : map.keySet()) {//map.keySet()获得的是key集合
            System.out.println(key+"----"+map.get(key));//用map.get(key)获得value

        }

        //3.2使用entrySet();
        System.out.println("-----------使用entrySet(),增强for--------");
//        Set> entries = map.entrySet();
        for(Map.Entry entry : map.entrySet()){//map.entrySet()把key和value一起封装成一个Entry获得
            System.out.println(entry.getKey()+"------------"+entry.getValue());//调用getKey()和getValut()获得
        }

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


    }
}

Map集合的实现类

  • HashMap【重点】
    • JDK1.2版本,线程不安全,运行效率快;允许用null作为key或是value
    • 刚创建HashMap之后没有添加元素table=null,size=0,目的是节省空间
    • HashMap刚创建时,table是null,为了节省空间,当添加第一个元素时候,table容量调整为16
    • 当元素个数大于阈值(16*0.75=12)时,会进行扩容,扩容后为原来的2倍,目的是减少调整元素的个数
    • jdk1.8当每个链表长度大于8,并且元素个数大于64时,会调整为红黑树,目的是提高执行效率
    • jdk1.8当链表长度小于6时,调整成链表
    • jdk1.8以前,链表是头插入,jdk1.8以后是尾插入
  • Hashtable(基本不用了):
    • JDK1.0版本,线程安全,运行效率慢;不允许null作为key或是value
  • Properties:
    • Hashtable的子类,要求key和value都是String。通常用于配置文件的读取‘
  • TreeMap:
    • 实现了SortedMap接口(是Map的子接口),可以对key自动排序

Collections工具类

package com.jihe.demo05;

import java.util.*;

public class Demo02 {
    public static void main(String[] args) {
        List list = new ArrayList<>();
        list.add(20);
        list.add(5);
        list.add(12);
        list.add(30);
        list.add(6);
        //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 dest = new ArrayList<>();
        for (int k = 0; k < list.size(); k++) {
            dest.add(0);
        }
        Collections.copy(dest,list);//两个数组大小要一样才能copy,所以先for添加0
        System.out.println(dest.toString());

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

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

        //补充,list转成数组
        Integer[] arr = list.toArray(new Integer[0]);
        System.out.println(arr.length);//是大的那个的长度,所以0就默认变成list的长度
        System.out.println(Arrays.toString(arr));

        //数组转成集合
        String[] names = {"张三","李四","王五"};
        //转换后的集合是一个受限集合,不能添加和删除,也就是不能add和remove
        List list2 = Arrays.asList(names);
        System.out.println(list2);

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

你可能感兴趣的:(JAVA学习day08)