返回顶部
首页 > 资讯 > 精选 >Java中数据结构的示例分析
  • 619
分享到

Java中数据结构的示例分析

2023-06-03 07:06:51 619人浏览 八月长安
摘要

这篇文章将为大家详细讲解有关Java中数据结构的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1.1.1.       增量内存分配 ArrayList 、 Hash

这篇文章将为大家详细讲解有关Java中数据结构的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。


1.1.1.       增量内存分配

ArrayList 、 HashMap 、 Vector 等类都允许我们向其中加入任意多的对象,从而进行处理的,我们在享受它们带来的便利的同时也要注意一定的性能问题。以 ArrayList 为例,我们来看一下在很多情况下是如何编写出低性能的代码的:


在一个数组中有若干个对象,对象的类型都是 PersonInfo , PersonInfo 的类结构如下:

public class PersonInfo

{

    // 身份证号码

    private String id;

    // 姓名

    private String name;

    // 年龄

    private int age;

    public PersonInfo(String id, String name, int age)

    {

        super();

        this.id = id;

        this.name = name;

        this.age = age;

    }

 

    public int getAge()

    {

        return age;

    }

 

    public String getId()

    {

        return id;

    }

 

    public String getName()

    {

        return name;

    }

}

请将所有这些 PersonInf 的身份证号码,也就是 id 属性,提取出来,放到另一个 List 类型的变量中。

实现代码 1 :

PersonInfo[] persons = new PersonInfo[] {

        new PersonInfo("00001", "Tom", 20),

        new PersonInfo("00002", "Tim", 23),

        new PersonInfo("00003", "Sally", 26),

        new PersonInfo("00005", "Lily", 20),

        new PersonInfo("00006", "Lucy", 30),

        new PersonInfo("00008", "Kitty", 20),

        new PersonInfo("00011", "Smith", 20),

        new PersonInfo("00031", "Ketty", 22),

        new PersonInfo("00051", "Melly", 20),

        new PersonInfo("00022", "Blues", 20),

        new PersonInfo("00033", "Tid", 18),

        new PersonInfo("00101", "Duoliaos", 30),

        new PersonInfo("00201", "Yang", 26),

        new PersonInfo("03001", "King", 20),

        new PersonInfo("05001", "Lee", 20),

        new PersonInfo("10001", "Wang", 20),

        new PersonInfo("06001", "Pizza", 60) };

 

List list = new ArrayList();

for (int i = 0, n = persons.length; i < n; i++)

{

    PersonInfo pInfo = persons[i];

    list.add(pInfo.getId());

}

程序运行正常,好像没有出现任何问题。程序也确实真的不会出现问题,因为其逻辑如此简单,不会但来问题。但是这个程序性能是最优的吗?

让我们来看看 ArrayList 类的实现 :

public class ArrayList extends AbstractList implements List, RandoMaccess,

        Cloneable, java.io.Serializable

{

    ……

    private transient Object elementData[];

    ……

    public ArrayList(int initialCapacity)

    {

        super();

        if (initialCapacity < 0)

             throw new IllegalArgumentException("Illegal Capacity: "

                      + initialCapacity);

        this.elementData = new Object[initialCapacity];

    }

    public ArrayList()

    {

        this(10);

    }

    ……

    public void ensureCapacity(int minCapacity)

    {

        modCount++;

        int oldCapacity = elementData.length;

        if (minCapacity > oldCapacity)

        {

             Object oldData[] = elementData;

             int newCapacity = (oldCapacity * 3) / 2 + 1;

             if (newCapacity < minCapacity)

                  newCapacity = minCapacity;

             elementData = new Object[newCapacity];

             System.arraycopy(oldData, 0, elementData, 0, size);

        }

    }    

 

    public boolean add(Object o)

    {

        ensureCapacity(size + 1);

        elementData[size++] = o;

        return true;

    }

}

