Ubuntu aircrack-ng ajax curl serialization pyspark triggers dns Modernizr 百度seo关键词 vue官方下载 小程序demo源码 多店版微信商城 软件测试项目实战案例 android小程序源代码 bootstrap图表 拼接json字符串 mysql设置自增初始值 pip环境变量 coreldraw入门学习 centos查看python版本 汇编语言clr 反函数的二阶导数 python界面 python中assert 简单python脚本实例 stringjava java环境部署 java的instanceof java替换字符 java接口的实例 javaenum java如何获取当前时间 mac地址修改器 迷你版kms pr滤镜插件 安卓刷机精灵 一羽月土米水日古余打一成语 pdf安装包官方下载 电脑代码雨
当前位置: 首页 > 学习教程  > 编程语言

Java基础自学第六期——集合

2021/2/13 17:27:35 文章标签: 测试文章如有侵权请发送至邮箱809451989@qq.com投诉后文章立即删除

集合 本文主要介绍一下Java中几个集合的框架。 Collection接口 在Java类库中&#xff0c;集合类的基本接口是Collection接口。这个接口有两个基本方法&#xff1a; public interface Collection<E> {boolean add(E element);Iterator<E> iterator(); }add方法是…

集合

本文主要介绍一下Java中几个集合的框架。

Collection接口

在Java类库中,集合类的基本接口是Collection接口。这个接口有两个基本方法:

public interface Collection<E>
{
	boolean add(E element);
	Iterator<E> iterator();
}

add方法是向集合中添加元素。如果改变了集合,方法返回值是true,否则返回false。
iterator方法则会返回一个实现Iterator接口的对象。可以使用这个迭代器对象依次访问集合中的元素。

Iterator迭代器

迭代器就是一个对集合进行引用的工具。对于数组我们可以通过下标来对其中元素进行引用。部分集合不支持这种引用,这就需要构造器。
Iterator接口中主要有三个方法:

public interface Iterator<E>
    {
        E next();
        boolean hasNext();
        void remove();
    }

Iterator的简单使用:

ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("11");
Iterator it =  arrayList.iterator();
System.out.println(it.next());
//打印输出11

如果我们需要遍历整个集合,我们则需要hasNext方法来判断时候到达了集合的末尾。当到达了集合的末尾,hasNext会返回false。

ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("11");
arrayList.add("22");
Iterator it =  arrayList.iterator();
while(it.hasNext())
{
    System.out.println(it.next());
}
//打印输出11 22

如果我们只想遍历集合中的元素,我们可以使用for each循环:

 for(String s : arrayList)
       {
           System.out.println(s);
       }

Iterator接口的remove方法将会删除上次调用next方法时返回的元素。我们可以先next返回该元素,然后remove删除。

集合框架

java集合有两个基本接口:Collection和Map。(图片源于网络)
在这里插入图片描述

Collection类下面分为List,Set和Queue(不做介绍)

List接口

元素存取有序,即先存先取
允许有重复的元素
有索引值,可以使用for循环

List接口的常用方法:

void add(int index,E element)
void remove(int index)
E get(int index)
E set(int index,E element)

也可以使用迭代器来访问。
由数组支持的有序集合可以快速地随机访问,因此适合使用List方法并提供一个整数索引来访问,如ArrayList。而链表支持的有序结合尽管也是有序的,但是通过索引访问很慢,所以最好使用迭代器来遍历,如LinkedList。
ArrayList在前面我们介绍过,所以接下来介绍一下LinkedList。
在数据结构中,我们学过链表。每个节点保存着自己的信息和对下一个节点的引用。在Java中,所有链表实际上都是双向链接的——即每个节点还存放着指向前去节点的引用。

LinkedList方法

public static void main(String[] args){
        LinkedList<String> l = new LinkedList<>();
        l.add("amy");  //向链表末尾添加
        l.add(1,"tom");  //向链表1号索引位置插入
        l.add("john");
        l.get(1);  //返回1号索引位置的元素
        l.getFirst();  //返回链表第一个元素
        l.getLast();  //返回链表最后一个元素
        l.remove();  //移除表头元素
        l.remove("john");   //移除指定的某个元素
        l.remove(1);  //移除1号索引位置的元素
        l.removeFirst();  //移除表头元素
        l.removeLast();  //移除表尾元素
    }

当我们插入删除链表元素时,其他元素的索引位置也会相对改变

Set接口

不允许有重复的元素
没有元素索引,不能for循环
TreeSet和HashSet是存取无序的
LinkedHashSet是存取有序的

有一种众所周知的数据结构们可以快速地查找所需要地对象,这就是散列表(hash table)。散列表为每一个对象计算一个整数,成为散列码(hash code)。散列码是由对象的实例域产生的一个整数。更准确地说,具有不同数据域的对象将产生不同的散列码。
在Java中,散列表采用链表数组实现。每个链表被称为桶。每一个散列码对应一个桶。若出现多个元素对应一个桶,这种现象被称为散列冲突,这时候会将多个元素按照链表给连接起来。

