1 Java程序设计


title: java 基本程序设计
tag: 核心卷知识
categories: Java基础
comment: 关于书籍知识总结
description: 描述

Java基本程序设计

数据类型

Java是一种强类型语言。必须为每一个变量声明一种类型。在Java中一共包括8种基本数据类型,其中4种整型、2种浮点类型、一种用于表示Unicode编码的字符单元的字符类型char和1种表示真值的boolean类型。

整型:owr5W9.png

在Java中,整型的范围与运行Java代码的机器无关。

变量

变量初始化

声明一个变量后,必须使用赋值语句对变量的变化进行初始化,不能够使用未初始化的变量。

反例:
    int vacationDays;
   System.out.prtintln(vacationDays);

正例:
    int vacationDays;
	vacationDays = 12;
或者
    int vacationDays = 12;

Java中可以将声明放在代码中的任何地方。变量的声明尽可能地靠近变量第一次使用的地方,这是一种良好的编程编写风格。

常量

java中通常使用final关键字修饰常量,final关键字表示这个变量只能被赋值一次,赋值之后就不能在修改了。习惯上我们将常量都是使用大写字母。

final double MONEY = 2.54

当我们希望某个常量可以在一个类中的多个方法中使用,此时将这些常量称为类常量。可以使用关键字static final 设置一个类常量。

static final double MONEY = 2.54
数学函数与常量

java中的平方根

double x = 4;
double y = Math.sqrt(x);
System.out.println(y);
强制类型转换

强制类型转换的语法格式是在圆括号中给出想要转换的目标类型,后面紧跟待转换的变量名:

double x = 9.997
int nx = (int) x;
自增与自减运算符

++n和n++;在表达式中是有区别的,前者是先完成加1,后者是先使用原来变量的值

int m = 7;
int n = 7;
int a = 2 * ++m;//16
int b = 2 * n++;//14

在表达式中一般不使用++,因为这样的代码会使人产生困扰。

括号与运算符级别

根据下表给出的运算符优先级次序进行计算,同一个级别的运算符按照从左到右的次序进行计算

o0u0AO.png

o0uRDP.png

枚举类型

有时候,变量的值只在一个有限的集合中。枚举类型包括有限个命名的值。

enum Size{SMALL,MEDIUM,LARGE,EXTRA_LARGE}

字符串

在标准Java类库中提供了一个预定义类,我们很自然地叫做String。每个用双括号括起来的字符串都是String类的一个实例。

子串

String类的substring方法可以从一个较大的字符串中提取出一个子串。

String greeting = "Hello";
String s = greeting.substring(0,3);//Hlo

substring方法的第二个参数是不想复制的第一个位置。这里需要复制的位置为0,1,2的字符。在substring中从0开始计数,直到3为止,但是不包含3.

字符串s.substring(a,b)的长度为b-a;

拼接

java语言支持使用+号连接两个字符串。

int age = 13;
String rating = "PG" + age;// "PG13"

将一个字符串与一个非字符串的值进行拼接时,后者会被转换成字符串。

检测字符串是否相等

可以使用equals方法检测两个字符串是否相等。

s.equals(t)

如果字符串s与字符串t相等,返回true,否则返回false.s与t可以是字符串变量,也可以是字符串字面量。下面的表达式也是合理的:

"Hello",equals(greeting)

如想检测两个字符串是否相等,而不区分大小写,可以使用equalsIgnoreCase方法。

"Hello".equalsIgnoreCase("Hello")

一定不要用==运算符检测两个字符串是否相等!这个运算符只能够确定两个字符串是否放置在同一个位置上。当然,放置在同一个位置上的它们必然相等,但是也完全有可能将内容的多个字符串的拷贝放置在不同的位置上。

空串与Null串

空串""是长度为0的字符串。可以运用以下代码检测一个字符串是否为空:

if(str.length() == 0)if(str.equals(""))

空串是一个Java对象,有自己的串长度和内容。String变量中还可以存放一个特殊的值,名为null,这表示目前没有任何对象与该变量关联。要检测一个字符串是否为Nulll,可以运用以下:

if(str == null)

要检查一个字符串既不是null也不是空串,可以使用以下的条件:

if(str != null && str.length() != 0)

首先需要检查str不为null.

String API

java.lang.string类名中

char charAt(int index)
// 返回给定位置的代码单元
int codePointAt(int index)
// 返回从给定位置开始的码点
int offsetByCodePoints(int startIndex,int cpCount)
// 返回从startIndex开始,位移cpCount后的码点索引
int compareTo(String other)
// 按照字典顺序,如果字符串位于other之前,返回一个负数;如果字符串位于other之后,返回一个整数,如果两个字符串相等,返回0
IntStream codePoints()
// 将这个字符串的码点作为一个流返回。调用toArray将它们放在一个数组中。
new String(int[] codePoints,int offset,int count)
// 用数组中从offset开始的count个码点构造一个字符串
boolean equals(Object other)
// 如果字符串与other相等,返回true
boolean equalsIgnoreCase(String other)
// 如果字符串与other相等(忽略大小写),返回true
boolean startWith(String suffix)
boolean endsWith(String suffix)
// 如果字符串以suffix开头或结尾,则返回true.
int idnexOf(String str)
int indexOf(String str,int fromIndex)
int indexOf(int cp)
int indexOf(int cp,int fromIndex)
// 返回与字符串str或代码点cp匹配的第一个子串的开始位置。这个位置从索引0或fromIndex开始计算。如果原字符串中不存在str,则会返回-1.
int length()
// 返回字符串的长度
int codePointCount(int startIndex, int endIndex)
// 返回startIndex和endIndex-1之间的代码点数量。没有配成对的代用字符将计入代码点。
String replace(CharSequence oldString,CharSequence newString)
// 返回一个新字符串。这个字符串用newString代码原始字符串中所有的oldString.
String substring(int beginIndex)
String substring(int beginIndex,int endIndex)
// 返回一个新字符串。这个字符串包含原始字符串中从beginIndex到串尾或者endIndex-1的所有代码单元。
String trim()
// 返回一个新字符串。这个字符创将删除了原始字符串头部和尾部的空格。
构建字符串

有些时候,需要由较短的字符串构建字符串。采用字符串连接的方式达到此目的的效率比较低。每次拼接一个新的String对象,既耗时,又浪费空间,

使用StringBuilder类就可以避免这个问题发生。

首先,构建一个空的字符串构建器:

StringBuilder builder = new StringBuilder();

当每次需要添加一部分内容是,调用append方法。

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

常用的API

StringBuilder()
// 构建一个空的字符串构建器
int length()
// 返回构建器或缓冲器的代码单元数量
StringBuilder append(String str)
// 追加一个字符串并返回this
StringBuilder append(char c)
// 追加一个代码单元并返回this
void setCharAt(int i,char c)
// 将第i个代码单元设置为c
StringBuilder insert(int offset,String str)
// 在offset位置插入一个字符串并返回this
StringBuilder insert(int offset,Char c)
// 在offset位置插入一个代码单元并返回this
StringBuilder delete(int startIndex,int endIndex)
// 删除偏移量从startIndex 到endIndex-1代码单元并返回this
String toString()
// 返回一个与构建器或缓冲器内容相同的字符串

输入输出

读取输入

要想通过控制台进行输入,首先需要构造一个Scanner对象,并与“标注输入流“System.in关联。

Scanner in = new Scanner(System.in);

利用Scanner类的各种方法实现输入操作,nextLine方法将输入一行,nextLine方法是因为在输入行中有可能包含空格。

String name = in.nextLine();

如果想要读取一个单词,以空白符为分隔符,就调用next方法

String firstName = in.next();

要想读取一个整数,就调用nextInt方法。

