集合的学习以及应用

集合

是一个容器

数组:原生的数组,删除元素不方便,长度是固定的,容量不够时,还需要自己进行扩容,现实中,程序在运行时,数据会时刻变化的,

所以为满足程序运行中各种变化的数据存储需求,java语言中,封装了许多的类,来帮助我们完成不同数据的存储,这些类就被称为集合类。

核心思想我们要学习一些类,这些类对数组进行了封装,让我们更加方便使用

4个接口 7个实现类

单列集合

Collection

List 可以存储重复元素

ArrayList 数据链表

LinkedList链表列表

Vector 线程安全的数组列表

set

HashSet 哈希集合

TreeSet 树形集合

Map 双列集合

键 :值

HashMap 哈希集合

TreeMap 树形集合

java中提供了不同结构的容器类,来存储不同的数据

单列集合

Collection

List

List接口实现类的集合,可以存储重复元素,有序地(按照添加顺序排列),还可以通过索引操作元素

ArrayList 数组列表

由于数组中的每个空间都是连续的,所以查询非常方便可以直接通过下标获取指定位置的元素,但是要删除元素时就比较麻烦删除后其他元素要进行位移

package com.ffyc.javapi.day1;
​
import java.util.ArrayList;
​
public class ArrayListDemo1 {
    /*
        ArrayList 数组列表 可以动态增长数组
        ArrayList<E> 建议使用泛型的语法,为集合的数据设定数据类型
        java中的集合,建议值存储一种类型
​
        底层有一个transien Object[] elementDate;数组
        add():默认是向集合的末尾添加元素,首次底层会初始化一个长度为10的数组,当元素添加满了的时候,
        会发生扩容操作,扩容为原来的1.5倍
     */
    public static void main(String[] args) {
        ArrayList<String> alist = new ArrayList<String>();
                  alist.add("a");
                  alist.add("b");
                  alist.add("c");
                  alist.add("d");
                  alist.add("e");
                  alist.add("f");
                  alist.add("g");
                  alist.add("h");
                  alist.add("i");
                  alist.add("j");
                  alist.add(0,"A");//指定位置田家庵
//                  alist.clear();//清空
                  alist.remove(1);//删除指定位置的元素
                  alist.remove("h");//删除指定内容的元素
                  System.out.println(alist.size());//获取集合中实际有多少个元素
                  System.out.println(alist.get(4));//查找指定位置元素
​
                  System.out.println(alist);
    }
}

package com.ffyc.javapi.day1;
​
import java.util.ArrayList;
import java.util.Arrays;
​
public class ArrayListDemo2 {
    public static void main(String[] args) {
        ArrayList<String> alist = new ArrayList<String>();
        alist.add("a");
        alist.add("b");
        alist.add("c");
        alist.add("d");
        alist.add("e");
        alist.add("f");
        alist.add("g");
        alist.add("h");
        alist.add("i");
        alist.add("j");
        System.out.println(alist.contains("d"));//是否包含某个属性
        System.out.println(alist.isEmpty());//判断集合是否为空
        alist.ensureCapacity(20);//扩容底层数组为20
        System.out.println(alist.indexOf("c"));//查找某个元素在数组中首次出现的位置,前到后
        System.out.println(alist.lastIndexOf("c"));//查找某个元素在数组中首次出现的位置,后到前
        alist.set(0,"A");//代替
        Object[] objs = alist.toArray();//将集合转为Object类型
        String [] arrays = alist.toArray(alist.toArray(new String[alist.size()]));//将集合转为指定类型
        System.out.println(Arrays.toString(arrays));
        System.out.println(alist);
    }
}

LikedList 链表列表

每一个数据存储在一个Node类中 Node节点

Node

prev

data

next

链表结构,对外只提供头,尾节点,没词查询元素时,非常慢,必须从头或者从尾开始,如果从中间删除某个元素时非常快,只需要改变next节点的内存地址即可,元素不需要移动位置

查询慢,但是中间增加删除快 方法和ArrayList基本相同