正如其名字所暗示的, ArrayList 内部是使用数组保存的数据, Java 中的数组是固定大小的,要想改变数组的大小,就要重新开辟一个新的大小的内存区域,把原先的数据复制到新内存区域中,这就是增量性数组。由于需要重新开辟内存区域并进行数据的复制,因此改变数组的大小是非常耗时的,我们要尽量避免改变数组的大小。

从 ArrayList 的内部实现我们可以发现, ArrayList 中储存数据用的数组的默认大小为 10 ,当调用 add 方法向其中增加数据的时候,如果数据已经超过了数组的大小, ArrayList 就要增加数组的大小以便容纳更多的数据。在我们的这个人例子中,由于数据已经超过 10 条,当增加到第 11 条的时候, ArrayList 就会进行一次“扩容”,这是一个非常耗时的操作,因此我们必须想方设法避免。

我们注意到 ArrayList 有一个带参数的构造函数: public ArrayList(int initialCapacity) ,这里的 initialCapacity 代表构造此 ArrayList 的时候,数组的大小。我们可以使用此构造函数来避免“扩容”。

实现代码 2 :

PersonInfo[] persons = new PersonInfo[] {

        new PersonInfo("00001", "Tom", 20),

        new PersonInfo("00002", "Tim", 23),

        new PersonInfo("00003", "Sally", 26),

        new PersonInfo("00005", "Lily", 20),

        new PersonInfo("00006", "Lucy", 30),

        new PersonInfo("00008", "Kitty", 20),

        new PersonInfo("00011", "Smith", 20),

        new PersonInfo("00031", "Ketty", 22),

        new PersonInfo("00051", "Melly", 20),

        new PersonInfo("00022", "Blues", 20),

        new PersonInfo("00033", "Tid", 18),

        new PersonInfo("00101", "Duoliaos", 30),

        new PersonInfo("00201", "Yang", 26),

        new PersonInfo("03001", "King", 20),

        new PersonInfo("05001", "Lee", 20),

        new PersonInfo("10001", "Wang", 20),

        new PersonInfo("06001", "Pizza", 60) };

 

List list = new ArrayList(persons.length);

for (int i = 0, n = persons.length; i < n; i++)

{

    PersonInfo pInfo = persons[i];

    list.add(pInfo.getId());

}

我们已经知道了 list 将放置 persons.length 条数据,因此我们就使 list 中数组的默认大小设置为 persons.length ,这样系统的性能就好了很多。

不仅是 ArrayList ,我们在使用 Vector 、 HashMap 等类的同时,同样要注意这个问题。

选用合适的类

List 接口最常用的实现类有两个: ArrayList 、 LinkedList ,我们一般都是通过 List 接口来调用这些类的实现方法,所以它们的使用方式是几乎相同的,其区别就在于其实现方式。

正如 4.5.1 中阐述的那样, ArrayList 内部是使用数组保存的数据,而 LinkedList 则使用链表保存的数据。数组方式和链表方式储存数据的优缺点比较如下 :

数组中的数据是顺序排列的,因此要向数组中插入数据或者从数组中删除数据,就必须对其他数据进行位置的改变,因此效率是非常低的;但是由于数组的数据是按下标读取的,所以从数组中检索数据是非常快的 。

链表中的数据是通过指针连在一起的,向链表中插入数据或者从链表中删除数据只需要断开指针关系即可,效率非常高;但是从链表中检索数据的时候,必须从链表头向后遍历,效率非常低 。

因此 ArrayList 适合于保存很少插入、删除,但是经常读取的场合,而 LinkedList 适合于经常插入、删除,但是很少读取的场合。合理的使用这两个类,将会提高系统的效率。

选用合适的数据结构

很多程序员都意识到了 Map 的方便性和实用性,因此也造成了 Map 的滥用。比如:

一个数组中有若干字符串,请验证,这些字符串是否有重复。

实现代码 1 :

String[] data = { "11", "22", "33", "55", "11", "66" };

Map map = new HashMap();

for (int i = 0, n = data.length; i < n; i++)

