【Java】List接口的应用,与C++中vector应用比较 (一)

【写作原因】

在解决【LeetCode.113 Path Sum II】时,我分别采用Java和C++,感觉其中差异有整理一下的必要。

【动态数组的创建】

在编程中,很多情况下,在预编译过程阶段,数组的长度是不能预先知道的,必须在程序运行时动态的给出,但是问题是,编程语言C/C++、Java要求定义数组时,必须明确给定数组的大小,要不然编译通不过。形如LeetCode113题,求满足要求的二叉树路径,由于二叉树结构多样,遍历路径繁多,事先无法确定路径长度。这时候,我们需要创建一个容量可以根据实际需要变化数组(或者存储器)。

[一]在C++中,最常用的方法是:采用new方法创建动态数组和采用vector容器来创建可变长数组

1、new 方法:int *p=new int[num];创建一个容量为num的int型数组,num可来自外部输入、函数传递等,int型指针p指向动态数组的首地址,在动态数组创建完成后,我们可以下标访问数组元素:p[0],p[1]...,但是new方法不能创建二维数组,只能创建一维数组,并且创建后数据元素操作缺乏灵活性;用得最多的地方当属创建链表结点;

2、vector容器:相比于new方法,vector容器功能非常强大,具有高度的灵活性,常用基本操作:

(1)头文件#include<vector>.

(2)创建一维vector对象,vector<int> vec;二维vector<vector<int>> vec2;

(3)尾部插入数字:vec.push_back(a);

(4)尾部元素弹出:vec.pop_back();相当于删除尾部元素;

(5)使用下标访问元素,cout<<vec[0]<<endl;记住下标是从0开始的,和数组的访问形式一样。

(6)插入元素:vec.insert(vec.begin()+i,a);在第i+1个元素前面插入a;

(7)删除元素:vec.erase(vec.begin()+2);删除第3个元素

vec.erase(vec.begin()+i,vec.end()+j);删除区间[i,j-1];区间从0开始

(8)向量大小:vec.size();

(9)清空:vec.clear();

(10)初始化赋值:

vector c1(c2)      // 复制一个vector(c2也是一个vector)

vector c(n)        // 创建一个vector,含有n个数据,数据均已缺省构造产生

vector c(n, elem) // 创建一个含有n个elem元素的vector

vector c(beg,end) // int array[]={1,2,3},beg=array,end=array+3,用数组为vector赋值

由于我们可以通过push_back()和pop_back()这两个函数动态改变vector中数据,从而采用vector很容易实现动态存储空间的建立,这种方法在C++中应用极为广泛。

3、常用算法

1) 使用reverse将元素翻转:需要头文件#include<algorithm>

reverse(vec.begin(),vec.end());将元素翻转(在vector中,如果一个函数中需要两个迭代器,一般后一个都不包含.)

2) 使用sort排序:需要头文件#include<algorithm>,

sort(vec.begin(),vec.end());(默认是按升序排列,即从小到大).

可以通过重写排序比较函数按照降序比较,如下:

定义排序比较函数:

bool Comp(int a,int b)

{

return a>b;

}

调用时:sort(vec.begin(),vec.end(),Comp),这样就降序排序。

[二] 在Java中,最常用的方式是:采用ArrayList和List接口

java集合的主要分为三种类型:

Set(集)

List(列表)

Map(映射)

要深入理解集合首先要了解下我们熟悉的数组:数组是大小固定的,并且同一个数组只能存放类型一样的数据(基本类型/引用类型),而JAVA集合可以存储和操作数目不固定的一组数据。 所有的JAVA集合都位于 java.util包中! 在Java中有一个Array类,专门用于操作数组,很有用,但是,它无法实现数组的容量动态增减,所以,要用到集合,集合有很多优点,这个问题可以单独写篇文章了,这里不详述了!!!

1、ArrayList:Java动态数组是一种可以任意伸缩数组长度的对象,在Java中比较常用的是ArrayList创建动态数组,简单例子:

ArrayList temp = new ArrayList(); //创建一个ArrayList对象,temp为对象的引用
for( int i=0;i <10;i++ ) //给数组增加10个Int元素
temp.Add(i);
temp.RemoveAt(5);//将第6个元素移除
for( int i=0;i<3;i++ ) //再增加3个元素
temp.Add(i+20);
Int32[] values = (Int32[])temp.ToArray(typeof(Int32));//返回ArrayList包含的数组

