上次提前说了java中的面向对象,主要是为了使用这些常见类做打算,毕竟Java中一切都是对象,要使用一些系统提供的功能必须得通过类对象调用方法。其实Java相比于C来说强大的另一个原因是Java中提供了大量可用的标准库

字符串

字符串可以说是任何程序都离不开的东西,就连一个简单的hello world程序都用到了字符串,当时C语言中对字符串的支持并不太好,C语言中的字符串实质上是一个字符数组。为了方便不同的C/C++库都有自己的字符串实现。而Java中内置了对字符串的支持,Java中的字符串是一个叫做String的对象。

根据jdk文档的描述,我们需要注意一下几点:

  1. Java程序中的所有字符串文字(例如"abc" )都被实现为此类的实例
  2. String对象是可以共享的
  3. String对象是不可变的

字符串的内存分布

一般把类似于 "abc" 这样直接通过字面值表示的字符串作为字面常量,这种在Java中也是一个字符串,只是它与普通的new出来的字符串在内存的存储上有点不一样,下面请看下面的代码

class StringDemo{public static void main(String[] args){String a = "abc";String b = "abc";String c = new String("abc");System.out.println(a == b);System.out.println(a == c);System.out.println(b == c);}
}

针对字符串来说 == 比较的是它们的地址是否相同,这个程序分别输出的是 true、false、false,也就是说a b 是指向的同一个地址空间,而c则不是。它们的内存分布如下:

一般程序在加载到内存地址空间后,会被划分为4个部分,全局数据段、代码段、堆、栈。而全局代码段是用来存放全局变量的。在C中如果我们写下这样的代码:

char* psz1 = "abc";
char* psz2 = "abc";

那么在程序加载到内存中时,在全局数据段中会存在一个连续的内存空间保存的是 'a','b','c','\0' 这4个值,一旦有char型指针指向"abc" 这样的字符串,那么系统会自动将这段内存的地址给赋值到对应的指针变量中,而且这个内存是只读内存,如果尝试往里面写入数据,则会造成程序崩溃。

Java中也是类似的,当出现 "abc" 的时候,其实系统早就为它在堆中创建了一个String对象,如果去阅读String的源码就会发现String中负责保存字符串的是一个 byte型的数组,所以在初始化的时候会再创建一个byte型数组,然后由字符串中成员变量保存它的地址,所以在内存图中看到有String也有byte[]。而且这个字符串是保存在堆中的常量字符串池中的,它的生命周期与程序相同(或者说与主线程相同)。

每当直接使用 "abc" 这样的字面常量的时候会自动将常量字符串池中相关的字符串对象的指针赋值给对应的对象。这样造成了上述程序中 a == b 为true的情况。而c是通过new关键字在程序运行期间动态创建的。所以JVM会在程序执行到这步的时候额外创建一个对象,并将 "abc" 这个字符串对应的byte[] 中的值拷贝到新的内存中。

这样就很容易理解上面的前两条了,至于字符串不可变,可以参考我之前写的关于类型中的说明(字符串的值发生改变时,在内存中其实是开辟了一块新的内存用于保存新的字符串内容,而丢弃了从前的字符串)

常见字符串方法

这里再简单的列举一下字符串中常见的方法,这些方法都可以在JDK文档都可以查到。

String(); //初始化新创建的 String对象,使其表示空字符序列
String(byte[] bytes); //通过使用平台的默认字符集解码指定的字节数组来构造新的 String
String(byte[] bytes, int offset, int length); //从bytes[] 数组中的第offset 位置开始,截取length个成员来初始化一个String
char charAt(int index); //返回指定位置处的索引
int compareTo(String anotherString); // 按字典顺序比较两个字符串的大小,为0表示两个字符串相同
int compareToIgnoreCase(String str); //比较两个字符串的大小,忽略大小写
String concat(String str) ; //字符串拼接
byte[] getBytes(Charset charset); //将字符串转化为byte型数组,并返回新的byte数组
int indexOf(String str); //返回字串第一次出现的位置
int length() ; //返回字符串的长度
String[] split(String regex); //按正则表达式进行分割,并返回对应的字符串数组

注意一下,这里返回数组或者新字符串的,都是在函数内部新建的,与原来的无关。所以这里是没办法拿到字符串底层的数组对象再来修改内存值的。

数组

java中数组的定义如下:

int[] Array1 = new int[10]; //定义了一个拥有10个整型数据的数组
int[] Array2 = new int[]{1, 2, 3, 4, 5, 6, 7,8, 9, 0}; //创建数组并初始化
int[] Array3 = {1,2 ,3,4,5,6,7,8,9,0}; 

