文档章节

基于ArrayList编写支持反向遍历的List

珂jack
 珂jack
发布于 2017/09/04 11:45
字数 1156
阅读 57
收藏 1
点赞 0
评论 0

一、概述

    List遍历是我们经常会使用到的一个功能,很多时候我们也会用到反向遍历,在用到反向遍历时我们常用的方法是通过for循环或者是对List反向排序来完成相应的操作,像下面代码这样:

方法1:

        for(int i = list.size()-1; i>=0; i--) {
            System.out.println(list.get(i));
        }

    这个方法开上去就比较臃肿,写起来也相对繁琐一些。

方法2:

        Collections.reverse(list);
        System.out.println(list);

    这种方法看似不错,但是reverse改变了原list的结构,如果我们只是要反向遍历list而不想改变list的结构的话这个方法是不适用的,除非你想在遍历完list之后再次调用reverse把list变回去,这种做法当然是不值得推荐的。

    那么有没有一种方法可以既不改变原有的List的结构,有可以很简洁的实现反向遍历呢?我个人认为,直接制作一个支持反向遍历的List就可以很好的解决这个问题。下面我们就从头开始制作支持反向遍历List。

二、准备工作

    众所周知,所有的Collection都实现了Iterable接口,而Iterable接口中的iterator()方法就是用来实现集合类遍历的,那么我们是不是可以从这里开始入手。

    还有一点,就是为什么要基于ArrayList去做这件事而不是直接实现List接口,原因很简单,如果我要实现List接口那么我就需要实现List接口中所有的方法,而我比较懒,不想再去实现List接口中的所有方法,而且一般需要遍历处理的都是ArrayList,所有我就直接在ArrayList的基础上去做这件事,也省了不少功夫。

三、新建List

    话不多说,开干。首先我们需要定义一个类,并且这个类要继承ArrayList:

public class ErgodicList<T> extends ArrayList<T> {

    /*构造方法 start*/
    public ErgodicList() {
        super();
    }
    public ErgodicList(Collection<? extends T> integers) {
        super(integers);
    }
    /*构造方法 end*/

}

    接着我们要编写能够实现反向遍历的Interator:

    /**
     * 反向遍历Iterator
     *
     * @return Iterable
     */
    public Iterable<T> reversed() {
        return () -> new Iterator<T>() {
            int index = ErgodicList.super.size() - 1;

            @Override
            public boolean hasNext() {
                return index > -1;
            }

            @Override
            public T next() {
                return ErgodicList.super.get(index--);
            }

//            Java8以下版本需要重写该方法
//            @Override
//            public void remove() {
//                throw new UnsupportedOperationException("remove");
//            }
        };
    }

    从代码可以看出,首先我们要取出List最末尾的Index,这一点跟for循环很像,然后就是重写Iterator接口的两个方法(java8种remove()有了默认方法,我这里也不需要它所以就没有重写),一个用来判断是否还有下一个元素,一个用来获取元素。

    到此可以支持反向遍历的List就编写好了,是不是感觉比for循环还要复杂,但是这属于一劳永逸的方法,麻烦一次以后再也不用苦逼的写for循环了。下面我们来测试一下效果如何:

    public static void main(String[] args) {
        ErgodicList<Integer> integers = new ErgodicList<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9));
        System.out.println("------------反向遍历结果-------------");
        integers.reversed().forEach(System.out::println);
        System.out.println("------------------------------------");
        System.out.println(integers);
    }

    

    从结果可以看出,简单的foreach代码在不改变原有List的结构的情况下(废话Interator当然不会改变List的结构)实现了List的反向遍历,并且以后再需要反向遍历的时候我们只需要new一个我们自制的List再加一个forEach就好了,用起来相当方便。

