数组:是将元素在内存中连续存储的;它的优点:因为数据是连续存储的,内存地址连续,所以在查找数据的时候效率比较高;它的缺点:在存储之前,我们需要申请一块连续的内存空间,并且在编译的时候就必须确定好它的空间的大小。在运行的时候空间的大小是无法随着你的需要进行增加和减少而改变的,当数据两比较大的时候,有可能会出现越界的情况,数据比较小的时候,又有可能会浪费掉内存空间。在改变数据个数时,增加、插入、删除数据效率比较低。

链表:是动态申请内存空间,不需要像数组需要提前申请好内存的大小,链表只需在用的时候申请就可以,根据需要来动态申请或者删除内存空间,对于数据增加和删除以及插入比数组灵活。还有就是链表中数据在内存中可以在任意的位置,通过应用来关联数据(就是通过存在元素的指针来联系)。

数组和链表就拿增加数据来说,数组中增加一个元素,需要移动大量的元素,在内存中空出一个元素的空间,然后将增加的元素放到空出的空间中;而链表就是将链表中最后的一个元素的指针指向新增的元素,在指出新增元素是尾元素就好了。

数组应用场景:

1、数据比较少;

2、经常做的运算是按序号访问数据元素;

3、数组更容易实现,任何高级语言都支持;

4、构建的线性表较稳定。

/**
* 自定义长度可变的数组[存放字符串]
* @author Administrator
*/ public class my { // 定义一个长度为0的初始数组
private String src = new String[]; /**
* 存放数据
* @param s 要存放的数据
*/
public void add(String s) {
// 定义一个新数组长度是源数组长度+1
String dest = new String[src.length + ];
// 将原数组的数据拷贝到新数组中
System.arraycopy(src, , dest, , src.length);
// 将新数据放到新数组的最后一个位置
dest[dest.length - ] = s;
// 将原数组指向新数组
src = dest; } /**
* 取出数据
* @param index 要取出的数据的下标
*/
public String get(int index) {
String s = src[index];
return s;
} /**
* 根据下标删除数据
* @param index要删除的数据的下标
*/
public void delete(int index) {
String dest=new String[src.length-];
//将下标小于index的拷贝到新数组对应的下标
System.arraycopy(src,,dest,,index);
//将下标大于index的拷贝到新数组下标的位置为原数组的下标位置-1
System.arraycopy(src,index+,dest,index,src.length-index-);
//将src指向新数组
src=dest;
} /**
* 删除指定的数据
* @param s要删除的数据,如果有重复的数据,就删除下标最小的
*/
public void delete(String s) {
int t=-;
for(int i=;i<src.length;i++){
if(s.equals(src[i])){
t=i;
break;
}
}
//如果s在数组中出现过,t一定是大于等于0的
if(t>=){
delete(t);
} } /**
* 将数据插入到指定位置
* @param index 要插入的位置
* @param s 要插入的数据
*/
public void insert(int index,String s){
String dest = new String[src.length+];
//将新数据放到新数组指定的位置
dest[index]=s;
//将下标小于index的数据拷贝到新数组对应的下标位置
System.arraycopy(src,,dest,,index);
//将下标大于等于index的数据拷贝到 新数组下标+1的位置
System.arraycopy(src, index, dest,index+, src.length-index);
src=dest;
} /**
* 修改数据
* @param index要修改的数据的下标
* @param s修改后的数据
*/
public void update(int index, String s) {
src[index] = s;
} /**
* 获得数据个数
*/
public int size {
return src.length;
} }
/**
* 自定义长度可变数组的测试类
*
* @author Administrator
*
*/
public static void main(String[] args) {
// 创建数组对象
my arr = new my;
// 增加数据
arr.add("AA");
arr.add("BB");
arr.add("CC");
arr.add("DD");
arr.add("EE");
arr.add("FF"); //根据下标删除数据
arr.delete();
//删除指定的数据
arr.delete("BB");
//将数据插入到指定位置
arr.insert(,"on");
//修改数据
arr.update(, "up");
//获得数据个数
arr.size;
// 取出数据
for (int i = ; i < arr.size; i++) {
String s = arr.get(i);
System.out.println(s);
}
}
}
//结果
// on
// AA
// up
// EE
// FF

