111 - Lecture3

String and Control Flow

一:Char and String

1.primitive types vs reference types

a data type is a set of values and a set of operations defined on those values
数据类型是一组值和在这些值上定义的操作的集合。
在Java中,数据可以分为两大类:原始数据类型和引用类型。

"We will see later that when we declare(声明) a reference type in a variable, we do not store the data itself, but the reference(引用)/address/pointer(指针) of the data. In Part 1 of today's lecture, we will learn more about char and consider String as a reference type, and also learn about string processing(字符串处理)."

(1)原始数据类型(Primitive Data Types)

Java内置了8种原始数据类型,这些类型直接存储数据的值,而不是存储数据的引用或地址。

  • byte:用于存储非常小的整数,通常是-128到127之间的值。
  • short:用于存储较小的整数,通常是-32,768到32,767之间的值。
  • int:用于存储整数,通常是-2,147,483,648到2,147,483,647之间的值。
  • long:用于存储大整数,可以存储比int更大的数值,但需要加上Ll后缀(推荐大写L以避免与数字1混淆)。
  • float:用于存储单精度浮点数,即带小数点的数,需要加上Ff后缀。
  • double:用于存储双精度浮点数,精度比float高,是Java中默认的浮点类型。
  • boolean:用于存储真值或假值,只有两个可能的值:truefalse
  • char:用于存储单个字符,如字母或数字。
(2)引用类型(Reference Types)

引用类型不直接存储数据值,而是存储数据的引用(或内存地址),通过这个引用可以找到数据在内存中的实际位置。常见的引用类型包括:

  • 数组(arrays):用于存储固定大小的同类型元素集合。
  • String:用于存储文本数据,虽然看起来像是基本类型,但实际上它是引用类型,因为String对象存储在堆内存中,而变量中存储的是对String对象的引用。

2. Char and string operations

(1)Char

A char is an (字母)alphabetic ,(数字)numeric or symbol, enclosed in single quote’'.

char firstLetter = 'A";
char five = '5';
char newLine = '\n';

A chart is a Unicode character(字符):

  • 它实际上是一个整数,范围在0到65,535之间(包括0和65,535)
  • 它可以像整数一样进行比较,使用==、!=、<、<=、>=、>等操作符

示例代码:

char firstLetter = &apos;A&apos;;
boolean b = firstLetter == 65;

这里,firstLetter变量被赋值为字符'A',而'A'在Unicode(以及ASCII,因为ASCII是Unicode的一个子集)中的整数值是65。因此,firstLetter == 65这个比较操作的结果是true,然后这个比较的结果(true)被赋值给布尔变量b
Char Testing

use Character wrapper class static method(静态方法)来测试字符:

  • boolean isLetter(char c)c 是否是字母?
  • boolean isDigit(char c)c 是否是数字?
  • boolean isWhitespace(char c)c 是否是空白字符?
  • boolean isUpperCase(char c)c 是否是大写字母?
  • boolean isLowerCase(char c)c 是否是小写字母?
    测试字符通常涉及验证字符的某些属性或行为是否符合预期。在Java中,你可以使用Character类提供的方法来测试字符的各种属性,比如它是否是字母、数字、大写、小写等。此外,你还可以编写自定义的测试逻辑来验证字符的特定行为。

以下是一些具体应用和测试字符的方法:

1. 使用Character类的方法测试字符属性

Character类提供了许多静态方法来测试字符的各种属性。例如:

  • isLetter(char ch):检查指定的字符是否为字母。
  • isDigit(char ch):检查指定的字符是否为数字。
  • isUpperCase(char ch):检查指定的字符是否为大写字母。
  • isLowerCase(char ch):检查指定的字符是否为小写字母。
  • isWhitespace(char ch):检查指定的字符是否为空白字符。

示例代码

public class CharacterTest {
    public static void main(String[] args) {
        char ch1 =A;
        char ch2 =5;
        char ch3 =&;

        System.out.println(Character.isLetter(ch1)); // 输出: true
        System.out.println(Character.isDigit(ch2)); // 输出: true
        System.out.println(Character.isWhitespace(ch3)); // 输出: true

        System.out.println(Character.isUpperCase(ch1)); // 输出: true
        System.out.println(Character.isLowerCase(ch1)); // 输出: false

        char ch4 = ‘a’;
        System.out.println(Character.isLowerCase(ch4)); // 输出: true
    }
}