相比于C中数组的定义来说,Java中的定义更容易让人理解,对应数据类型后面加一对 [] 就是对应的数组类型了。而C中,中括号是写在变量后面的,相比于Java中的定义来说就显的有点怪异了。或者说C中从根本上来说数组并不算是一种特别的数据类型,仅仅只是开辟相同数据类型的一块连续的内存而已。至于[] 在C中应该只是表示寻址而已,毕竟汇编中我们经常看到类似于 esp:[eax] 这样的东西。

Java中的数组是一种单独的数据类型,它是一种引用类型,也就是说它的变量名中保存的是它的地址。

它的使用十分的简单,与C/C++中数组的使用基本相同,注意事项也是基本相同。但是有一点很重要的不同,Java中的数组允许动态指定长度,也就是通过变量来指定长度,而C中必须静态的指定长度,也就是在程序运行之前就需要知道它的长度。这是因为Java中数组是引用类型,是new在堆上的,而C中数组是分配在全局变量区或者栈上的,在程序运行之初就需要为数组分配内存。

//这样的代码是可以编译通过的
int length = 10;
int array[] = new int[length];

数组作为函数参数

import java.util.Arrays;class Demo{public static void main(String[] args){int length = 10;int array[] = new int[length];System.out.println(Arrays.toString(array));test(array);System.out.println(Arrays.toString(array));}public static void test(int[] array){for(int i = 0; i < array.length; i++){array[i] = i;}}
}

运行上述的代码,发现函数中修改array的值在函数结束后也可以生效,这是因为数组是一个引用类型,在C中我们说要想改变实参的值,需要传入对应的引用或者指针。在函数中通过引用访问,实际上在访问对应的内存,所以这里其实是在修改对应内存的值。当然可以修改实参的值了。

ArrayList类

之前在数组中,我们说数组一旦定义,是不能改变大小的,那么如果我后续需要使用可变大小的数组呢?Java中提供了ArrayList这样的容器。由于它是一个通用的容器,而java又是一个强类型的语言,所以在定义的时候需要事先指定我们需要使用容器存储何种类型的数据。一般ArrayList的定义如下:

ArrayList<String> array = new ArrayList();

表示容器内部存储的是字符串。

需要注意的是容器中只能存储引用类型,不能存储像int、double、char这样的基本类型,如果要存储这样的数据,需要存储它们对应的封装类。比如int 类型对应的封装类为 Integer。

它的常用方法如下:

ArrayList(); //构造方法
boolean add(E e);//添加元素
void clear(); //清空
E get(int index); //获取指定位置的元素
int indexOf(Object o); //查询元素第一次出现的位置
E remove(int index); //删除指定位置的元素
E remove(Object o); //从列表中删除指定元素的第一个出现(如果存在)
int size(); //获取容器中元素个数
void sort(Comparator<? super E> c); //使用提供的 Comparator对此列表进行排序

键盘输入

Java中的键盘输入主要通过Scanner类来实现,Scanner需要提供一个输入流,从输入流中获取输入。一般常用的输入流是 System.in 表示从键盘输入,例如:

Scanner sc = new Scanner(System.in);

Scanner类中常用方法是一系列的next方法,next方法主要功能是根据指定 的分割符,从输入流中取出下一个输入并做相应的转化,比如nextInt()会转化为int,nextBoolean() 会转化为boolean类型等等,next()方法会直接转化为字符串。

默认情况下next函数会通过空格进行转化。

import java.util.Scanner;
import java.util.ArrayList;class Demo{public static void main(String[] args){ArrayList<String> array = new ArrayList<String>();Scanner sc = new Scanner(System.in);String str = sc.next();array.add(str);while(sc.hasNext()){array.add(sc.next()); }for(int i = 0; i < array.size(); i++){System.out.println(array.get(i));}}
}

这段代码,会将输入的数据依次存储到ArrayList容器中。因为程序事先不知道用户会输入多少数据,所以这里采用可以可变长度的容器来存储

//输入(> 表示cmd的提示符)
>hello world python java c++ c lisp
// 输入ctrl + c来退出sc.next的输入
> ctrl+c//输出
>hello
world
python
java
c++
c
lisp

上述代码首先执行到sc.next 位置,并且中断下来,我们输入上述的一些字符串,然后回车,然后程序继续执行,在循环中根据空格,依次从里面取出每一个值,并放到容器中。当没有值时,程序会再次中断在sc.next() 的位置,这个时候输入 ctrl + c ,此时程序再次执行到 sc.hasNext() 这个地方会返回false,这个时候循环退出,并依次打印这些内容。

这个程序证明了上面说的,next方法会根据指定的分割符,依次从输入流中取出下一个输入。当然如果想要一次读取一行,可以使用 nextLine方法。

更多内容请查阅JDK文档。


转载于:https://www.cnblogs.com/lanuage/p/10885669.html

