集合(容器)

本文详细介绍了Java中的集合概念,包括数组的创建与存储特性,集合(尤其是List, Map, Set)的不同结构(链表、哈希和树)及其用途。重点讲解了Collection接口、ArrayList、LinkedList、HashSet、TreeSet以及HashMap的使用和迭代方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

集合的概念

数组(容器),创建一个指定长度的数组,使用数组来储存多个数据

缺点:程序运行时,数组数量是变化的,但是数组长度一旦给定,就不能改变.

频繁的扩容是不可取的

优点:查询速度快.

集合(容器),对数据的操作是多种多样的,增删比较多,查询较少,链表结构

针对程序中,这种不同存储操作需求,所有java 语言提供了许多不同的存储结构.(对底层结构进行包装),建议存储同一类型.

数组结构,链表结构,哈希结构,树结构

集合体系

 

Collection接口(list,map,set,collection)

作为单列集合中顶级接口,里面定义了单列集合共有的方法.方法以增,删,改,查,判断,转换为主

package Collection;

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

public class CollectionDemo1 {
    public static void main(String[] args) {
        Collection<String> c = new ArrayList<>();//E是jdk5之后的语法--泛型
        c.add("a");
        c.add("b");
        c.add("c");
        c.add("d");
        Collection<String> c1 = new ArrayList<>();
        c1.add("d");
        c1.add("e");
        c1.add("f");
        c1.add("g");
        Collection<Integer>c2=new ArrayList();
        c2.add(1);//自动装箱,不用引号
        c2.add(2);
        c2.add(3);
        c1.addAll(c);//把一个集合全部添加到另一个集合
        c1.clear();//清空集合中所有的元素
        c1.remove("c");//在集合中指定删除某一个元素
        System.out.println(c.isEmpty());//判断集合中个数是否为空
        System.out.println(c.equals(c1));//比较集合中的两个元素内容是否相等
        System.out.println(c.remove("b"));//删除指定元素,成功返回true,没有成功返回false
        System.out.println(c.retainAll(c1));//在c中保留c1中交集的元素,发生变化返回true,没有返回false
        System.out.println(c.size());//输出该集合的长度,数组length视为属性;length()字符串长度;size:集合长度
        String []object=c1.toArray(new String[c1.size()]) ;
        System.out.println(c);
        System.out.println(c1);
    }
}

List接口及其实现类

共有的特点:有序(按照,添加顺序排序),可以有重复元素

ArrayList:底层是通过数组实现的,是可以变长的;查询快,中间增删慢

LinkedList:底层是通过链表实现,查询慢(必须从头/尾),中间增删快,只需要改变后继节点位置

Vector:底层是数组实现,线程安全的

add();向集合中添加元素时,底层会默认创建一个长度为10的object类型数组

List接口集合迭代

4种方式:

for循环遍历,增强for循环,Iterator迭代器,ListIteractor迭代器(只支持List接口下的实现类)

public class ArrayListDemo {
    public static void main(String[] args) {
        ArrayList<String> list=new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        list.add("d");
        list.add("d");
        System.out.println(list);
        System.out.println(list.size());//返回集合中实际的存储的个数
        System.out.println(list.get(10));//根据索引得到指定位置的元素
        System.out.println(list.remove(5));//删除并返回指定位置的元素
        list.set(3,"M");//替换指定位置的元素
    }
}

迭代器遍历集合1:Iterator();返回了一个ArrayList中内部类对象,实现了Iteractor接口

public class ArrayListDemo3 {
    public static void main(String[] args) {
        ArrayList<String> list=new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        list.add("d");
        list.add("d");
        list.add("d");
        list.add("d");
        list.add("d");
        for (int i=0;i<list.size();i++){
            if (list.get(i).equals("d")){
                list.remove(i);
            }
        }for (String s:list){
            if (s.equals("d")){
                list.remove(s);//如果需要在遍历中删除元素,请使用迭代器中的remove();
                System.out.println(list);
            }
        }
        Iterator<String>it=list.iterator();//此内部类,专门用作对集合进行遍历时的控制
        while(it.hasNext()){//判断集合中是否还有元素,有返回true,没有返回false
            String e=it.next();
            ListIterator<String>lt=list.listIterator(list.size());
            while (lt.hasPrevious()){
                String s=lt.previous();
                System.out.println(s);
            }
        }
        System.out.println(list);
    }
}

迭代器遍历集合2:针对List接口如下的集合类还是提供listIteractor();

public class LinkedListDemo {
    public static void main(String[] args) {
        LinkedList<String>list=new LinkedList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        list.add("e");
        list.add("f");
        list.add("g");
        ListIterator<String> it=list.listIterator(list.size());//此方法可以指定位置进行迭代
        while (it.hasPrevious()){//此方法可以将集合中的元素进行逆序遍历
            String e=it.previous();
            System.out.println(e);
        }
    }
}