使用Character类的静态方法来改变字符:

  • char toUpperCase(char c) 将字符转换为大写
  • char toLowerCase(char c) 将字符转换为小写
  • String toString(char c) 将字符转换为一个包含该字符的String对象
    示例:
char firstLetter = 'A'; 
char smallA = 'a'; 

char upperSmallA = Character.toUpperCase(smallA); 
char lowerFirstLetter = Character.toLowerCase(firstLetter); 
// 如果你想要将字符转换为String对象
String stringFirstLetter = Character.toString(firstLetter); 

注意:在原始内容中,Character.toUpperCase(smallA);Character.toLowerCase(firstLetter); 的调用没有接收返回值,这在实际编程中是不正确的,因为这两个方法都会返回一个新的字符值,而不是修改原始变量。因此添加变量来接收这些方法的返回值。

(1) String

字符串是a sequence of characters(chars),比如 "Halloween"。

String cosmo = "Halloween";

同样地,你也可以创建一个句子(如 "A corpse is talking.")的字符串:

String sentence = "A corpse is talking.";

总结来说,通过在**双引号(double quotes)**中写入字符序列,你可以创建 Java 字符串。这些字符可以是单个单词、短语、句子。

String Class and Object

String 类和对象

● String 是 Java 中的一个类或数据类型,其名称首字母大写(capitalized)。

● 通过构造一个新对象来创建一个 String 对象(object)。例如:

String cosmo;
cosmo = new String("Halloween");

这里,cosmo 是一个 String 类型的对象名(object name),我们通过 new String("Halloween") 构造了一个新的 String 对象,并将其赋值给 cosmo

○ 使用 new 关键字来调用构造器(call a constructor)。

○ 使用类名或数据类型名(如 String)来指定要创建的对象类型。

