Java教程(七)集合

Java 集合

1. 集合概念

1.1 集合的定义

集合与数组类似,用来存储一系列数据或元素。

1.2 集合和数组的区别
  • 长度区别:数组长度是固定的,集合长度是可以改变的;
  • 类型区别:数组可以存储基本数据类型和引用数据类型,集合只能存储引用数据类型;
  • 内容区别:数组只能存储同一种类型,集合可以存储不同的类型;
1.3 集合框架图

在这里插入图片描述
发现一个特点,上述所有的集合类,除了map系列的集合,即左边的集合都实现了Iterator接口。
  Iterator是一个用来遍历集合中元素的接口,主要有hashNext(),next(),remove()三种方法。
  它的子接口ListIterator在它的基础上又添加了三种方法,分别是add(),previous(),hasPrevious()。

从图中我们可以看到:
  1.集合主要分为Collection和Map两个接口。
  2.Collection又分别被List和Set继承。
  3.List被AbstractList实现,然后分为3个子类,ArrayList,LinkedList和VectorList。
  4.Set被AbstractSet实现,又分为2个子类,HashSet和TreeSet。
  5.Map被AbstractMap实现,又分为2个子类,HashMap和TreeMap。
  6.Map被Hashtable实现。

1.4 主要学习框架

集合重点学习内容:
在这里插入图片描述

1.5 List、Set和Map的区别
集合是否有序 能否重复
List有序
Set无序不能
Map无序双列型,key不能,value可以

2. List 集合

2.1 ArrayList

底层是数组。
数组可以存储不同的数据类型,在创建这类数组时,需要用祖先类Object。
以下是创建和查询一个集合的代码实例:

import java.util.ArrayList;

public class Demo1 {
    public static void main(String[] args) {
        Object[] obbattr = {true,'好',12,3.14F};
//Object 创建的数据都是封装类型,obbattr数组里的类型分别是:Boolean、Character、Integer、Float
// 集合是可以存放饮用类型
        ArrayList aList = new ArrayList();  //集合默认大小为10,但是可以随着元素个数自增
        aList.add(true);
        aList.add('好');
        aList.add(12);
        aList.add(3.14F);
        aList.add(true);
        aList.add('好');
        aList.add(12);
        aList.add(3.14F);

//     打印单个元素
        Object a = aList.get(0);   //访问单个集合元素用get,下标是从0到元素个数-1,越界会报异常
        System.out.println(a);
//     遍历集合有三种方式
//     1.传统for循环
        for(int i=0;i<aList.size();i++){        //数组长度是length,集合是size
            System.out.println(aList.get(i));
        }
//     2.高级for循环(jdk1.5版本的新功能)
        for(Object temp : aList){        //数组长度是length,集合是size
            System.out.println("temp="+temp);
        }
//     3.lambda表达式(jdk1.8版本的新功能,且只能遍历集合)
        aList.forEach(temp->{        //无需指定temp类型,会根据集合内元素的类型自动识别
            System.out.println(temp);
        });
    }
}

泛型: 指的是在设计程序时可以自定义某些可变部分,在使用这部分之前需要声明。
代码实例:

import java.util.ArrayList;

public class Demo2 {
    public static void main(String[] args) {
        ArrayList<String> bList = new ArrayList();          //简写
        ArrayList<String> cList = new ArrayList<>();        //简写
        ArrayList<String> dList = new ArrayList<String>();  //标准写法
        bList.add("张三");
        bList.add(4);               //报错,若想装4,需要指定为Integer类型
    }
}

泛型可以指定集合只能存储单个数据类型,但是指定的类型不能是基本类型,只能是引用类型(例如:String、Integer、Character等)。

以下是删除和修改一个集合的代码实例:

import java.util.ArrayList;

public class Demo3 {
    public static void main(String[] args) {
        Object[] obbattr = {true,'好',12,3.14F};
        ArrayList aList = new ArrayList();  //集合默认大小为10,但是可以随着元素个数自增
        aList.add(true);
        aList.add('好');
        aList.add(12);
        aList.add(3.14F);
        aList.add(true);
        aList.add("好");
        aList.add(12);
        aList.add(3.14F);

        //删除单个元素有两种方法:按下标和按内容
        //1.按下标
        aList.remove(0);
        //2.按内容
        aList.remove("好");  //按内容删除只能删除String类型的元素,删不掉Character类型的元素

        //清空集合元素
        aList.clear();

        //修改(格式:下标,要修改的结果(在没有使用泛型时,可以改为任意类型的值,使用泛型后要遵守约定))
        aList.set(0,222222);   //修改下标为0的元素,改为222222

        aList.forEach(temp->{
            System.out.println(temp);
        });
    }
}

由于remove默认为按下标删除。若一个集合是纯数字集合,要按照内容删除,则:
lists.remove((Object)99);可以确保是按内容删除,删除内容为99的元素。

2.2 LinkedList

底层是链表。
LinkedList的使用方法,包括增删改查与ArrayList一模一样。
LinkedList 和 ArrayList的区别:

集合ArrayListLinkedList
底层基于数组基于链表
查询速度
增删速度

关于查询速度和增删速度的比较快慢的解释:

ArrayList基于数组,而数组存储的地址空间是连续的,所以ArrayList查询速度快。而LinkedList基于链表,链表在内存中的存储空间是不连续的,只能从头元素开始逐个访问下一个元素的地址。所以数组查询快。

而对于增加和删除的操作,数组中每增加一个元素都会影响后面元素的下标。

集合可以根据需要转数组

一般转换:OBject Arr = aList.toArray();
强制转换:String Arr = (String[])aList.toArray();

集合可以装入另一个集合

aList.addAll(bList);

3. Set集合

3.1 HashSet

底层是哈希码。

增加代码演示:

import java.util.HashSet;

public class Demo1 {
    public static void main(String[] args) {
        HashSet<String> aList = new HashSet();  
        aList.add("a");
        aList.add("12345678");
        aList.add("0");
        aList.add("0");    //虽然Set不允许重复,但是程序不会报错
        aList.add("我爱你");

        aList.forEach(temp->{       
            System.out.println(temp);
        });
    }
}

Set声明与增加方法和List类似,但是由于Set是无序不可重复的。
所以结果顺序是不确定的,以下是其中一种结果:

0
a
我爱你
12345678

若添加的有相同的值,Set会自动去重,不会报错。

3.2 删除、修改和查询

删除时,由于底层是哈希码,没有索引值,所以只能用remove(“内容”)的方法进行删除。
修改时,由于没有索引值无法修改,所以只能是删除再添加。
查询时,由于没有索引值无法查询单个,所以只能遍历整个集合。
例如:

 aList.add("0");

修改 0 为1
则:

   aList.remove("0");
   aList.add("1");
3.3 TreeSet

底层是二叉树。
Set是不可重复无序,但是TreeSet是不可重复有序的。
因为TreeSet实现了 ComparableComparator 接口。
Java的八种基本数据类型的包装类都实现了 Comparable 接口,所以可以排序(默认从小到大)。
但是对字符串类String集合排序仅限英文(按首字母顺序,中文不能排序)。

3.4 增加、删除、修改和查询

增加方式依然是add()和addAll()。
删除时,由于底层是二叉树,没有索引值,所以只能用remove(“内容”)的方法进行删除。
修改时,由于没有索引值无法修改,所以只能是删除再添加。
查询时,由于没有索引值无法查询单个,所以只能遍历整个集合。

4. Map集合

Map是双列集合。每条数据都有一个 key 值和一个 value 值, key 唯一。

4.1 HashMap

底层是哈希码。
与List不同,HashMap添加数据时使用的是put方法。
实例:

import java.util.HashMap;

public class Demo4 {
    public static void main(String[] args) {
        HashMap<Integer,String> bookMap = new HashMap<>();

        //1.添加
        bookMap.put(1,"第一本书");
        bookMap.put(1,"第二本书");                  //key不允许重复,所以会覆盖掉上一个
       String v1 =  bookMap.put(1,"第三本书");
        bookMap.put(2,"第四本书");
        System.out.println("返回值是:"+v1);        //返回值是刚刚被覆盖掉的value
        //2.查询
        //2.1 通过 key 查询单个 value
        String v2 = bookMap.get(1);
        System.out.println("key为1的值是:"+v2);
        //2.2 遍历Map 用lambda表达式
        bookMap.forEach((k,v)->{
            System.out.println(k+"="+v);
        });
        //2.3 直接打印Map集合,因为HashMap中已经覆盖了toString()方法
            System.out.println(bookMap);
        //3.修改 思路是直接添加,会覆盖掉
        // bookMap.put(2,"第五本书");
        // 4.删除
        // 4.1 删除单个 根据key删value
        bookMap.remove(1);
        System.out.println(bookMap);
        // 4.1 删除全部
        bookMap.clear();
        System.out.println(bookMap);
    }
}

注意: 返回值返回的都是被覆盖掉的旧值,若没有旧值,则返回null。

4.2 TreeMap

底层是二叉树。
可以根据Key进行排序。前提是Key类型为数字或者字母等。
假如有一个字符串,求各个字符出现的次数。
代码如下:

import java.util.TreeMap;

public class Demo5 {
    public static void main(String[] args) {
        //给定一个字符串:String str,统计每个字符出现的次数
        //提示:TreeMap<String,Integer>
        String str = "askqweasdasqwefasasf";
        //1.将字符串转换为字符数组
        char[] chs = str.toCharArray();
        //2.取出chs中的元素,看容器中是否存在
        TreeMap<Character,Integer> aMap = new TreeMap<>();
        for(char temp:chs){
            Integer value = aMap.get(temp);
            if(value==null){
                aMap.put(temp,1);
            }else{
                value++;
                aMap.put(temp,value);
            }
        }
        //打印结果
        aMap.forEach((k,v)->{
            System.out.println(k+"="+v);
        });
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值