{

    if (map.containsKey(data[i]))

    {

        System.out.println(" 数据重复 ");

        return;

    }

    map.put(data[i], "");

}

运行结果 :

数据重复

     

这段代码利用了 Map 中键不能重复的特性,实现了要求的效果,但是看起来怪怪的,因为 Map 中的数据是“键 - 值对”,而这里只用到了“键”,对于“值”则只是简单的塞了一个空字符串进去应付差事。显然这对 Map 来说是误用。

实现代码 2 :

String[] data = { "11", "22", "33", "55", "11", "66" };

Set set = new HashSet();

for (int i = 0, n = data.length; i < n; i++)

{

    if (set.contains(data[i]))

    {

        System.out.println(" 数据重复 ");

        return;

    }

    set.add(data[i]);

}

运行结果 :

数据重复

     

jdk 中的 Set 接口代表中数学中的“集合”(注意和 JDK 中的 Collection 区分开),即不重复的数据项的容器。显然使用 Set 接口就完全能满足我们的要求,同时我们又使用了采用哈希算法的 HashSet ,这就保证了判断数据重复时的效率。案例系统中的 PermissionServiceImpl 类(包 com.cownew.PIS.base.permission.bizLayer 下)就是用 Set 来完成权限项名称重复验证的;类 ServerUserContext (包 com.cownew.PIS.framework.server.sessionMgr 下)的 getPermissonNameSet 方法返回 Set 类型的意义也在于此 。

关于返回值

经常需要使用 List 、 Map 、 Set 等类做为方法返回值以返回多个数据,但是 JDK1.5 之前是不支持泛型的,我们只能看到方法返回一个 List 、 Map 或者 Set 类型的返回值,至于这些容器内存放着什么类型的数据则无法得知,只能通过查手册才能得知。在读取数据的时候又要进行类型转换。这给系统留下了很多不确定性因素。在 JDK1.5 之前唯一能在编译器就确定容器中数据的类型的 Java 结构就是数组,因此如果在返回数据的时候能够确定数据的类型以及大小,并且确定调用者只是读取返回值,那么我们就应该尽量使用数组来返回数据,这样程序的可读性就增强了,而且也减少了很多不确定性因素。

在使用返回值的时候还要注意一些惯用法。

( 1 )数组,一定不能返回 NULL

Object[] fooBar()

{

   //do something

   return null;

}

极少有人这样使用此方法:

Object[] objarray = fooBar();

if (objArray != null)

{

   for (int i = 0; i < objArray.Length; ++i)

   {

       //do something

   }

}

应该这样写 fooBar 方法:

Object[] fooBar()

{

   //do something

   return new Object[0];

}

( 2 )集合,同样不能返回 NULL

Set fooBar()

{

   //do something

   return null;

}

应该这样写:

Set fooBar()

{

   //do something

   return new HashSet(0);

}

关于“Java中数据结构的示例分析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

--结束END--

本文标题: Java中数据结构的示例分析