注意:在 Java 中,通常不需要使用 new String() 来创建字符串对象,因为字符串常量(如 “Halloween”)在 Java 中是自动作为 String 对象处理的。直接使用 String cosmo = ‘Halloween“;` 更为常见和高效。

Reference Variable Declaration引用变量声明

● 当我们声明任何引用类型的变量,比如 String 时,Java 会分配一个 64 位的盒子(在 64 位 JVM 中即8字节),不论对象的类型是什么。
○ 这个 64 位的盒子并不包含字符串本身的数据,而是包含字符串在堆内存中的地址
解释:
在 Java 中,当你声明一个引用类型的变量(如 String)时,你实际上是在创建一个引用,这个引用可以指向一个对象。但是,这个引用本身(在 Java 中通常是一个指针或地址)存储在栈内存中,并且它的大小是固定的(在 64 位 JVM 中通常是 64 位,即 8 字节),与它所引用的对象的大小无关
当你执行 cosmo = new String(“Halloween”); 时,Java 会在堆内存中创建一个新的 String 对象,该对象包含字符串 “Halloween” 的数据。然后,它将这个新对象的地址存储在之前声明的 cosmo 引用变量中。因此,cosmo 并不直接包含字符串数据,而是包含了一个指向堆内存中 String 对象的引用(或地址)。

Concatenation 字符串连接
  • 使用加号 + 操作符(plus operator)可以将字符串连接在一起,形成一个新的、更长的字符串。
String cosmo = "hallo" + "ween"; 
String bang = "bang";
String exclamation = "!!";
String makima = bang + exclamation; 
  • 第一个字符串的字符与第二个字符串的字符按顺序组合在一起。

  • 这种操作适用于字符串(strings)和字符(chars)之间的连接,但请注意,当与字符连接时,字符会被自动转换成字符串

Length and Method Call

长度和方法调用

String cosmo = "Halloween";
int len = cosmo.length();
System.out.println(len);

● 字符串的长度是指它里面包含的字符数量。

● 在字符串上调用名为 length() 的方法会返回它的长度。

● 要调用一个方法(calla a method)/执行一个操作(apply an operation):

○ 使用对象名来指定哪个对象。

○ 使用点号dot operator(.)后跟方法名来调用方法。

Empty String and Length

Java程序的输出是:

○ 0

public static void main(String[] args) {
    String s = "";
    int len = s.length();
    System.out.println(len);
}
Index Number

索引编号

● 字符串中的字符通过索引编号0, 1, 2, …来识别
○ 最左边的字符位于索引0
○ 最后一个字符位于索引length-1

示例:Halloween
(在这个例子中,“H”位于索引0,“n”位于索引8,因为字符串长度为9,最后一个字符的索引是8,即length-1)

Substring

子字符串

substring 方法通过索引编号来picks out字符串的一部分 to identify the desired part

substring(int start) return一个新字符串,该字符串由从索引 start 开始的字符组成,并一直持续到原字符串的末尾

示例:

H a l l o w e e n
0 1 2 3 4 5 6 7 8
String cosmo = "Halloween";
String ss1 = cosmo.substring(1); 

这将返回 alloween.
Another version substring(int start, int end) returns a new string of the
chars starting at index start up to but not including the end index
○ notice the length of the resulting substring can be computed by
subtracting end - start

String cosmo = "Halloween";
String ss1 = cosmo.substring(2, 5);
String ss2 = cosmo.substring(8, 9);
String Index Error

字符串索引错误

● 在向substring()方法传递索引号时,常常会出现错误
It is common to make mistakes with the index numbers fed into substring()
○ 对于substring()方法来说,有效的索引号是0, 1, 2, …, str.length() - 1,因此我们需要小心不要传递超出这个范围的数字
not to pass in numbers outside that range
■ 最后一个数字,即str.length(),是不包括在内的,因为字符串的索引是从0开始的,所以最后一个字符的索引是字符串长度减一(str.length() - 1)

String Equality

字符串相等性
Use the equals() method to check if 2 strings are the same
○ equals() method is case-sensitive区分大小写
● Recall the == operator used to compare primitive types int, double, char
○ it does not work reliably with object types such as String
它对于对象类型如 String 不可靠

String cosmo = "Halloween";
String makima = "Bang";
System.out.println(cosmo.equals("Halloween"));
// correct use .equals() to compare Strings
System.out.println(cosmo == "Halloween");
// do not use == with Strings
System.out.println(cosmo.equals(makima));//return false

String Equality Not Case Sensitive

字符串相等性不区分大小写
● 有一种字符串相等性检查的变体(variant)叫做equalsIgnoreCase()
它在比较两个字符串时会忽略大小写(uppercase/lowercase)差异。

String Test

boolean isEmpty()
is string an empty string?
boolean contains(String substring)
does string contain substring?
boolean startsWith(String prefix)
does string start with prefix?
boolean endsWith(String postfix)
does string end with postfix?
当然,我可以为上面提到的字符串方法提供具体的例子。以下是每个方法的示例代码和输出:

isEmpty() 方法

String emptyString = "";

System.out.println(emptyString.isEmpty()); // 输出: true

contains(String substring) 方法

String text = "Hello, world!";

System.out.println(text.contains("Hello"); // 输出: true


startsWith(String prefix) 方法

String greeting = "Hello, everyone!";


System.out.println(greeting.startsWith("hello"); // 注意大小写敏感,输出: false

endsWith(String postfix) 方法

String sentence = "This is a test sentence.";


System.out.println(sentence.endsWith("sentence&quot"); // 注意结尾的句号,输出: false

这些方法都是大小写敏感的,这意味着在比较时,字符的大小写必须完全匹配。

Uppercase and Lowercase

We can change string:
○ String toUpperCase()------ to uppercase
○ String toLowerCase() ------to lowercase

String cosmo = "Halloween";
cosmo.toUpperCase();
cosmo.toLowerCase();
CharAt

char charAt(int i) returns the character at index i
○ for example, print the first and the last character of a string:

String cosmo = "Halloween";
char c = cosmo.charAt(0);
System.out.println(c);
System.out.println(cosmo.charAt(8));
index Of

str.indexOf(String target) 方法从左到右在 str 中搜索字符串 target
○ 如果找到目标字符串,它会返回目标字符串首次出现的索引编号,如果没有找到,则返回 -1
○ case-sensitive
○ 你可以使用这个方法代替 for-loop to iterate over(循环来遍历)并查找字符串

String cosmo = "Halloween";
int a = cosmo.indexOf("allo");//1
int b = cosmo.indexOf("e");//6
int c = cosmo.indexOf("allO");
lastIndexOf

There is also lastIndexOf(String target) method that searches for the
target from right to left

String cosmo = "Halloween";
int d = cosmo.lastIndexOf("e");
indexOf, lastIndexOf with fromIndex

存在indexOf和lastIndexOf的版本,它们take a fromIndex参数to specify where the search should begin.
○ int indexOf(String target, int fromIndex):从左到右,从给定的fromIndex开始搜索。
○ int lastIndexOf(String target, int fromIndex):从右到左,从给定的fromIndex开始搜索。
○ fromIndex实际上不需要是有效(valid)的。
■ 如果它是负数,那么搜索将从字符串的开始处进行。
■ 如果它大于字符串的长度,那么将返回-1。

Example

Write a program to capitalize the text in parenthesis

String str = "Hal(low)een";
int left = str.indexOf("(");
int right = str.indexOf(")");
String sub = str.substring(left + 1, right);
sub = sub.toUpperCase();
String result = str.substring(0, left + 1) + sub +
str.substring(right);// return Hal(LOW)een

二.Conditionals

Boolean type only has two values: true or false
Boolean Operators
● Operators defined for boolean:
○ and: a && b is true if both a and b are true, and false otherwise
○ or: a || b is true if either a or b is true (or both are true), and false
otherwise
○ not: !a is true if a is false, and false otherwise
Comparison Operators
比较运算符,它接受一种类型的运算数operands(例如,int 或 double)并产生一个布尔类型的结果。

operatormeaning
==equal
!=not equal
<less than
<=less than or equal
>greater than
>=greater than equal

do not confuse equality == with assignment operator =(赋值运算符)

equivalent of a calculator计算机
straight-line control flow 直线控制流程

1. if, if-else statements

if statement

if block (statement inside curly brackets花括号)
evaluate the boolean expression
○ if true, execute if-block
○ if false, do nothing, go to next statement
Example
compute the absolute value of user integer input

public class AbsoluteIntValue {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String input; 
int num; 
input = scanner.nextLine();
num = Integer.parseInt(input);
if (num < 0) {
num = -num;
}
System.out.println(num);
}
}
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int num = scanner.nextInt();
        if(num < 0){
        num = -num;
        }
        System.out.println(num);
    }
}

scanner.nextLine()会读取整行文本,包括空格和换行符,直到遇到换行符为止。这意味着如果你输入的是"123 456"(两个数字之间有一个空格),整个字符串"123 456"作为结果返回。然后你需要使用Integer.parseInt()来解析这个字符串并获取整数。

scanner.nextInt()只会读取下一个整数,忽略任何空格或换行符。所以如果你输入的是"123 456",只会读取并返回第一个整数123,第二个整数456将被忽略。

因此,选择哪种方法取决于你的需求。如果你需要处理包含空格或其他分隔符的输入,那么使用scanner.nextLine()可能更合适。

其中通常使用"parse"前缀的方法来将字符串解析为其他数据类型,例如Integer.parselnt()用于将字符串解析为整数,
Double.parseDouble()用于将字符串解析为双精度浮点数,Boolean.parseBoolean()用于将字符串解析为布尔值。
相反,通常使用"to"前缀的方法将其他数据类型转换为字符串,例如
Integer.toString()用于将整数转换为字符串
Double.toString()用于将双精度浮点数转换为字符串,
Boolean.toString()用于将布尔值转换为字符串。

if - else statement

example
compute the maximum of two values of user integer
input

public class MaximumIntValue {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String input; 
int x, y; 
input = scanner.nextLine();
x = Integer.parseInt(input);
input = scanner.nextLine();
y = Integer.parseInt(input);
int max;
if (x > y) {
max = x;
}
else {
max = y;
}
System.out.println(max);
}
}

Bugs

Which of the following will lead to a compile error?
Assume a, b, c are already initialized.
 if a > b { c = 5; }缺少括号包围条件表达式
 if (a > b) ( c = 5; )False括号改成花括号
 if (a > b) then c = 5;False
 if (a > b) c = 5 else c = 2;Ture 如果if和else语句控制的是单独的语句而不是语句块,则通常不需要花括号

whether a user integer input is “Negative”, “Zero”, or “Positive”

public class NegZeroPos {
public static void main(String[] args) {
// code to receive user integer input to num
if (num < 0) {
System.out.println("Negative");
}
else if (num == 0) {
System.out.println("Zero");
}
else {
System.out.println("Positive");
}
}
}

Multiple ifs and logical operaters
print the Degree Class given user’s Percentage Score according to
British marking creteria

public class BritishMarkingCriteria {
public static void main(String[] args) {
// code to receive user double input to score
if (score >= 70)
System.out.println("First Class");
if (score >= 60 && score < 70)
System.out.println("Upper Second Class");
if (score >= 50 && score < 60)
System.out.println("Lower Second Class");
if (score >= 40 && score < 50)
System.out.println("Third Class");
if (score < 40)
System.out.println("Fail");
}
}

2.Nested if-elses

……
if (score < 40)
	System.out.println("Fail");
else {
	if (score < 50)
		System.out.println("Third Class");
	else {
		if (score < 60)
			System.out.println("Lower Second Class");
		else {
			if (score < 70)
				System.out.println("Upper Second Class");
			else
				System.out.println("First Class");
}
}
}

If and String Index Error
为了避免边界(bounds)错误,添加一个if语句来检查字符串的长度
○ 不要假设字符串足够长,(calling)调用substring()之前先检查length()

if (str.length() >= 5) {
prefix = str.substring(0, 5);
}
else {
// do something else when length is < 5
}

Conditional Operator

条件运算符 ? : 是一个三元运算符ternary operator(三个操作数operands)
○ 用于在表达式expression中嵌入条件embed a conditional
○ 三个操作数由 ? 和 : 符号分隔
○ 如果第一个操作数(布尔表达式)为真,则结果具有第二个表达式的值;否则,它具有第三个表达式的值

int min = (x < y) ? x : y;

三.Loops

count down from 10 to 1

public class CountDown {
public static void main(String[] args) {
System.out.println("10");
System.out.println("9");
...
System.out.println("1");
}
}

many computations are inherently(本质上) repetitive

1. while loops

while loop executes statements repeatedly when certain conditions are met

Example
print count down from 10 to 1 using while loops

public class CountDown {
public static void main(String[] args) {
int count = 10;
while (count >= 1) {
System.out.println(count);
count = count - 1;
		}
	}
}

2. infinite loops

Program never stops looping
○ forget to update stopping condition
○ or, stopping condition is never met

public class Halloween {
public static void main(String[] args) {
while (true) {
System.out.println("Halloween!");
}
}
}

Example

Write a Java program that takes integer input n and prints n first( 前n个)
powers of two(2的幂次方) starting from 2^0 = 1

import java.util.Scanner;


public class HailStone {
 public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int i = 0;
       while(i<=n-1) {
           int m = (int)Math.pow(2,i);
           System.out.println(m);
           i++;
       }
    }
}
public class PowersOfTwo {
public static void main(String[] args) {
// code to receive user integer input to n
int i = 1, val = 1;
while (i <= n) {
System.out.println(val);
val = val * 2;
i = i + 1;
}
}
}

while loops is especially useful when you don’t exactly know
how many times needed to loop over

3. logical error-off-by-one-bug

差一错误:
如果我们用 < 代替 <=,我们就会错过打印一个2的幂次。这是计算机编程中一个常见的逻辑错误。

4. for loops

for循环使用三个语句在其体内重复执行语句:
○ 初始化一个索引变量(例如 i, j, k)为某个值
initialize an index variable (e.g. i, j, k) to some value
○ 测试一个涉及索引的继续条件,如果它仍然为真,则继续循环
test a continuation condition involving the index, continue looping if it’s still true
○ 使用最后一个语句来更新索引变量

For Loop and String

Use for loop to iterate over(遍历) the characters of a string
○ for example, loop to hit(遍历) each index number(索引号) once:

for (int i = 0; i < str.length(); i++) {
// do something to str at index i
}
For Loop and charAt

char charAt(int i) returns the character at index i
○ for example, print each character of str once:

for (int i = 0; i < str.length(); i++) {
// do something to str at index i
System.out.println(str.charAt(i));
}
Nested For Loops

we use three index variables that depend on the other,
to print a pyramid pattern:

for (int i = 1; i <= 5; i++) { 
for (int j = i; j < 5; j++) { 
System.out.print(" ");
}
for (int k = 1; k <= (2 * i - 1); k++) { 
System.out.print("*");
}
System.out.println();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值