在Java 8中,一个桶超过8个元素会从链表变为平衡二叉树。这样当产生冲突的元素过多时,能提高查找的性能

HashSet

HashSet就是通过hashcode来确定元素的位置,一个hash code上可以存储多个元素。HashSet通过hashcode和equals方法可以快速查看元素是否在集合中重复。
当你试图把对象加入HashSet时,HashSet会使用对象的hashcode来判断对象加入的位置。同时也会与其他已经加入的对象的hashcode进行比较,如果没有相等的hashcode,HashSet就会假设对象没有重复出现。

如果对象的hashCode值是不同的,那么HashSet会认为对象是不可能相等的。

因此我们自定义类的时候需要重写hashCode,来确保对象具有相同的hashCode值。
如果元素(对象)的hashCode值相同,是不是就无法存入HashSet中了? 当然不是,会继续使用equals 进行比较.如果 equals为true 那么HashSet认为新加入的对象重复了,所以加入失败。如果equals 为false那么HashSet 认为新加入的对象没有重复.新元素可以存入。

public static void main(String[] args){
        HashSet<String> set = new HashSet<>();
        set.add("amy");
        set.add("tom");
        set.add("amy");
        Iterator<String> it = set.iterator();
        while(it.hasNext())
        {
            System.out.println(it.next());
        }

    }
    //打印tom amy

从打印结果我们可以发现,HashSet是存取无序的,而且会默认地去掉重复地元素。如果我们现在需要按照一定的顺序存取元素,并且要求去重,这时候就需要TreeSet了。

TreeSet

TreeSet与HashSet很类似,不过它是一个有序集合。在对集合进行遍历时,每个值将自动地按照排序后地顺序实现。TreeSet底层是通过红黑树实现的。
TreeSet自定义排序可以通过两个方式来实现:

  • 让元素自身具备比较性,即元素实现Comparable接口,重写compareTo方法
  • 让容器自身具备比较性,即定义一个类实现Comparator接口,覆盖compare方法,并将该接口的子类对象作为参数传递给TreeSet集合的构造函数。

要使用TreeSet,必须能够比较元素。这些元素必须实现Comparable接口,或者构造集时必须提供一个Comparator

LinkedHashSet

LinkedHashSet底层则是链表+散列表实现的,存取有序。可以看作散列表按照链表插入顺序来存取。

Map

在Set接口中,我们通常使用hashcode作为元素的索引值。但有时候我们已经有要查找的元素的索引了。这时候我们可以用映射来存放键值对。如果我们知道了键,就可以查找到相对应的值。Java中提供了HashMap和TreeMap两种框架。
HashMap对键进行散列,TreeMap则用键的排序顺序来对值进行排序,并将其组织成搜索树。散列或比较函数只能作用于键,与键关联的值不能进行散列或者比较。
HashMap和TreeMap的特点与HashSet和TreeSet一样。HashMap查找快,TreeMap则会按照排列顺序访问键。

基本映射操作

public class Launch {
    public static void main(String[] args) {
        HashMap<Integer, String> map = new HashMap<Integer, String>();
        map.put(1, "amy");
        map.put(2, "tom");
        map.put(3, "john");
        System.out.println(map.get(1));
    }
}

在创建map的时候,我们需要定义映射中键值对的数据类型。put方法将键值对插入到映射中。如果这个键已经存在,那么新的值则会取代旧的值。
get方法则会返回与键对应的值。如果映射中没有这个键则会返回null。

map的遍历

对于map的遍历,我们首先要获得map的键集合,通过不断获得键,来找到值。

public static void main(String[] args) {
        HashMap<Integer, String> map = new HashMap<Integer, String>();
        map.put(1, "amy");
        map.put(2, "tom");
        map.put(3, "john");
        Set<Integer> set = map.keySet();
        Iterator<Integer> it = set.iterator();
        while(it.hasNext())
        {
            int i = it.next();
            System.out.println(i+" "+map.get(i));
        }

    }

通过keySet方法返回一个存储键的集合,然后遍历集合即可找到值。也可以使用for each循环

	for(int i : set)
        {
            System.out.println(i+" "+map.get(i));
        }

Map类中提供了一个同时反映键与值的方法entrySet():

Set<Map.Entry<Integer, String>> entries = map.entrySet();

该方法会返回一个保存着键值对的一个集合。Map.Entry接口提供了getKey和getValue方法:

for(Map.Entry<Integer, String> entry: map.entrySet())
        {
            System.out.println(entry.getKey()+" "+entry.getValue());
        }

往期回顾

第一期——继承
第二期——反射与数组
第三期——接口
第四期——内部类与lambda
第五期——异常


本文链接: http://www.dtmao.cc/news_show_700160.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?