int age = in.nextInt();
Java.util.scanner API
Scanner (InputStream in) //用给定的输入流创建一个Scanner对象
String nextLine()  // 读取输入的下一行内容
String next() // 读取输入的下一个单词(以空格为分隔符)
int nextInt()  
double nextDouble 
// 读取并转换下一个表示整数或浮点数的字符序列
boolean hasNext()  // 检测输入中是否还有其他单词
boolean hasNextInt()
boolean hasNextDouble()
//检测是否还有表示整数或浮点数的下一个字符序列
文件输入与输出

要想对文件进程读取,就需要一个用File对象构造一个Scanner对象,如下所示:

Scanner in = new Scanner(Paths.get("myfile.txt"),"UTF-8");

要想写入文件,就需要构造一个PrintWriter对象,在构造器中,只需要提供文件名:

PrintWriter out = new PrintWriter("myfile.txt","UTF-8");

控制循环

与任何程序设计语言一样,Java使用条件语句和循环语句结构控制流程。

块作用域

块(即复合语句)是指由一对大括号括起来的若干条简单的Java语句。一个块可以嵌套在另一个块中。

public static void main(String[] args) {
        int n;
        {
            int k;
            
        }
    }

但是,不能在嵌套的两个块中声明同名的变量。下面的代码就是错误的:

public static void main(String[] args) {
        int n;
        {
            int k;
            int n; // can't redefine n in inner block
        }
    }
条件语句

条件语句的格式为:

if(conditon) statement

条件语句中else子句与最邻近的if构成一组。

if(x <= 0)if(x == 0)sign = 0;else sign = -1;

此处的else与第2个if配对。

循环

当条件为true时,while循环执行一条语句。一般格式为

while(condition) statement

while循环语句首先检测循环条件。因此,循环体中的代码有可能不被执行。如果希望循环体至少执行一次,则应该将检测条件放在最后。使用do/while循环语句可以实现这种操作方式

do statement while(condition)
确定循环

for循环语句是支持迭代的一种通用结构,利用每次迭代之后更新的计数器或类型的变量来控制迭代次数。

for(int i =1; i <= 10; i++){
    System.out.println(i);
}

for语句中的第1部分用于对计数器初始化;第2部分给出每次新一轮循环前执行前要检测的循环条件;第3部分指示如何更新计数器。

有一条不成文的规定:for语句的3个部分应该对同一个计数器变量进行初始化、检测和更新。

多重选择:switch语句

在处理多个选项时,使用if/else结构显得有些笨拙。

Scanner in = new Scanner(System.in);
in choice = in.nextInt();
switch(choice){
    case 1:
        ...
        break;
    case 2:
        ...
        break;
    case 3:
        ...
        break;
    case 4:
        ...
        break;
    default:
        ...
        break;
}

switch语句将从选项值相匹配的case标签处开始执行直到遇到break语句,或者执行到switch语句的结束处为止。如果没有相匹配的case标签,而又default子句,就执行这个子句。

case的标签可以是:

  • 类型为char、byte、short或int的常量表达式
  • 枚举常量
  • 从JavaSE7 开始,case标签还可以是字符串字面量。
中断控制流程语句

与C++不同,Java还提供了一种带标签的break语句,用于跳出多重嵌套的循环语句。有时候,在嵌套很深的循环语句中会发生一些不可预料的事情。此时可能更加希望调到嵌套的所有循环语句之外。通过添加一些额外的条件判断实现各层循环的检测很不方便。

请注意,标签必须放在希望跳出的最外层循环之前,并且必须紧跟一个冒号

oB40KO.png

如果输入有误,通过执行带标签的break跳转到带标签的语句块末尾。对于任何使用break语句的代码都需要检测循环正常结束,还是由break跳出。

还有一个continue语句。与break语句一样,它将中断正常的控制流程,continue语句将控制转移到最内层循环的首部。

Scanner in = new Scanner(System.in);
while( sum < goal){
    n = in.nextInt();
    if(n < 0)continue;
    sum += n;
}
// 如果n<0,则continue语句超过了当前循环体的剩余部分,立刻跳到循环首部

如果将continue语句用于for循环中,就可以跳到for循环的“更新“部分。