package com.ffyc.javapi.day1;
​
import java.util.LinkedList;
​
public class LinkedListDemo1 {
    /*
        LinkedList
            add();向链表中添加元素,不存在扩容问题。
     */
    public static void main(String[] args) {
        LinkedList<String> llist = new LinkedList<>();
        llist.add("a");
        llist.add("b");
        llist.add("c");
        llist.add("d");
        llist.add("e");
        llist.add("f");
        llist.add("g");
        llist.add("h");
        llist.add("i");
        llist.add("j");
        llist.add("k");
        llist.addFirst("S");//向头节点添加元素
        llist.add(1,"A");
        System.out.println(llist.getFirst());//获得第一个元素
        System.out.println(llist.removeFirst());//删除并返回第一个元素
        System.out.println(llist.get(3));
    }
}

Vector数组列表(线程安全的)

package com.ffyc.javapi.day1;
​
import java.util.Vector;
​
public class VectorDemo {
    /*
        Vector 数组链表
            里面的方法都添加了synchronized关键字,是线程安全的
     */
    public static void main(String[] args) {
        Vector<Integer> v = new Vector<>();
        v.add(1);
        v.add(2);
        v.add(3);
        v.add(4);
        v.add(5);
        v.add(6);
        v.add(7);
        v.add(7);
        v.add(9);
        v.add(10);
        System.out.println(v);
    }
}

集合遍历

package com.ffyc.javapi.day1;
​
import java.util.ArrayList;
​
public class ListFor {
    public static void main(String[] args) {
        ArrayList<String> alist = new ArrayList<String>();
        alist.add("a");
        alist.add("b");
        alist.add("c");
        alist.add("d");
        alist.add("e");
        alist.add("f");
        alist.add("g");
        alist.add("h");
        alist.add("i");
        alist.add("j");
        /*
            for循环进行遍历
            在遍历时,是可以删除元素的,删除时需要注意元素的移动,以及索引的变化
         */
        for(int i = 0;i< alist.size();i++){
            String item = alist.get(i);
            System.out.println(item);
        }
        /*
            增强for循环
            在遍历元素是不允许从集合中删除元素,如果从集合中删除元素就会报ConcurrentModificationException
         */
//        for(String item : alist){
//            if(item.equals("c")){
//                alist.remove(item);
//            }
//            System.out.println(item);
//        }
    }
}

Iterator关键字

package com.ffyc.javapi.day2;
​
import java.util.ArrayList;
import java.util.Iterator;
​
public class ListFor2 {
    public static void main(String[] args) {
        ArrayList<String> alist = new ArrayList<String>();
        alist.add("a");
        alist.add("b");
        alist.add("c");
        alist.add("d");
        alist.add("e");
        alist.add("f");
        alist.add("g");
        alist.add("h");
        alist.add("i");
        alist.add("j");
        /*
            java中提供了对于集合进行遍历的迭代器
            里面维护了一个指针(计数器),当删除元素时,计数器会自动回退
         */
        Iterator<String> it = alist.iterator();
        while (it.hasNext()){//判断有没有下一个元素
            String item = it.next();//取出元素
            if(item.equals("c")){
                it.remove();//使用迭代器方法进行删除元素
            }
        }
        System.out.println(alist);
    }
}

ListIterator关键字

package com.ffyc.javapi.day2;
​
import java.util.ArrayList;
import java.util.ListIterator;
​
public class ListFor3 {
    public static void main(String[] args) {
        ArrayList<String> alist = new ArrayList<String>();
        alist.add("a");
        alist.add("b");
        alist.add("c");
        alist.add("d");
        alist.add("e");
        alist.add("f");
        alist.add("g");
        alist.add("h");
        alist.add("i");
        alist.add("j");
        ListIterator<String> lit = alist.listIterator();
        while (lit.hasNext()){
            String item = lit.next();
            System.out.println(item);
        }
        //从后向前遍历取前一个元素
        ListIterator<String> li = alist.listIterator(alist.size());
        while (li.hasPrevious()){
            String item = li.previous();
            System.out.println(item);
        }
    }
}

Set

Set接口实现类的集合,不可以存储重复元素,添加时,会自定的判断,有的是无序的,有的是有序的,

HashSet:

HashSet:是无序的,即不按照添加的顺序业不按照自然顺序存放

是调用hsahCode()方法进行计算hash值,为了更快速判段

但是hash判断是不安全·的

当hash值相同时再调用equals方法判断内容是否相同,保证了安全