1)ArrayList是Array的复杂版本

ArrayList内部封装了一个Object类型的数组,从一般的意义来说,它和数组没有本质的差别,甚至于ArrayList的许多方法,如Index、IndexOf、Contains、Sort等都是在内部数组的基础上直接调用Array的对应方法。

2)内部的Object类型的影响

对于一般的引用类型来说,这部分的影响不是很大,但是对于值类型来说,往ArrayList里面添加和修改元素,都会引起装箱和拆箱的操作,频繁的操作可能会影响一部分效率。 但是恰恰对于大多数人,多数的应用都是使用值类型的数组。

消除这个影响是没有办法的,除非你不用它,否则就要承担一部分的效率损失,不过这部分的损失不会很大。

3)数组扩容

这是对ArrayList效率影响比较大的一个因素。

每当执行Add、AddRange、Insert、InsertRange等添加元素的方法,都会检查内部数组的容量是否不够了,如果是,它就会以当前容量的两倍来重新构建一个数组,将旧元素Copy到新数组中,然后丢弃旧数组,在这个临界点的扩容操作,应该来说是比较影响效率的。

2、Java中List接口:

我们知道,Java中,接口不是类,不能使用new方法进行实例化;但是,接口可以声明接口变量,如List temp;接口变量必须引用实现了接口的类的对象,如ArrayList类实现了List接口,那么:List<String> temp=new ArrayList<String>()就是合法的。

 List的特征是其元素以线性方式存储,集合中可以存放重复对象。 List接口主要实现类包括:

(1) ArrayList() : 代表长度可以改变得数组。可以对元素进行随机的访问,向ArrayList()中插入与删除元素的速度慢。

(2)LinkedList(): 在实现中采用链表数据结构。插入和删除速度快,访问速度慢。

List接口常用方法如下:

通过上述List接口提供的方法,我们可以对List列表中的数据进行“丰富”的操作,下面以一个实例来理解List接口的应用:【LeetCode】113. Path Sum II 解法:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {

    public List<List<Integer>> pathSum(TreeNode root, int sum)
    {
	   List<List<Integer>> result=new ArrayList<List<Integer>>();//List接口引用ArrayList类的对象
	   List<Integer> temp=new ArrayList<Integer>();//List引用ArrayList对象,存放当前路径

	   if(root==null)return result;
	   DFS(result,temp,root,sum);
	   return result;
    }

    void DFS(List<List<Integer>> result,List<Integer> temp,TreeNode root,int sum)
    {
	   if(root==null)return;
	   if(root.left==null&&root.right==null)
	   {
		   temp.add(root.val);//当前路径中添加元素
		   if(sumOfPath(temp)==sum)
			   result.add(new ArrayList(temp));//注意List接口的add()方法的用法
		   temp.remove(temp.size()-1);//当前路径末端元素弹出,注意下标从0开始
		   return;
	   }
	   else
	   {
		   temp.add(root.val);//当前路径添加元素,采用add()
		   DFS(result,temp,root.left,sum);
		   DFS(result,temp,root.right,sum);
		   temp.remove(temp.size()-1);//当前路径弹出末端元素
	   }
   }

   int sumOfPath(List<Integer> temp)
   {
	   int sum=0;
	   for(int i=0;i<temp.size();i++)
	   {
		   sum+=temp.get(i);//采用get()方法获取下标为i的元素
	   }
	   return sum;
   }
}

后续再补充......

看考文章:http://blog.csdn.net/speedme/article/details/22398395

时间: 2024-08-06 06:41:25

【Java】List接口的应用,与C++中vector应用比较 (一)的相关文章

java 通过接口在后台管理器中生成数据

需求:测试人员在后台批量添加数据很麻烦,特别是针对一款商品配置了英语,还需要手动添加法语.俄语.阿拉伯语,很麻烦,但是因为没有项目组配合,做个小工具批量生成数据就只有自己去研究了 第一步:通过抓包工具fiddler查看接口走向 第二步:模拟url,进行请求 第三步:验证结果 第一步:从接口中我了解到,我们需要获取原始语言的数据,如:标题.名称.文件标题.详细信息,在把数据取出来,取出来后,在调用商品增加的接口,把数据内容填充进去,进行提交,就完了 目前我们排除登录态的问题,默认是可以登录成功的,

java微信接口之四—上传素材