for(count = 1; count <= 100;count++){
    n = in.nextInt();
    if(n < 0) continue;
    sum += n;
}
// 如果n < 0,则continue语句跳到count++语句

大数值

如果基本的整数和浮点数精度不能满足需求,那么可以使用java.math包中的两个很有用的类:BigInteger和BigDecimal.这两个类可以处理包含任意长度数字序列的数值。BigInteger类实现了任意精度的整数运算,BigDecimal实现了任意精度的浮点数运算。

使用静态的valueOf方法可以将普通的数值转换为大数值

BigInteger a = BigInteger.valueOf(100);

使用大数值类中的add和multiply方法。

BigInteger c = a.add(b);// c = a+b
BigInteger d = c.multiply(b.add(BigInteger.valueOf(2))); // d = c*(b+2)

数组

数组是一种数据结构,用来存储同一类型的集合。通过一个整型下标可以访问数组中的每一个值。

在声明数组变量时,需要指出数组类型(数组元素类型紧跟[])和数组变量的名字。

int[] a  // 只声明了变量a,并没有将a初始化为一个真正的数组
int[] a = new int[100]; // 创建一个可以存储100个整数的数组。

使用for循环给数组赋值

int[] a = new int[100];
for(int i = 0; i < 100; i++){
    a[i] = i;
}
// 创建一个数字数组时,所有元素都初始化为0。boolean数组的元素初始化为false.对象数组的元素则初始化为一个特殊值null,这表示这些元素还为存放任何对象。
for each循环

Java有一种功能很强的循环结构,可以用来依次处理数组中的每个元素而不必为指定下表值而分心。

增强for循环的语句格式为:

for(variable : collection)statement
// 定义一个变量用于暂存集合中的每一个元素,并执行相应的语句。collection这一集合表达式必须是一个数组或者是一个Iterable接口的类对象。
   
例:
    for(int element : a){
        System.out.println(element);
    }
// 打印数组a的每一个元素,一个元素占一行
数组初始化以及匿名数组

在java中,提供了一种创建数组对象并同时赋予初始值的简化书写形式。下面是一个例子:

int[] a = {2,4,6,8,10}
// 在使用这种语句时,不需要调用new 
new int[]{17,19,23,31,37}
// 初始化一个匿名的数组
a = new int[]{2,4,6,8,10}
// 可以在不创建新变量的情况下重写初始化一个数组
数组拷贝

在java中,允许将一个数组变量拷贝给另一个数组变量。

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

int[] copiedLuckyNumbers = Arrays.copyOf(luckyNumbers,luckyNumber.length);
// 第2个参数是新数组的长度。
luckyNumbers = Arrays.copyOf(luckyNumbers,2*luckyNumbers.length);
// 如果数组元素是数值型,那么多余的元素将被赋值为0;如果数组元素是布尔型,则将赋值为false.相反,如果长度小于原始数组的长度,则只拷贝最前面的数据元素。
数组排序

可以使用Arrays类中的sort方法:

int[] a = new int[1000];
....
Arrays.sort(a)
// 这个方法使用了优化的快速排序算法。排序算法对于大多数数据集合来说都是效率比较高的。

例子:

public class Example {
    public static void main(String[] args) {

        Scanner in = new Scanner(System.in);

        int k = in.nextInt();
        int n = in.nextInt();

        // 创建一个数组用于存储所有元素
        int[] numbers = new int[n];
        for (int i = 0; i < numbers.length; i++) {
            numbers[i] = i+1;
        }

        // 运用第二个数组来存储抽取出来的值
        int[] result = new int[k];
        for (int i = 0; i < result.length; i++){
            // 获取抽取的值
            int r = (int) (Math.random()*n);

            result[i] = numbers[r];

            // 将最后一个元素移动到已经被抽取的元素处
            numbers[r] = numbers[n-1];
            n--;
        }
         // 对获取的数据进行排序
        Arrays.sort(result);
        for (int r:result) {
            System.out.println(r);
        }

    }
}
API
static String toString(type[] a)
// 返回包含a中数据元素的字符串,这些数据元素被放在括号内,并于逗号分隔。
参数: a     类型为intlongshortcharbytebooleanfloatdouble的数组
static type copyOf(type[] a,int length)
static type copyOfRange(type[] a,int start,int end)
// 返回与a类型相同的一个数组,其长度为length或者end-start,数组元素为a的值。
参数: a  类型为intlongshortcharbytebooleanfloatdouble的数组
      start 起始下标(包含这个值)
      end   终止下标(不包含这个值),这个值有可能大a.length。这种情况下,结果为0false.
     length 拷贝的数据元素长度。如果length值大于a.length,结果为0false;否则,数组中只有前面length个数据元素的拷贝值。  