本文链接: https://lsjlt.com/news/233599.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Java中数据结构的示例分析
    这篇文章将为大家详细讲解有关Java中数据结构的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1.1.1.       增量内存分配 ArrayList 、 Hash...
    99+
    2023-06-03
  • Java数据结构中图的示例分析
    这篇文章给大家分享的是有关Java数据结构中图的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。有向图有向图的定义及相关术语定义∶ 有向图是一副具有方向性的图,是由一组顶点和一组有方向的边组成的,每条方向的...
    99+
    2023-06-29
  • java数据结构之树的示例分析
    这篇文章主要介绍java数据结构之树的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!树定义和基本术语定义树(Tree)是n(n≥0)个结点的有限集T,并且当n>0时满足下列条件:(1)有且仅有一个特定的称为根...
    99+
    2023-05-30
    java
  • Java数据结构之链表的示例分析
    小编给大家分享一下Java数据结构之链表的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、链表的介绍什么是链表链表是一种物理存储单元上非连续、非顺序的存...
    99+
    2023-06-15
  • Java数据结构与算法的示例分析
    这篇文章给大家分享的是有关Java数据结构与算法的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。第1章 数据结构与算法基础概述1.1 数据结构和算法的重要性算法是程序的灵魂,优秀的程序可以在海量数据计算时...
    99+
    2023-06-29
  • Java集合中基本数据结构的示例分析
    这篇文章主要介绍Java集合中基本数据结构的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!集合中三大数据结构数组内存地址连续可以通过下标的成员访问,下标访问的性能高增删操作有较大的性能消耗(需要动态扩容)链表...
    99+
    2023-06-15
  • JavaScript数据结构中串的示例分析
    这篇文章将为大家详细讲解有关JavaScript数据结构中串的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。具体如下:类似于线性表的顺序存储结构,用一组地址连续的...
    99+
    2024-04-02
  • C++数据结构中list的示例分析
    小编给大家分享一下C++数据结构中list的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!前言list相较于vector来说会显得复杂,它的好处是在任意位置插入,删除都是一个O(1)的时间复杂度。一、list的节点...
    99+
    2023-06-25
  • Java数据结构之红黑树的示例分析
    小编给大家分享一下Java数据结构之红黑树的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、红黑树所处数据结构的位置:在JDK源码中, 有treeMap...
    99+
    2023-05-30
    java
  • python数据结构堆的示例分析
    小编给大家分享一下python数据结构堆的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!1、说明堆是用数据结构来实现的一种算法:树,数组均可。堆本身是一棵完全二叉树。2、特点最大堆:所有父节点的值大于子节点的值最小...
    99+
    2023-06-15
  • Python Pandas数据结构的示例分析
    这篇文章将为大家详细讲解有关Python Pandas数据结构的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1 Pandas介绍2008年WesMcKinney开发出的库专门用于数据挖...
    99+
    2023-06-29
  • JS中数据结构之栈的示例分析
    这篇文章给大家分享的是有关JS中数据结构之栈的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。栈是一种高效的数据结构,因为数据只能在栈顶添加或删除,所以这样的操作很快,而且...
    99+
    2024-04-02
  • JDK 1.8中HashMap数据结构的示例分析
    这篇文章给大家分享的是有关JDK 1.8中HashMap数据结构的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。概述JDK 1.8对HashMap361天恒平台制作,进行了比较大的优化,底层实现由之前的“...
    99+
    2023-06-04
  • Java中逻辑结构的示例分析
    这篇文章主要介绍Java中逻辑结构的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Java中的逻辑结构逻辑结构 Java中的逻辑结构 顺序结构分支结构循环结构顺序结构顺序结构顾名思义,就是按照代码的顺序依次往...
    99+
    2023-06-14
  • Redis中数据结构与数据操作的示例分析
    小编给大家分享一下Redis中数据结构与数据操作的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Redis完成数据操作的...
    99+
    2024-04-02
  • ES6中Set和Map数据结构的示例分析
    这篇文章主要介绍了ES6中Set和Map数据结构的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。ES6 的 Set:ES6 提供了新...
    99+
    2024-04-02
  • PHP数据结构中图遍历的示例分析
    这篇文章将为大家详细讲解有关PHP数据结构中图遍历的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。图的遍历:深度优先与广度优先树的遍历演化到图的遍历还记得在树的学习中,我们讲到过先序、中序、后序以...
    99+
    2023-06-20
  • C++ 数据结构中单链表的示例分析
    小编给大家分享一下C++ 数据结构中单链表的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!一、链表是什么链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接依次实现的...
    99+
    2023-06-29
  • python数据结构算法的示例分析
    小编给大家分享一下python数据结构算法的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1.算法分析的定义有这样一个问题:当两个看上去不同的程序 解决同...
    99+
    2023-06-22
  • Python数据结构创建的示例分析
    本篇文章为大家展示了Python数据结构创建的示例分析,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。 列表list:变量赋值方式:shoplist = ['apple', '...
    99+
    2023-06-17
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作