一.微信上传素材接口简介 1.请求:该请求是使用post提交地址为: https://api.weixin.qq.com/cgi-bin/media/uploadnews?access_token=ACCESS_TOKEN 其中ACCESS_TOKEN是我们动态获取的. 发送的数据: {"articles":[ { "thumb_media_id":"qI6_Ze_6PtV7svjolgs-rN6stStuHIjs9_DidOHaj0Q-mwvBelOXC

java微信接口之五—消息分组群发

一.微信消息分组群发接口简介 1.请求:该请求是使用post提交地址为: https://api.weixin.qq.com/cgi-bin/message/mass/sendall?access_token=ACCESS_TOKEN   其中ACCESS_TOKEN是我们动态获取的.   发送的数据:(这里使用图文消息示例) { "filter":{ "group_id":"2" }, "mpnews":{ "me

“全栈2019”Java第八十七章:类中嵌套接口的应用场景(拔高题)

难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第八十七章:类中嵌套接口的应用场景(拔高题) 下一章 "全栈2019"Java第八十八章:接口中嵌套接口的应用场景 学习小组 加入同步学习小组,共同交流与进步. 方式一:关注头条号Gorhaf,私信"Java学习小组". 方式二:关注公众号Gorhaf,回复"J

Java Web学习系列——Maven Web项目中集成使用Spring、MyBatis实现对MySQL的数据访问

本篇内容还是建立在上一篇Java Web学习系列——Maven Web项目中集成使用Spring基础之上,对之前的Maven Web项目进行升级改造,实现对MySQL的数据访问. 添加依赖Jar包 这部分内容需要以下Jar包支持 mysql-connector:MySQL数据库连接驱动,架起服务端与数据库沟通的桥梁: MyBatis:一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架: log4j:Apache的开源项目,一个功能强大的日志组件,提供方便的日志记录: 修改后的pom.xm

内功心法 -- Java标记接口

写在前面的话:读书破万卷,编码如有神--------------------------------------------------------------------这篇博客主要来谈谈"Java标记接口"的相关知识,主要内容包括: 1. 概述 2. Serializable 3. Cloneable 4. RandomAccess --------------------------------------------------------------------1.概述 Ja

深入理解Java的接口和抽象类(转)

深入理解Java的接口和抽象类 对于面向对象编程来说,抽象是它的一大特征之一.在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类.这两者有太多相似的地方,又有太多不同的地方.很多人在初学的时候会以为它们可以随意互换使用,但是实际则不然.今天我们就一起来学习一下Java中的接口和抽象类.下面是本文的目录大纲: 一.抽象类 二.接口 三.抽象类和接口的区别 若有不正之处,请多多谅解并欢迎批评指正,不甚感激. 请尊重作者劳动成果,转载请标明原文链接: http://www.cnblogs.

Java中vector的使用详解

Vector 可实现自动增长的对象数组. java.util.vector提供了向量类(vector)以实现类似动态数组的功能.在Java语言中没有指针的概念,但如果正确灵活地使用指针又确实可以大大提高程序的质量.比如在c,c++中所谓的“动态数组”一般都由指针来实现.为了弥补这个缺点,Java提供了丰富的类库来方便编程者使用,vector类便是其中之一.事实上,灵活使用数组也可以完成向量类的功能,但向量类中提供大量的方法大大方便了用户的使用.     创建了一个向量类的对象后,可以往其中随意插

(转载)深入理解java的接口和抽象类

本文转自地址:http://www.cnblogs.com/dolphin0520/p/3811437.html 作者:海子 出处:http://www.cnblogs.com/dolphin0520/ 深入理解Java的接口和抽象类 对于面向对象编程来说,抽象是它的一大特征之一.在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类.这两者有太多相似的地方,又有太多不同的地方.很多人在初学的时候会以为它们可以随意互换使用,但是实际则不然.今天我们就一起来学习一下Java中的接口和抽象类

Java的接口和抽象类

深入理解Java的接口和抽象类 对于面向对象编程来说,抽象是它的一大特征之一.在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类.这两者有太多相似的地方,又有太多不同的地方.很多人在初学的时候会以为它们可以随意互换使用,但是实际则不然.今天我们就一起来学习一下Java中的接口和抽象类.下面是本文的目录大纲: 一.抽象类 二.接口 三.抽象类和接口的区别 若有不正之处,请多多谅解并欢迎批评指正,不甚感激. 请尊重作者劳动成果,转载请标明原文链接: http://www.cnblogs.