package com.ffyc.javapi.day2;
​
import java.util.HashSet;
​
public class HashSetDemo1 {
    public static void main(String[] args) {
        /*
            HashSet不能存储重复元素,且存储的元素是无序的
​
            添加元素时是如何去除重复元素的
            判断元素是否重复时没有直接使用equals()方法进行判断,因为效率低
            java中在比较是否重复时,先是调用hashCode(),计算出内容的hash值(整数)
            两个整数判断是否相等,是比较简单并且快,但是不同内容计算出来的hash值有可能相同
            当hash值出现相同时再调用equals()方法进行判断,
            、这样即安全又快。
​
            存储自定义对象时,类中默认没写hashCode();equals都调用的是Object类中
                Object中hashCode方法,默认获取的对象是内存地址
         */
        HashSet<String> haset = new HashSet<>();
        haset.add("b");
        haset.add("c");
        haset.add("r");
        haset.add("a");
        haset.add("通话");
        haset.add("种地");
        haset.add("e");
        haset.add("a");
​
        System.out.println(haset.contains("a"));
//        haset.clear();
        System.out.println(haset.isEmpty());
        System.out.println(haset.size());
        System.out.println(haset);
    }
}

重写HashCoad方法
​
package com.ffyc.javapi.day2;
​
​
import java.util.Objects;
​
public class HashSetDemo2 {
    private int num;
    private String name;
​
    public HashSetDemo2(int num, String name) {
        super();
        this.num = num;
        this.name = name;
    }
​
    public int getNum() {
        return num;
    }
​
    public void setNum(int num) {
        this.num = num;
    }
​
    public String getName() {
        return name;
    }
​
    public void setName(String name) {
        this.name = name;
    }
​
    @Override
    public String toString() {
        return "Car{" +
                "num=" + num +
                ", name='" + name + '\'' +
                '}';
    }
​
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
​
        HashSetDemo2 that = (HashSetDemo2) o;
​
        if (num != that.num) return false;
        return name != null ? name.equals(that.name) : that.name == null;
    }
​
    @Override
    public int hashCode() {
        int result = num;
        result = 31 * result + (name != null ? name.hashCode() : 0);
        return result;
    }
}
测试方法
package com.ffyc.javapi.day2;
​
import java.util.HashSet;
​
public class HashSetDemo3 {
    public static void main(String[] args) {
        HashSetDemo2 car1 = new HashSetDemo2(101,"宝马1");
        HashSetDemo2 car2 = new HashSetDemo2(102,"宝马2");
        HashSetDemo2 car3 = new HashSetDemo2(103,"宝马3");
        HashSetDemo2 car4 = new HashSetDemo2(101,"宝马1");
        HashSetDemo2 car5 = new HashSetDemo2(104,"宝马5");
        HashSet<HashSetDemo2> hset = new HashSet<>();
        hset.add(car1);
        hset.add(car2);
        hset.add(car3);
        hset.add(car4);
        hset.add(car5);
        System.out.println(hset);
    }
}

TreeSet

TreeSet:是有序地(按照自然顺序存放)

set中添加的类中必须要实现Comparable接口,支持比较大小进行排序

package com.ffyc.javapi.day2;
​
import java.util.TreeSet;
​
public class TreeSetDemo1 {
    public static void main(String[] args) {
        /*
            不能存储重复元素
            可以按照自然顺序排序
         */
        TreeSet<String> tset = new TreeSet<>();
        tset.add("c");
        tset.add("b");
        tset.add("a");
        tset.add("d");
        tset.add("c");
        System.out.println(tset);
    }
}