链表应用场景:

1、对线性表的长度或者规模难以估计;

2、可以频繁做插入删除操作;

3、构建动态性比较强的线性表。

/**
* 自定义链表类【双向链表】
*
* @author Administrator
*
*/
public class MyLinkList<E> { // 初始状态下,链表没有任何结点,头结点为null,尾结点为null
private Node<E> head = null;
private Node<E> last = null;
private int num = ;// 数据个数 // 增加数据
public void add(E e) {
// 根据数据创建结点对象
Node<E> node = new Node<E>(e); // 如果链表中已经有结点,就将node作为last的下一个结点
if (last != null) {
last.next = node;
node.front = last;
last = node;
} else {
// 如果链表中还没有结点,node就是第一个结点
// 既是头结点,又是尾结点
head = node;
last = node;
}
num++; }
//插入数据
public void insert(int index, E e) {
// 创建新结点
Node<E> node = new Node<E>(e);
// 找到index位置的结点
Node<E> n1 = getNode(index);
// 找到n1的前一个结点
Node<E> n2 = n1.front; n2.next = node;
node.front = n2; node.next = n1;
n1.front = node; num++;
} public void delete(int index) { } public void delete(E e) { } public void update(int index, E e) {
Node<E> n1 = getNode(index);
n1.data = e;
} public E get(int index) {
Node<E> node = getNode(index);
return node.data;
} //根据内容确定下标
private int getIndex(E e){
int index=-;
Node<E> n = head;
while(n!=null){
index++;
if(n.data.equals(e)){
break;
}
n=n.next;
}
return index;
} public int getIndex2(E e){
for(int i=;i<num;i++){
E e2 = get(i);
if(e2.equals(e)){
return i;
}
}
return -; } //根据下标确定结点
private Node<E> getNode(int index) {
int t = -;
if (index >= && index < num) {
Node<E> n = head; while (n != null) {
t++;
if (t == index) {
break;
}
n = n.next; }
return n; } else {
// 抛出异常
throw new IndexOutOfBoundsException("下标超出边界!index:" + index
+ ",size:" + num);
}
} public int size {
return num;
} } // 内部的结点类,主要为MyLinkList类服务
class Node<E> {
// 结点的数据
E data;
// 对下一个结点的引用
Node<E> next;
// 对前一个结点的引用
Node<E> front; // 创建结点对象的时候必须指定数据
public Node(E e) {
data = e;
} }
public class Main {
public static void main(String[] args){
myLinkList<String> mm=new myLinkList<String>;
mm.add("AA");
mm.add("BB");
mm.add("CC");
mm.add("DD");
mm.add("EE"); mm.insert(,"链");
mm.update(, "表");
for(int i=;i<mm.size;i++){
String s=mm.get(i);
System.out.println(s); }
}
}
//结果
// AA
// BB
// 链
// 表
// DD
// EE