Java 学习笔记(4)——java 常见类相关推荐

  1. Java学习笔记1:Java中有关print、println、printf的用法和区别

    Java学习笔记1:Java中有关print.println.printf的用法和区别 最近在学习java,写一些笔记记录下. 1.print()函数是一般的标准输出,但是不换行. 2.println ...

  2. Java学习笔记(java基础)

    Java学习笔记(第一周) Java 介绍 Java 发展方向 JVM , JDK , JRE 名词解释 Java语言的特点 Java安装 安装包的下载 配置环境变量 验证是否安装成功 Java的第一 ...

  3. 【java】java学习笔记之java常用类

    如下图所示为笔者总结的java常用类学习笔记,其中,附带有代码示例(未展开),方便理解记忆.需要源文件的请到我的资源中下载,下载地址:https://download.csdn.net/downloa ...

  4. Java学习笔记——正则表达式(Pattern类、Matcher类和PatternSyntaxException)

    目录 一.Pattern类 (一)Pattern 介绍 (二)Pattern 方法 二.Matcher类 (一)Matcher 类介绍 (二)Matcher 类方法 三.PatternSyntaxEx ...

  5. java时间规划书_【计算机本科补全计划】Java学习笔记(九) Java日期时间

    正文之前 终于好像仿佛看完了菜鸟教程的Java课程,感觉自己收获颇丰!很好,Java看完之后正愁如何开始进阶呢!结果发现菜鸟还准备了Java实例这种好东西!简直就是教程界的良心啊 !!!没事,先写写笔 ...

  6. 【java】java学习笔记之java oop(面向对象)

    如下图所示为笔者总结的java oop(面向对象)学习笔记,其中,附带有代码示例(未展开),方便理解记忆.需要源文件的请到我的资源中下载,下载地址:https://download.csdn.net/ ...

  7. java学习笔记(一) ----java下常用的包功能

    ***java下常用的包*** java.lang----包含一些java语言的核心类,如String,Math,Integer,System,Thread,提供常用的功能. java.awt---- ...

  8. Java学习笔记-7.Java IO流

    一.输入/输出流 1.流:不同类型的输入.输出源    数据流:输入或输出的数据 Java数据流的所有接口和类都是在java.io包中定义的,因此应在程序开头加入 import java.io.* 2 ...

  9. Java学习笔记十:Java的数组以及操作数组

    Java的数组以及操作数组 一:什么是数组: 数组可以理解为是一个巨大的"盒子",里面可以按顺序存放多个类型相同的数据,比如可以定义 int 型的数组 scores 存储 4 名学 ...

最新文章

  1. python3 文件内容搜索 文件名搜索 目录遍历
  2. oracle中做数据字典,oracle中数据字典是干嘛用的啊
  3. 使用SQL语句创建数据库2——创建多个数据库文件和多个日志文件
  4. [LeetCode] Multiply Strings 解题报告
  5. linux rpm和deb的区别,rpm与deb的区别
  6. Python添加模块路径
  7. Android ContentProvider的介绍(很详细)
  8. Android开发之万能适配器
  9. linux数组操作 增删改查,JS实现数组的增删改查操作示例
  10. 商业计划书模板(高质量)
  11. 物联网15年,盘点国内崛起的智能产业
  12. retainall java_瞬间教你学会使用java中list的retainAll方法
  13. jupyter 阿里云服务器配置 远程连接 开机自动启动服务
  14. Help Hanzo(LightOJ - 1197)(欧拉筛 + 思维)
  15. 如何查看电脑的操作系统以及更改计算机名称
  16. gridlayout计算器java_java新手编写亲戚计算器求助
  17. ibm笔记本修复计算机开机按,联想thinkpad重装系统按什么键_联想thinkpad电脑重装系统按哪个键-win7之家...
  18. JAVA并发类包介绍
  19. 最小拍有纹波系统仿真实验Matlab,控制技术实验报告--基于Matlab的最少拍控制系统设计.doc...
  20. python jupyter输出结果_Jupyter noteb中Python子进程的实时stdout输出

热门文章

  1. iOS开发UI篇—UIWindow简单介绍
  2. nodejs、gulp调试工具node-inspector使用
  3. exchange 2010 search mailbox 的幕后强大功能
  4. ORA-01113 file 1 needs media recovery
  5. 定制开发软件所有权_职业所有权软件开发人员指南
  6. angular react_Angular 2 vs React:将会有鲜血
  7. 微信出现“已停止访问该网页”或“关于潜在的违法或违规内容”怎么办?如何获取被屏蔽的网页的网址?...
  8. (C++)设计一个程序能计算一个日期加上若干天后是什么日期and计算日期差值
  9. Web前端面试自我介绍对话技巧注意事项
  10. linux传文件到xp,Linux与Windows XP之间使用FTP互传文件