package com.ffyc.javapi.day2;
​
import java.util.TreeSet;
​
public class TreeSetDemo2 {
    public static void main(String[] args) {
        /*
            不能存储重复元素
            可以按照自然顺序排序
            向treeSet中添加元素的类,必须要实现Comparable接口,支持比较大小进行排序
​
         */
        Car car1 = new Car(101,"宝马1");
        Car car2 = new Car(102,"宝马2");
        Car car3 = new Car(103,"宝马3");
        Car car4 = new Car(101,"宝马1");
        Car car5 = new Car(104,"宝马5");
        TreeSet<Car> tset = new TreeSet<>();
        tset.add(car1);
        tset.add(car2);
        tset.add(car3);
        tset.add(car4);
        tset.add(car5);
        System.out.println(tset);
    }
}
写car类
package com.ffyc.javapi.day2;
​
public class Car implements Comparable<Car>{
    private int num;
    private String name;
​
    public Car(int num, String name) {
        super();
        this.num = num;
        this.name = name;
    }
​
    public int getNum() {
        return num;
    }
​
    public void setNum(int num) {
        this.num = num;
    }
    public String getName() {
        return name;
    }
​
    public void setName(String name) {
        this.name = name;
    }
​
    @Override
    public String toString() {
        return "Car{" +
                "num=" + num +
                ", name='" + name + '\'' +
                '}';
    }
​
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
​
        Car car = (Car) o;
​
        if (num != car.num) return false;
        return name != null ? name.equals(car.name) : car.name == null;
    }
​
    @Override
    public int hashCode() {
        int result = num;
        result = 31 * result + (name != null ? name.hashCode() : 0);
        return result;
    }
​
    @Override
    public int compareTo(Car o) {
        return this.num-o.num;
    }
}

遍历方式

set集合不支持索引操作,不能用普通for循环

增强for循环

迭代器遍历 只支持Iterator关键字进行遍历

package com.ffyc.javapi.day2;
​
import java.util.ArrayList;
import java.util.Iterator;
​
public class ListFor2 {
    public static void main(String[] args) {
        ArrayList<String> alist = new ArrayList<String>();
        alist.add("a");
        alist.add("b");
        alist.add("c");
        alist.add("d");
        alist.add("e");
        alist.add("f");
        alist.add("g");
        alist.add("h");
        alist.add("i");
        alist.add("j");
        System.out.println(alist);
        /*
            java中提供了对于集合进行遍历的迭代器
            里面维护了一个指针(计数器),当删除元素时,计数器会自动回退
         */
        Iterator<String> it = alist.iterator();
        while (it.hasNext()){//判断有没有下一个元素
            String item = it.next();//取出元素
            if(item.equals("c")){
                it.remove();//使用迭代器方法进行删除元素
            }
        }
        System.out.println(alist);
    }
}

package com.ffyc.javapi.day2;
​
import java.util.ArrayList;
import java.util.ListIterator;
​
public class ListFor3 {
    public static void main(String[] args) {
        ArrayList<String> alist = new ArrayList<String>();
        alist.add("a");
        alist.add("b");
        alist.add("c");
        alist.add("d");
        alist.add("e");
        alist.add("f");
        alist.add("g");
        alist.add("h");
        alist.add("i");
        alist.add("j");
        ListIterator<String> lit = alist.listIterator();
        while (lit.hasNext()){
            String item = lit.next();
            System.out.println(item);
        }
        //从后向前遍历取前一个元素
        ListIterator<String> li = alist.listIterator(alist.size());
        while (li.hasPrevious()){
            String item = li.previous();
            System.out.println(item);
        }
    }
}

Map

双列数据存储

键-->值

键值映射

键不能重复 值可以重复

每个键最多只能映射到一个值

HashMap

package com.ffyc.javapi.day2;
​
import java.util.Collection;
import java.util.HashMap;
import java.util.Set;
​
public class HashMapDemo {
    public static void main(String[] args) {
        /*
            Map 键值对形式进行存储
                键不可重复,值可以重复
            HashMap
                键是无序的,只能存储一个为null的值
         */
        HashMap<String,String> map =  new HashMap<>();
        map.put("a","aa");
        map.put("z","zz");
        map.put("s","ss");
        map.put("h","hh");
        map.put("a","aaa");
​
//        map.clear();//清空所有键值对
//        map.remove("a");//删除指定的key
        System.out.println(map.get("h"));//获取值
        System.out.println(map.containsKey("h"));//判断是否包含指定的key
        System.out.println(map.containsValue("hh"));//包含值
        System.out.println(map.isEmpty());
        System.out.println(map.size());
//        Collection<String> list= map.values();
//        System.out.println(list);
        Set<String> keyset=  map.keySet();//获取map中所有的key
        for(String key :keyset){
            String v =  map.get(key);
            System.out.println(key+"::"+v);
        }//通过key进行遍历
        System.out.println(map);
    }
}

HashMap遍历