Java--数组和链表的区别以及使用场景的更多相关文章

  1. 面试之路(8)-BAT面试题之数组和链表的区别

    两种数据结构都是线性表,在排序和查找等算法中都有广泛的应用 各自的特点: 数组: 数组是将元素在内存中连续存放,由于每个元素占用内存相同,可以通过下标迅速访问数组中任何元素.但是如果要在数组中增加一个 ...

  2. C# 、Java数组申明、初始化区别

    一.数组申明   int[] a1 int a2[] C# 支持 不支持 Java 支持 支持 二.数组申明且初始化    int[] a1 = new int[] { 2, 31 } int a1[ ...

  3. Java中NIO和IO区别和适用场景

    NIO是为了弥补IO操作的不足而诞生的,NIO的一些新特性有:非阻塞I/O,选择器,缓冲以及管道.管道(Channel),缓冲(Buffer) ,选择器( Selector)是其主要特征. 概念解释: ...

  4. Java线程池种类、区别和适用场景

    newCachedThreadPool: 底层:返回ThreadPoolExecutor实例,corePoolSize为0:maximumPoolSize为Integer.MAX_VALUE:keep ...

  5. 牛客网Java刷题知识点之数组、链表、哈希表、 红黑二叉树

    不多说,直接上干货! 首先来说一个非常形象的例子,来说明下数组和链表. 上体育课的时候,老师说:你们站一队,每个人记住自己是第几个,我喊到几,那个人就举手,这就是数组. 老师说,你们每个人记住自己前面 ...

  6. 栈的Java实现-分别使用数组和链表

    栈是非常重要的数据结构,栈具有后进先出的特点. 在JVM内部,每个线程维护一个栈,对于每个方法调用,入栈一个元素,成为栈帧,当方法执行完成后,对应的栈帧出栈. 栈帧中,也包含一个栈,称为操作数栈. 一 ...

  7. 数组、链表、Hash(转)

    在程序中,存放指定的数据最常用的数据结构有两种:数组和链表. 数组和链表的区别: 1.数组是将元素在内存中连续存放. 链表中的元素在内存中不是顺序存储的,而是通过存在元素中的指针联系到一起. 2.数组 ...

  8. java学习笔记(基础篇)—java数组

    一:什么是数组,什么时候使用数组? 数组是用来保存一组数据类型相同的元素的有序集合,数组中的每个数据称为元素.有序集合可以按照顺序或者下标取数组中的元素. 在Java中,数组也是Java对象.数组中的 ...

  9. 源码:Java集合源码之:数组与链表(一)

    数组和链表是数据结构中最基本的部分. 数组 在java中,数组定义为一种基本类型,其可以通过下标获取到对应位置的数据.那么这种结构的数据,在内存中是怎么存放的呢? 数组在内存中是一段连续的存储单元,每 ...

随机推荐

  1. P2P系统哪家强,功能其实都一样

    现在的P2P平台有好几千家了,了解了其中的几十家,发现用户端的P2P界面功能都差不多.下面来做个简要的总结: 1.通用功能  注册.登录  2.投资理财  针对理财人的投标.债权转让  3.借款申请  ...

  2. 【习题 3-1 UVA - 1585】Score

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 模拟水题 [错的次数] 在这里输入错的次数 [反思] 在这里输入反思 [代码] #include <bits/stdc++.h ...

  3. sum()函数——MATLAB

    a=sum(A)  %列求和 b=sum(A,2) %行求和 c=sum(A(:)) %矩阵求和 假定A为一个矩阵: sum(A)以矩阵A的每一列为对象,对一列内的数字求和. sum(A,2)以矩阵A ...

  4. [RxJS] Replace zip with combineLatest when combining sources of data

    This lesson will highlight the true purpose of the zip operator, and how uncommon its use cases are. ...

  5. boost::asio的http client应用笔记

    1 踩过的坑 1.1 io_service boost::asio::io_service::run()会一直运行到没有任务为止,假设中途调用stop().则全部等待中的任务会立马运行.要在停止的时候 ...

  6. MHA 一主两从搭建-脚本VIP-自动切换

    环境介绍:主机名 IP MHA角色 MySQL角色node1 192.168.56.26 Node MySQL Master node2 192.168.56.27 Node MySQL Master ...

  7. [Angular] Using InjectionToken

    Previously we have 'OpaqueToken', but it is DEPRECATED. The new one is called 'InjectionToken'. The ...

  8. Eclipse 快捷键大全 分类: C_OHTERS 2014-06-01 13:05 332人阅读 评论(0) 收藏

      精选常用: 1.  ctrl+shift+r:打开资源 这可能是所有快捷键组合中最省时间的了.这组快捷键可以让你打开你的工作区中任何一个文件,而你只需要按下文件名或mask名中的前几个字母,比如a ...

  9. 事件处理之一:两种方式:监听器与回调 分类: H1_ANDROID 2013-10-31 10:26 3250人阅读 评论(0) 收藏

    Android组件的事件处理有2种方式: 1.基于监听器的事件处理方式:先定义组件,然后为组件设定监听器. 详见http://blog.csdn.net/jediael_lu/article/deta ...

  10. LinearLayout的一些注意事项 分类: H1_ANDROID 2013-10-26 23:01 856人阅读 评论(0) 收藏

    1.orientation的默认值为horizontal,即从左向右排列.由于一般从上向下排列,所以必须指定orientation属性. 2.layout_gravity与gravity的区别: (1 ...