四、衍生

    我们既然实现了反向遍历,那么可不可以实现随机遍历呢,当然没问题,举一反三是我们程序员应有的基本素养。下面来看看随机遍历的实现,还是刚才的那个List,我们再增加一个方法:

    /**
     * 随机遍历Iterator
     *
     * @return Iterable
     */
    public Iterable<T> random() {
        return () -> {
            List<T> randomList = new ArrayList<>(this);
            Collections.shuffle(randomList, new Random());
            return randomList.iterator();
        };

    是不是更简单,具体的说明我就不写了(我比较懒),有兴趣的朋友可以自己查一下。测试代码和反向遍历的测试也差不多,只需要:

integers.random().forEach(System.out::println);

    使用起来体验也是很不错的,大家可以试一试。

附完整代码,以便参考:http://git.oschina.net/jack90john/ergodic

------------------------------------------------------------------------------

欢迎关注我的个人公众号,推送最新文章

© 著作权归作者所有

共有 人打赏支持
珂jack
粉丝 41
博文 16
码字总数 20976
作品 0
成都
后端工程师
数据结构与算法-线性表ArrayList源码分析

前言 ArrayList继承了AbstractList,实现了List。ArrayList在工作中经常用到,所以要弄懂这个类是极其重要的。 构造图如下: 蓝色线条:继承 绿色线条:接口实现 image.png 正文 ArrayList简介...

小朱v ⋅ 2017/12/29 ⋅ 0

Java集合框架总结(4)——List接口的使用

List集合代表一个有序集合,集合中每个元素都有其对应的顺序索引。List集合允许使用重复元素,可以通过索引来访问指定位置的集合元素。 1、List接口和ListIterator接口 List作为Collection接...

dong.li ⋅ 2012/04/24 ⋅ 1

40个Java集合面试问题和答案

1.Java集合框架是什么?说出一些集合框架的优点? 每种编程语言中都有集合,最初的Java版本包含几种集合类:Vector、Stack、HashTable和Array。随着集合的广泛使 用,Java1.2提出了囊括所有集...

赵小宾 ⋅ 2015/05/12 ⋅ 0

40个JAVA问题

1.Java集合框架是什么?说出一些集合框架的优点? 每种编程语言中都有集合,最初的Java版本包含几种集合类:Vector、Stack、HashTable和Array。随着集合的广泛使用,Java1.2提出了囊括所有集...

裸奔的八戒 ⋅ 2016/02/17 ⋅ 0

数据结构(一)——线性表、栈和队列

数据结构是编程的起点,理解数据结构可以从三方面入手: 逻辑结构。逻辑结构是指数据元素之间的逻辑关系,可分为线性结构和非线性结构,线性表是典型的线性结构,非线性结构包括集合、树和图...

yhthu ⋅ 2017/09/22 ⋅ 0

Java集合框架面试题

1.Java集合框架是什么?说出一些集合框架的优点? 每种编程语言中都有集合,最初的Java版本包含几种集合类:Vector、Stack、HashTable和Array。随着集合的广泛使用,Java1.2提出了囊括所有集...

火力全開 ⋅ 2016/10/09 ⋅ 0

40个Java集合面试问题和答案

Java集合框架为Java编程语言的基础,也是Java面试中很重要的一个知识点。这里,我列出了一些关于Java集合的重要问题和答案。 1.Java集合框架是什么?说出一些集合框架的优点? 每种编程语言中都...

天蚕宝衣 ⋅ 2016/03/31 ⋅ 0

ArrayList集合实现RandomAccess接口有何作用?为何LinkedList集合却没实现这接口?

众所周知,在List集合中,我们经常会用到ArrayList以及LinkedList集合,但是通过查看源码,就会发现ArrayList实现RandomAccess接口,但是RandomAccess接口里面是空的!Linked并没有实现Rando...

kim_o ⋅ 06/07 ⋅ 0

ArrayList工作原理

1.前言 List接口中,重要的两个实现是ArrayList和LinkedList,其中ArrayList又比LinkedList常用。这是因为ArrayList的读取性能远远高于LinkedList。本篇博文将介绍ArrayList,稍后介绍Linke...

kukudeku ⋅ 2016/08/26 ⋅ 0

记录转化为有层次结构的树状列表的通用算法

问题说明: 访问数据库记录次数随着记录的增多而增多 由于需要多次访问数据库, 因此访问速度受影响 需要数据库访问层的支持, 并对记录进行转化, 耦合性太强 通用性不好, 每次需要一个新的类型...

walb呀 ⋅ 2017/12/04 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

mysql in action / alter table

change character set ALTER SCHEMA `employees` DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_general_ci ;ALTER TABLE `employees`.`t2` CHARACTER SET = utf8mb4 , COLLAT......

qwfys ⋅ 今天 ⋅ 0

Java 开发者不容错过的 12 种高效工具

Java 开发者常常都会想办法如何更快地编写 Java 代码,让编程变得更加轻松。目前,市面上涌现出越来越多的高效编程工具。所以,以下总结了一系列工具列表,其中包含了大多数开发人员已经使用...

jason_kiss ⋅ 昨天 ⋅ 0

Linux下php访问远程ms sqlserver

1、安装freetds(略,安装在/opt/local/freetds 下) 2、cd /path/to/php-5.6.36/ 进入PHP源码目录 3、cd ext/mssql进入MSSQL模块源码目录 4、/opt/php/bin/phpize生成编译配置文件 5、 . ./...

wangxuwei ⋅ 昨天 ⋅ 0

如何成为技术专家

文章来源于 -- 时间的朋友 拥有良好的心态。首先要有空杯心态,用欣赏的眼光发现并学习别人的长处,包括但不限于工具的使用,工作方法,解决问题以及规划未来的能力等。向别人学习的同时要注...

长安一梦 ⋅ 昨天 ⋅ 0

Linux vmstat命令实战详解

vmstat命令是最常见的Linux/Unix监控工具,可以展现给定时间间隔的服务器的状态值,包括服务器的CPU使用率,内存使用,虚拟内存交换情况,IO读写情况。这个命令是我查看Linux/Unix最喜爱的命令...

刘祖鹏 ⋅ 昨天 ⋅ 0

MySQL

查看表相关命令 - 查看表结构    desc 表名- 查看生成表的SQL    show create table 表名- 查看索引    show index from  表名 使用索引和不使用索引 由于索引是专门用于加...

stars永恒 ⋅ 昨天 ⋅ 0

easyui学习笔记

EasyUI常用控件禁用方法 combobox $("#id").combobox({ disabled: true }); ----- $("#id").combobox({ disabled: false}); validatebox $("#id").attr("readonly", true); ----- $("#id").r......

miaojiangmin ⋅ 昨天 ⋅ 0

金山WPS发布了Linux WPS Office

导读 近日,金山WPS发布了Linux WPS Office中文社区版新版本,支持大部分主流Linux系统,功能更加完善,兼容性、稳定性大幅度提升。本次更新WPS将首次在Linux提供专业办公文件云存储服务,实...

问题终结者 ⋅ 昨天 ⋅ 0

springboot2输出metrics到influxdb

序 本文主要研究一下如何将springboot2的metrics输出到influxdb maven <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-bo......

go4it ⋅ 昨天 ⋅ 0

微信小程序 - 选择图片显示操作菜单

之前我分享过选择图片这个文章,但是我在实际开发测试使用中发现一个问题在使用 wx.chooseImage 选择照片显示出第一格是拍照,后面是相册里的图片。这种实现之前说过了,效果如下。 但是你从...

hello_hp ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部