package com.ffyc.javapi.day3;
​
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
​
public class HashMapDemo3 {
    public static void main(String[] args) {
        HashMap<String,String> map =  new HashMap<>();
        map.put("a","aa");
        map.put("z","zz");
        map.put("s","ss");
        map.put("h","hh");
        map.put("a","aaa");
        /*
            方式一:通关keySet();获取map中所有的key的集合
            变相的遍历map
            Set<String> keySet = map.keySet();
        for(String key : keySet){
            System.out.println(map.get(key));
        }
            方式二:在遍历时,将key-value元素,封装到一个Entry对象中,Entry对象中包含了key和Value
         */
        Set<Map.Entry<String,String>> entrySet = map.entrySet();
        for(Map.Entry<String,String> entry : entrySet){
            System.out.println(entry.getKey()+":"+entry.getValue());
        }
    }
}

TreeMap

package com.ffyc.javapi.day3;
​
import java.util.TreeMap;
​
public class TreeMapDemo {
    public static void main(String[] args) {
        /*
            是一个键值对的存储
            可以根据键进行排序
            键的类型要实现Comparable接口,来进行排序
​
         */
        TreeMap<String,Integer> tmap = new TreeMap<>();
        tmap.put("c",2);
        tmap.put("b",3);
        tmap.put("a",1);
        tmap.put("d",4);
        tmap.put("c",33);
        System.out.println(tmap);
    }
}

Hashtable

package com.ffyc.javapi.day3;
​
import java.util.Hashtable;
​
public class HashtableDemo1 {
    public static void main(String[] args) {
        /*
            键值对存储
            Hashtable底层结构与HashMap类似,但是Hashtable是线程安全的
            Hashtable中不能存储为null的key
         */
        Hashtable<String,String> ht = new Hashtable<>();
        ht.put("a","a");
        ht.put("s","s");
        ht.put("w","w");
        ht.put("g","g");
        ht.put("a","a");
        System.out.println(ht);
    }
}

Collections

提供了关于集合操作的方法类似于Arrays类

常用方法实现

package com.ffyc.javapi.day3;
​
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
​
public class CollectionsDemo1 {
    public static void main(String[] args) {
        /*
            addAl l(Collection<? super T> c, T... elements);
            binarySearch(List<? extends Comparable<? super T>> l ist, T key)
            sort(List<T> l ist)
            sort(List<T> l ist, Comparator<? super T> c)
            swap(List<?> l ist, int i, int j)
            copy(List<? super T> dest, List<? extends T> src) ; 注意 dest size需大于等于src.size
            emptyList() 返回为空的集合,不能添加数据
            fi l l(List<? super T> l ist, T obj)
            max(Col lection<? extends T> col l)//返回最大最小值
            min(Col lection<? extends T> col l)
            replaceAl l(List<T> l ist, T oldVal, T newVal)
            reverse(List<?> l ist)
            shuffle(List<?> l ist) 随机排序
            copy(dest,src)集合复制
         */
//        CollectionsDemo1.test(1,2,3);
        ArrayList<String> list = new ArrayList<>();
        list.add("a");
        list.add("c");
        list.add("b");
        list.add("d");
//        Collections.addAll(list,"c","b","d");//加入数组
        System.out.println(Collections.binarySearch(list,"b"));//二分查找
        Collections.sort(list);//排序
        Collections.swap(list,0,3);//交换指定位置元素
        ArrayList<String> dest = new ArrayList<>();
        dest.add("1");
        dest.add("2");
        dest.add("3");
        dest.add("4");
        dest.add("5");
        Collections.copy(dest,list);//把原数组复制到目标数组里面去,目标数组的size()大于等于原数组的size();
​
        System.out.println(list);
        Collections.reverse(list);//逆序
        Collections.shuffle(list);//随机排序
        System.out.println(dest);
//        List emptyList =  Collections.emptyList();//返回一个空集合,这个空集合是一个内部类,不能使用,为了避免出现空指针
//        Collections.fill(list,"+");//用指定的内容填充集合
        System.out.println(list);
    }
    /*
        int...a可变长度参数本质是一个数组
        在一个参数链表中,只能有一个可变长度的参数,并且只能放在参数链表的最后一位
     */
    public static void test(int b, int...a){
        System.out.println(Arrays.toString(a));
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值