Set接口

共有的特点:不能存储重复元素,无序(不会按照添加元素的顺序排列)

HashSet:存储的元素顺序不固定

public class HashSetDemo {
    public static void main(String[] args) {
        HashSet<String>set=new HashSet<>();
        set.add("a");
        set.add("b");
        set.add("z");
        set.add("x");
        set.add("x");
        set.add("x");
        System.out.println(set);
    }
}

TreeSet:可以按照元素的自然顺序排序

public class TreeSetDemo {
    public static void main(String[] args) {
        TreeSet<String>hset=new TreeSet<>();
        hset.add("a");
        hset.add("c");
        hset.add("b");
        hset.add("x");
        hset.add("1");
        hset.add("d");
        System.out.println(hset);
    }
}
        Demo demo1=new Demo(1,"宝马");
        Demo demo2=new Demo(2,"宝马");
        Demo demo3=new Demo(3,"宝马");
        TreeSet<Demo> a=new TreeSet<>();
        a.add(demo1);
        a.add(demo2);
        a.add(demo3);
        System.out.println(a);

Set接口集合迭代

Set接口继承了Collection接口。 Set中所存储的元素是不重复的,但是是无序的, Set中的元素是没有索引的。
Set接口有两个实现类
HashSet中不能存储重复元素.如何判断元素是否已经包含了此元素.

在底层使用hashCode()和equals()放法来判断内容是否重复
hashCode()是object类中的方法
public native int hashCode();native修饰的方法称为本地方法
java没有实现,是调用操作系统中的方法,hashCode()获取的对象在内存中的地址。
equals();除了oject类中的equals是比较对象地址,其它类中都是比较内容是否相等,因为equals效率很低。
其他类中重写的HashCode(),都不是对象中的地址,而是根据对象内容计算出哈希值

ArrayList<String>list=new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        list.add("d");
        list.add("d");
        list.add("d");
        HashSet<String>set1=new HashSet<>(list);
        System.out.println(set1);

        TreeSet<String>set2=new TreeSet<>(list);
        System.out.println(set2);
    }
}

HashCode();判断时,先调用hashCode()计算哈希值来比较是否相等,这样提高了比较效率,但此种做法不安全,因为内容不同,可能计算的哈希值相同

Map接口

键值对,双列集合,键不可以重复,值可以重复,可以存储一个null键

底层数据结构:Java8
有3种数据结构
1.数组 2.链表 3.红黑树

添加元素过程:
根据元素计算出一个hash值(例如a-97),进行计算,计算出元素在数组中的位置,将元素封装到一个node对象中。
将对象存储到对应的位置。然后继续有元素存储进来。如果有相同的位置,将新的元素存入之前元素的下一位。
当链表的长度达到一定的条件,会转为红黑树

public class HashMapDemo {
    public static void main(String[] args) {
        HashMap<String, String> map=new HashMap<>();
        map.put("a","aa");
        map.put("q","ss");
        map.put("x","aa");
        System.out.println(map);
    /*
    Set<String>set=map.KeySet();
    for(String key:set){
        String value=map.get(key);}
        System.out.println("key+"="+value");
     */
     Set<Map.Entry<String,String>> mapentry=map.entrySet();
    }
}

哈希数组默认长度为6
负载因子是0.75
哈希数组如果发生扩容,每次扩容原来的2倍
当链表长度为81且哈希数组长度大于等于64,链表会转为红黑树

Collections类

public static void main(String[] args) {
        ArrayList<String>list=new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        test(10,3,2,1,4,5);
        Collections.addAll(list,"2,4,5,8");
        System.out.println(list);
        ArrayList<Integer>list1=new ArrayList<>();
        list1.add(0);
        list1.add(2);
        list1.add(5);
        list1.add(1);
        list1.add(3);
        Collections.sort(list1);
        Collections.binarySearch(list1,2);
        Collections.swap(list1,0,3);
        ArrayList<Integer>dlist=new ArrayList<>();
        dlist.add(0);
        dlist.add(0);
        dlist.add(0);
        dlist.add(0);
        dlist.add(0);
        dlist.add(0);
        List<Integer>list2=Collections.emptyList();
        Collections.copy(dlist,list1);
        System.out.println(Collections.binarySearch(list1,2));
        System.out.println(list1);
        System.out.println(dlist);
    }
    public static void test(int b,int...a){

    }

可变长度的参数,本质是数组
一个参数列表中,只能允许有一个可变长度参数
如果有,必须放在参数列表的末尾

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值