static void sort(type[] a)
// 采用优化的快速排序算法对数组进行排序
参数: a  类型为intlongshortcharbytebooleanfloatdouble的数组
static int binarySearch(type[] a,type v)
static int binarySearch(type[] a,int start,int end, type v)
// 采用二分搜索算法查找值V。如果查找成功则返回相应的下标;否则,返回一个负数值r.
参数: a  类型为intlongshortcharbytebooleanfloatdouble的数组
      start 起始下标(包含这个值)
      end   终止下标(不包含这个值)
      v     同a的数据元素类型相同的值。
static void fill(type[] a,type v)
// 将数组的所有元素值设置为v
参数: a  类型为intlongshortcharbytebooleanfloatdouble的数组
      v  与a数据元素类型相同的一个值
static boolean equals(type[] a,type[] b)
// 如果两个数组大小相同,并且下标相同的元素都对应相等,返回true
参数a,b    类型为intlongshortcharbytebooleanfloatdouble的数组   
多维数组

在java中,声明一个二维数组很简单,如

double[][] balances;

与一维数组一样,在调用new 对多维数组进行初始化之前不能使用它。

balances = new double[n][n];

多维数组的初始化。

int[][] array ={
    {16,3,2,13},
    {5,10,11,8},
    {9,6,7,12},
    {4,15,14,1}
};
不规则数组

Java实际上没有多维数组,只有一维数组。多维数组被解释为“数组的数组“

表达式array[i]引用第i个子数组,也就是二维表的第i行。它本身也是一个数组,array[i][j]引用这个数组的第j项。
由于可以单独地存取数组的某一行,所以可以让两行交换
 array[] temp = array[i];
 array[i] = array[i+1];
array[i+1] = temp;

可以方便的创建一个不规则的数组,即数组的每一行有不同的长度。

想要创建一个不规则的数组,首先需要分配一个具有所含行数的数组
int[][] odds = new int[MAX + 1][];
接下来分配这些行
for(int n = 0; n <= MAX; n++)
    odds[n] = new int[n + 1];
分配数组之后,假定没有超出边界,就可以采用通常的方式访问其中的元素了
    for(int n = 0; n < odds.length; n++){
        for(int k = 0; k < odds[n].length; k++){
            ....
            odds[n][k] = lotterOdds;
        }
    }

11,8},
{9,6,7,12},
{4,15,14,1}
};


#### 不规则数组

Java实际上没有多维数组,只有一维数组。多维数组被解释为“数组的数组“

```java
表达式array[i]引用第i个子数组,也就是二维表的第i行。它本身也是一个数组,array[i][j]引用这个数组的第j项。
由于可以单独地存取数组的某一行,所以可以让两行交换
 array[] temp = array[i];
 array[i] = array[i+1];
array[i+1] = temp;

可以方便的创建一个不规则的数组,即数组的每一行有不同的长度。

想要创建一个不规则的数组,首先需要分配一个具有所含行数的数组
int[][] odds = new int[MAX + 1][];
接下来分配这些行
for(int n = 0; n <= MAX; n++)
    odds[n] = new int[n + 1];
分配数组之后,假定没有超出边界,就可以采用通常的方式访问其中的元素了
    for(int n = 0; n < odds.length; n++){
        for(int k = 0; k < odds[n].length; k++){
            ....
            odds[n][k] = lotterOdds;
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值