欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java核心技术 卷1笔记(一):第3章 java基本的程序设计结构

程序员文章站 2022-05-01 11:49:49
...

第3章 java基本的程序设计结构
程序设计的相关的基本概念:如数据类型、分支以及循环在java中的实现方式。
基于GUI的Java应用程序设计技术并不是一件很容易的事情,编程者需要掌握很多相关知识才能创建窗口、添加文本和按钮框等。
关键字class表明java程序中的全部内容都包含在类中。这里,只需要将类作为一个加载程序逻辑的容器。
程序逻辑定义了应用程序的行为。

类是构建所有java应用程序和applet的构建块。java应用程序中的全部内容都必须放置在类中。
源码的文件名必须与共有类的名字相同,并用.java作为后缀名。

java编译器将字节码文件自动地命名为.class文件,并与源文件存储在同一个目录下。

每个java应用程序都必须有一个main方法。

java的类与C++的类很相似。但还是存在一些差异。
java中的所有函数都属于某个类的方法。因此java中的main方法必须有一个外壳类。

java使用的通用语法是: object.method(parameters)。这等价于函数调用
java中的注释可以用来自动生成文档。这种注释以/*开始,以/结束。

数据类型:java是一种强类型语言,这意味着必须为每一个变量声明一种类型。
java中一共有8种基本类型:4种整型,2种浮点类型,1种用于表示Unicode编码的字符单元的字符类型char,还有一个布尔类型。

type bytes range
int 4 ±2147483648正好20亿
short 2 ±32768
long 8 ±9223372036854775808
byte 1 -128~127

float 4 有效位数为6~7位。后缀F
double 8 有效位数为15位。后缀D
在java中NaN不是一个数字。一个正整数除以0的结果为正无穷大。计算0/0或者负数的平方根结果为NaN。
可以使用Double.isNaN方法

java中有一个能表示任意精度的算术包,通常称为“大数值”big number。
它本质上是一个java对象。

3.4 java中的变量
3.4.1 变量初始化
不对变量进行初始化就使用,java会报错。
变量声明可以放在任何地方。(编译过程如何实现的?)
在java中不区分变量的声明与定义。
3.4.2 常量
在java中,利用关键字final声明常量(必须)。c++中用const。
在java中,经常希望某个变量可以在一个类中的多个方法中使用。通常将这些常量称为类常量。c++中也有public和private的类变量
可以使用static final设置一个类常量。如果一个常量被声明为public,那么其他类的方法也可以使用这个常量。
3.6 字符串

//字符串
String s = "hello";
//子串
String sub_s = s.substring(0,3);
//拼接:使用加号
String s1 = "a";
Stirng s2 = "b"
Stirng s3 = s1 + s2;//s3="ab"

不可变字符串
Stirng类没有提供用于修改字符串的方法。
在java中很容易实现字符串的修改:

s = s.substring(0,3) + "p!"//hello变help

检测两个字符串是否相等:

s.equals(s1);//判断两个字符串是否相等。

判断两个字符串是否相等而忽略大小写:

s.equalsIgnoreCase(t)

一定不能使用== 运算符检测两个字符串是否相等。
c++注释:c++的string类重载了运算符以便于检测字符串内容是否相等。
c程序员从不用
对字符串进行比较,而是使用strcmp函数。java的compareTo方法
与strcom完全类似。因此也可以这样来使用:if (greeting.compareTo(“hello”) == 0)…

查看第index个位置的代码单元:

greeting.charAt(index);

查看第index个位置的代码点:

int ind = greeting.offsetByCodePoints(0,i);
int cp = greeting.codePointAt(index)

注意这里描述的差别,这里不像c语言中描述的那样称为第几个元素。所以java中string类型不是一个字符串数组,
那称呼为什么呢?准确地说,java字符串就是一段Unicode字符序列。

String 类提供处理 Unicode 代码点(即字符)和 Unicode 代码单元(即 char 值)的方法。

public class str
{
	public static void main(String[] args)
	{
		String greeting = "hello";
		int n = greeting.length();
		System.out.println(n);
		
		int cpCount = greeting.codePointCount(0, greeting.length());
		
		//System.out.println(cpCount);
		
		int index = 0;
		char c = greeting.charAt(index);//代码单元是一个字符
		int i =  greeting.codePointAt(index);//代码点是一个数值
		System.out.printf("c = %c\n", c);//输出:c = h
		System.out.printf("i = %d\n", i);//输出:i = 104
	}
}

如果想要遍历一个字符串,并且依此查看每一个代码点,使用下列语句:

int cp = sentence.codePointAt(i);
if(Character.isSupplementaryCodePoint(cp))
{
	i += 2;
} 
else
{
	i++;	
} 

(这里看不太明白)

//字符串API
char charAt(int index);//返回给定位置的代码单元,除非对底层的代码单元感兴趣,否则不需要调用这个方法。
int codePointAt(int index);//返回给定位置的开始或结束的代码点
int offsetByCodePoints(int startIndex, int cpCount);//返回从startIndex代码点开始,位移cpCount后的代码点索引
int compareTo(String other);//按照字典顺序,如果字符串位于other之前,返回一个负数,如果位于other之后,返回整数,如果相等,返回0
boolean endsWith(String suffix);//如果字符串以suffix结尾,返回true.
boolean equals(Object other);//如果字符串与other相等,返回true
boolean equalsIgnoreCase(String other);//忽略大小写的比较
int indexOf(String str);
int indexOf(String str, int fromIndex);
int indexOf(int cp);
int indexOf(int cp, int fromIndex);
//返回与字符串str或代码点cp匹配的第一个子串的开始位置。这个位置从索引0或者fromIndex开始计算。
//int length
int codePointCount(int startIndex, int endIndex);//返回startIndex和endIndex-1之间的代码点数量。没有配成对的代用字符将计入代码点。
Stirng replace(CharSequence oldString, CharSequence newString);//返回的是一个新对象。可以使用String或者StringBuilder对象作为CharSequence参数
boolean starsWith(String prefix);
String substring(int beginIndex);
String substring(int beginIndex, int endIndex);
Stirng toLowerCase();
String toUpperCase();
String trim();//返回一个新的字符串,这个字符串将删除了原始字符串头部和尾部的空格。

3.6.8 构建字符串:
有些时候,需要由较短的字符串构建字符串,例如,按键或者来自文件中的单词。
采用字符串连接的方式达到此目的效率比较低。每次连接字符串,都会构建一个新的String对象,即耗时,又浪费空间。使用StringBuilder类就可以避免这个问题的发生。
首先构建一个空的字符串构建器:

StringBuilder builder = new StringBuilder();

当每次需要添加一部分内容时,就调用append方法:

builder.append(ch);
builder.append(str);

在需要构建字符串时就调用toString方法:

String completeString = builder.toString();

3.7 输入输出:
读取“标准输入流”System.in要比System.out复杂。要想通过控制台进行输入,
首先需要构造一个Scanner对象,并与标准输入流关联。Scenner类定义在java.util包中,在程序最开始添加:import java.util.*;

import java.util.*;
//...
Scenner in = new Scenner(System.in);

实现各种操作:
nextLine:输入下一行
next:读取一个单词
nextInt:读取一个整数

在控制台进行输入时,输入是可见的。比如现在建了一个数据库,如果想输入密码怎么办?
java中肯定有办法解决这个问题,使用了一个新的类:console

Console cons = System.console();
String username = cons.readline("User name: ");
char[] passwd = cons.readPassword("Password: ");

3.7.2 格式化输出:
和C语言差不多
还有一个format方法。在学MFC的时候用过。在java用法如下:

String message = String.format("Hello, %s. Next year you'll be %d", name, age);

还有System.out.println功能不必System.out.printf。后者可以使用%控制输出。而前者不能。
3.7.3 文件输入和输出

Scenner in = new Scenner(new File("myfile.txt"));//要想对文件进行读取,就需要用一个File对象构造一个Scanner对象
PrintWriter out = new PrintWriter("myfile.txt");

有时候文件不一定存在。这时就需要告诉编译器,可能出现“找不到文件”的异常。

public static void main(String[] args) throws FileFoundException
{
	Scenner in = new Scenner(new File("myfile.txt"));
}

当采用命令行方式启动一个程序时,可以利用重定向将任意文件捆绑到System.in和System.out

java MyProg < myfile.txt > output.txt

3.10 数组
数组是一种数据结构,而string是一种类型。

int[] a;//这条语句只声明了变量a,并没有初始化。应该使用new运算符创建数组。
int[] a = new int[100];//创建一个可以存储100个整数的数组

3.10.2 数组初始化以及匿名数组
数组拷贝:在java中,允许将一个数值变量拷贝给另外一个数组变量。此时两个变量将引用同一个数组。

int[] luckynumbers = a;

如果希望将一个数组的所有值拷贝到一个新的数组中去,就要使用Arrays类的copyOf方法。

int[] copiedLuckyNumbers = Arrays.copyOf(luckynumbers. luckynumbers.length);

java数组与C++数组在堆栈上有很大不同,但基本上与分配在堆上的数组指针一样。
int[] a = new int[100];//java
不同于 int a[100];//c++
而等同于 int* a = new int[100];//c++
java中的[]运算符被预定义为检查数组边界,而没有指针运算。即不能通过a+1得到数组的下一个元素。

3.10.4 命令行参数
每一个java应用程序都有一个带String[] args参数的main方法。这个参数表明main方法将接受一个字符串数组,也就是命令行参数。

public class Message
{
	public static void main(String[] args)
	{
		if args[0].equals("-h"))
		{
			System.out.print("Hello, ");
		}
		else if (args[0].equals("-g"))
		{
			System.out.print("Goodble, ");
		}
		for (int i=1; i<args.length; i++)
		{
			System.out.print(" " + args[i]);
		}
		System.out.print("!");
	}
}

运行程序的语句:java Message -g cruel world
args数组将包含下列内容:
args[0]:"-g"
args[1]:“cruel”
args[2]:“world”
程序结果为:Goodble, cruel world!

3.10.5 数组排序 sort方法Arrays.sort方法

Arrays的一些常用API
static String toString(type[] a);
static type copyOf(type[] a, int length);
static type copyOf(type[] a, int star, int end);
static int sort(type[] a);
static int binarySearch(type[] a, type v);
static int binarySearch(type[] a, int start, int end, type v);//采用二分搜索算法查找值v,如果查找成功,则返回相应的下标值
static void fill(type[] a, type v);//将数组的所有元素值设置为v
static boolean equals(type[] a, type[] b);//如果两个数组的大小以及对应位置元素值相等,返回真值

3.10.6 多维数组
要想快速地打印一个二维数组的数据元素列表,可以调用:

System.out.println(Arrays.deepToString(a));

3.10. 7 不规则数组
要想创建一个不规则的数组,首先需要分配一个具有所含行数的数组:

int[][] odds = new int[NMAX+1][];

接下来分配这些行:

for(int n=0; n<=NMAX; n++)
{
	odds[n] = new int[n+1];
}

访问元素:

for(int n=0; n<odds.length; i++)
{
	for(int k=0; k<odds[n].length; k++)
	{
		odds[n][k] = lotterOdds;
	}
}

java的声明:

double[][] balances = new double[10][6];

不同于C++中的声明:

double balances[10][6];

也不同于C++中的声明:

 double (*balances)[6] = new double[10][6];

而是创建了一个包含10个指针的一个数组:

double** balances = new double*[10]; //C++