Java基础
第一章:计算
定义并输入年龄
Scanner in = new Scanner(System.in);
int age = in.nextInt();
题目内容:
写一个将华氏温度转换成摄氏温度的程序,转换的公式是:
°F = (9/5)*°C + 32
其中C表示摄氏温度,F表示华氏温度。
程序的输入是一个整数,表示华氏温度。输出对应的摄氏温度,也是一个整数。
提示,为了把计算结果的浮点数转换成整数,需要使用下面的表达式:
(int)x;
其中x是要转换的那个浮点数。
package hello;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System.in);
int huashi;
huashi = in.nextInt();
System.out.println((int)((huashi-32)/(9/5.0)));
}
}
第二章:判断
判断两个浮点数是否相等不能直接用等号,因为两个浮点数相加是有误差的,需要使用如下表达式:
Math.abs(f1-f2) < 1e-6
比较三个数的大小
package hello;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int x;
int y;
int z;
System.out.println("请输入三个数字:");
x = in.nextInt();
y = in.nextInt();
z = in.nextInt();
int max=0;
if(x>y)
{
max=x;
if(x>z)
{
max=x;
}
else
{
max=z;
}
}
else
{
max=y;
if(y>z)
{
max=y;
}
else
{
max=z;
}
}
System.out.println("最大值是:"+max);
}
}
在判断语句中else是与最近的那个if匹配的。
switch-case语句:
switch(控制表达式){
case 常量:
语句
…
case 常量:
语句
…
default:
语句
…
}
- 控制表达式只能是整数型的结果
- 常量可以使常数,也可以是常数表达式
- 根据表达式的结果,寻找匹配的case,并执行case后面的语句,一直到break为止
- 如果所有的case都不匹配,那么就执行default后面的语句;如果没有default,那就什么都不做
判断语句常见错误 - 忘记大括号
- if后面加分号,不会提示错误,但代码最后结果是错误的
- “==”和“=”是不一样的
题目内容:
UTC是世界协调时,BJT是北京时间,UTC时间相当于BJT减去8。现在,你的程序要读入一个整数,表示BJT的时和分。整数的个位和十位表示分,百位和千位表示小时。如果小时小于10,则没有千位部分;如果小时是0,则没有百位部分;如果分小于10分,需要保留十位上的0。如1124表示11点24分,而905表示9点5分,36表示0点36分,7表示0点7分。
有效的输入范围是0到2359,即你的程序不可能从测试服务器读到0到2359以外的输入数据。
你的程序要输出这个时间对应的UTC时间,输出的格式和输入的相同,即输出一个整数,表示UTC的时和分。整数的个位和十位表示分,百位和千位表示小时。如果小时小于10,则没有千位部分;如果小时是0,则没有百位部分;如果分小于10分,需要保留十位上的0。
提醒:要小心跨日的换算。
输入格式:
一个整数,表示BJT的时和分。整数的个位和十位表示分,百位和千位表示小时。如果小时小于10,则没有千位部分;如果小时是0,则没有百位部分;如果小时不是0而且分小于10分,需要保留十位上的0。
输出格式:
一个整数,表示UTC的时和分。整数的个位和十位表示分,百位和千位表示小时。如果小时小于10,则没有千位部分;如果小时是0,则没有百位部分;如果小时不是0而且分小于10分,需要保留十位上的0。
输入样例:
933
输出样例:
133
package hello;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in= new Scanner(System.in);
System.out.println("请输入一个数字:");
int t = 0;
int x;
x = in.nextInt();
if(x>=800 && x<=2359 )
{
t=x-800;
}
else if(x>=0 && x<=800)
{
t=x+1600;
}
else
{
System.out.println("时间输入错误");
}
System.out.println(t);
}
}
第三章 循环
if语句可以判断条件是否满足,满足时才做相应的动作,而循环语句可以在满足条件时,不断地重复执行一些动作。
重复执行的语句(循环语句)可以多次执行其他语句,它检查一个逻辑条件是否满足,只在满足的时候执行它的循环体。
while语句是一个循环语句,它会首先判断一个条件是否满足,如果条件满足,则执行后面紧跟着的语句或语句括号,然后再次判断条件是否满足,如果条件满足则再次执行,直到条件不满足为止。后面紧跟的语句或语句括号,就是循环体。
do-while循环和while循环很像,唯一的区别是我们在循环体执行结束的时候才来判断条件。也就是说,无论如何,循环都会执行至少一遍,然后再来判断条件。与while循环相同的是,条件满足时执行循环,条件不满足时结束循环。
例题
输入一个数字判断它是几位数。
方法:352/10=35;35/10=3;3/10=0
int类型得到的都是整数。
package hello;
import java.util.Scanner;
public class Xunhuan {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("请输入一个数字:");
Scanner in =new Scanner(System.in);
int number = in.nextInt();
int count = 0;
while(number>0)
{
number = number/10;
count = count + 1;
}
System.out.println("该数字是:"+count+"位数");
}
}
上述代码用的是while循环,上这个代码是有一些问题的,当你输入0时会提示为0位数。
package hello;
import java.util.Scanner;
public class Xunhuan {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("请输入一个数字:");
Scanner in =new Scanner(System.in);
int number = in.nextInt();
int count = 0;
do
{
number = number/10;
count = count + 1;
}while(number>0);
System.out.println("该数字是:"+count+"位数");
}
}
上述代码就解决了关于0的问题,这个代码使用的是do-while循环。
- 在计数循环中,如果要模拟一个很大次数的循环,可以模拟较少的循环次数,然后做出推断。
例题:计算平均数
让用户输入一系列的正整数,最后输入-1表示输入结束,然后计算除这些数字的平均数,输出输入的数字的个数和平均数。
package hello;
import java.util.Scanner;
public class Xunhuan {
public static void main(String[] args) {
System.out.println("请输入数字");
Scanner in = new Scanner(System.in);
int number = in.nextInt();
int count = 0;
int sum = 0;
while(number != -1)
{
sum = sum + number;
count = count + 1;
number = in.nextInt();
}
if(count > 0)
{
System.out.println("输入数字的个数:"+count+"他们的平均值:"+(double)sum/count);
}
}
}
例题:猜数游戏
让计算机来想一个数,然后让用户来猜,用户每输入一个数,就告诉他是大了还是小了,直到用户猜中位置,最后还要告诉用户猜了多少次。
package hello;
import java.util.Scanner;
public class Xunhuan {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int number = (int)(Math.random()*100+1);
int a;
int count = 0;
a = in.nextInt();
while (a!=number)
{
count = count+1;
if(a>number)
{
System.out.println("你猜的数大了");
}
else
{
System.out.println("你猜的数小了");
}
System.out.println("请继续输入");
a = in.nextInt();
}
count = count + 1;
System.out.println("恭喜您猜对了,您猜了"+count+"次");
}
}
该程序用do-while稍微简单一点,遇到循环时应该先思考是用while合适还是do-while合适。
例题:整数拆分
用户随机输入一个整数,最后得到他的逆序组成的数。
package hello;
import java.util.Scanner;
public class Xunhuan {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int number;
int result = 0;
number = in.nextInt();
do
{
int digit = number % 10;
result = result*10+digit;
number = number / 10;
}while(number>0);
System.out.println(result);
}
}
第四章:for循环
例题:计算一个数的阶乘
package hello;
import java.util.Scanner;
public class Forxh {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int factor = 1;
for (int i=1; i<=n; i++)
{
factor = factor * i;
}
System.out.println(factor);
}
}
for循环和while循环是可以相互转换的。
for(初始动作;条件;每一轮的动作){ }
- for中的每一个表达是都是可以省略的
for(;条件;)==while(条件)
选择使用哪种循环的方法
- 如果有固定次数,用for
- 如果必须执行一次,用do-while
- 其他情况用while
对于break和continue的比较
- break:直接跳出循环
- continue:跳过循环这一轮剩下的语句进入下一轮
例题:写出一个九九乘法表
package hello;
import java.util.Scanner;
public class Forxh {
public static void main(String[] args) {
for(int i=1;i<=9;i++)
{
for(int j=1;j<=i;j++)
{
System.out.print(i+"*"+j+"="+(i*j));
}
System.out.println();
}
}
}
例题:如何用一元、两元、五元、十元和二十元凑出想要的金额呢?
package hello;
import java.util.Scanner;
public class Forxh {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int count = in.nextInt();
for(int one=0;one<=count;one++)
{
for(int five=0;five<=count/5;five++)
{
for(int ten=0;ten<=count/10;ten++)
{
for(int twenty=0;twenty<=count/20;twenty++)
{
if(one+five*5+ten*10+twenty*20==count)
{
System.out.println(one+"张1元,"+five+"张5元,"+ten+"张10元,"+twenty+"张20元");
}
}
}
}
}
}
}
例如用户输入33元,就会出现所有的结果。
- 假如我们想让程序出现一种结果之后就立刻停止,应该怎么做?
在这种多重循环中使用break是不可以的,它只能跳出所在的那个循环。这时我们应该在第一个循环的前面起一个名字,这个名字就成为一个标号,这代表着下面整个循环。这时候再利用break加上后面这个名字就可以跳出整个循环。(名字后面加上冒号)
Scanner in = new Scanner(System.in);
int count = in.nextInt();
out:
for(int one=0;one<=count;one++)
{
for(int five=0;five<=count/5;five++)
{
for(int ten=0;ten<=count/10;ten++)
{
for(int twenty=0;twenty<=count/20;twenty++)
{
if(one+five*5+ten*10+twenty*20==count)
{
System.out.println(one+"张1元,"+five+"张5元,"+ten+"张10元,"+twenty+"张20元");
break out;
}
}
}
}
}
}
}
这时程序运行的结果就是这样的。
逻辑类型
- 关系运算的结果是一个逻辑值,true或false。这个值可以保存在一个对应的逻辑类型变量中,这样的变量类型是Boolean。
- boolean flag = true;
- boolean done = false;
这时候就出现了逻辑运算
- 逻辑非 ;!; !a(如果a是true,结果就是false)
- 逻辑与 ;&& ;a&&b ;这就是a且b
- 逻辑或 ;|| ;a||b ; 这就是a或b
String类的substring方法可以从一个较大的字符串提取出一个子串。例如:
String greeting = "Hello";
String s = greeting.substring(0,3);
以上语句就创建了一个由字符“Hel”组成的字符串。
例题:计算1+1/2+1/3+…+1/n(最后保留两位小数)
package hello;
import java.util.Scanner;
public class Forxh {
public static void main(String[] args) {
Scanner in =new Scanner(System.in);
int n= in.nextInt();
double sum = 0.0;
for(int i=1;i<=n;i++)
{
sum = sum+1.0/i;
}
System.out.printf("%.2f",sum);
}
}
最后的输出格式是保留两位小数就用:printf。
例题:求两个数的最大公约数。
法一:
Scanner in = new Scanner(System.in);
int a = in.nextInt();
int b = in.nextInt();
int gcd = 1;
for(int i=2; i<=a&&i<=b; i++)
{
if(a%i==0&&b%i==0)
{
gcd=i;
}
}
System.out.println(a+"和"+b+"的最大公约数是:"+gcd);
}
}
法二:辗转相除法
- 如果b=0,计算结束,a就是最大公约数;
- 否则,计算a除以b的余数,让a等于b,而b等于那个余数;
- 回到第一步。
Scanner in = new Scanner(System.in);
int a = in.nextInt();
int b = in.nextInt();
int oa=a;
int ob=b;
while(b!=0)
{
int r=a%b;
a=b;
b=r;
}
System.out.println(oa+"和"+ob+"的最大公约数是:"+a);
}
}
第五章:数组
数据可以存放在变量里,每一个变量有一个名字,有一个类型,还有它的生存空间。如果我们需要保存一些相同类型、相似含义、相同生存空间的数据,我们可以用数组来保存这些数据,而不是用很多个独立的变量。数组是长度固定的数据结构,用来存放指定的类型的数据。一个数组里可以有很多个数据,所有的数据的类型都是相同的
int[] numbers = new int[100];
for(i=0;i<n;i++)
numbers[i] = x;
这是定义了一个名为numbers的数组,并且是int类型的,并且创建了一个新的放一百个int类型的数组。讲x的值全部放到数组的每一个位置上去。
特点
- 其中所有的元素具有相同的数据类型
- 一旦创建,不能够改变大小
定义数组变量
- <类型>[] <名字> = new <类型>[元素个数];
- int[] grades = new int[100];
- double[] averages = new double[20];
- 元素个数必须是整数
- 元素个数必须给出
- 元素个数可以使变量
- 假如要遍历名为grade的数组,最好应该使用
for(i=0;i<grade.length;i++)
直接初始化数组
- new创建的数组会得到默认的0值
- int[] scores = {87,98,86,95,84,80,91,85};
- 不需要给出数组的大小,编译器替你数,想要知道数组大小,可以使用length。System.out.println(scores.length);
数组变量
- 数组变量是数组的管理者而非数组本身
- 数组必须创建出来然后交给数组变量来管理
- 数组变量之间的赋值是管理权限的赋予
- 数组变量之间的比较是判断是否管理同一个数组
看如下代码的输出结果
package hello;
public class Shuzu {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] a = {1,2,3,4,5,6};
int[] b = a;
for(int i=0; i<b.length; i++)
{
b[i]++;
}
for(int i=0; i<a.length; i++)
{
System.out.print(a[i]);
}
}
}
输出结果如上所示,虽然只是将变量b全部增加,但是现在是变量a和b共同管理数组。
Scanner in = new Scanner(System.in);
int[] a = {1,2,3,4,5};
int[] b = a;
System.out.println(a==b);
上述代码得到的结果是true。
Scanner in = new Scanner(System.in);
int[] a = {1,2,3,4,5};
int[] b = {1,2,3,4,5};
System.out.println(a==b);
上述代码得到的结果就是false。
复制数组
因此要想将一个数组的值全部赋值给另一个数组,必须遍历原数组将每一个元素逐一拷贝给目的数组
package hello;
import java.util.Scanner;
public class Shuzu {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int[] a = {1,2,3,4,5};
int[] b = new int[a.length];
for(int i=0; i<b.length; i++)
{
b[i] = a[i];
System.out.print(b[i]);
}
}
}
例题
写一个程序,输入数量不确定的[0,9]范围内的整数,统计每一种数字出现的次数,输入-1表示结果。
package hello;
import java.util.Scanner;
public class Shuzu {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int x;
int[] a = new int[10];
x= in.nextInt();
while(x != -1)
{
if(x>=0&&x<=9)
{
a[x]=a[x]+1;
x = in.nextInt();
}
}
for(int i=0; i<a.length; i++)
{
System.out.println(i+":"+a[i]);
}
}
}
数组的遍历
for-each
for(<类型><变量>:<数组>){
… }
例如:
for(int i : a){
System.out.println(i);
}
这种遍历只是把数组里面的值遍历一遍,并不能利用它修改数组里面的值。
数组的拷贝
希望将一个数组的所有制值拷贝到一个新的数组中去,就要使用Arrays类中的copyof方法:
int[] a = new int[100];
int[] b = Arrays.copyOf(a,a.length);
x的平方根:Math.sqrt(x)。
使用Arrays类中的sort方法可以进行快速排序:Arrays.sort(a)
使用Arrays类中的toString方法可以打印数组中的所有值:Arrays.toString(a)
访问二维数组a中的所有元素
for(int[] row : a){
for(int value : row)
do somrthing with value
}
快速打印二维数组的数据元素列表
System.out.println(Arrays.deepToString(a));
第六章:字符类型
- 单个的字符是一种特殊的类型:char
- 用单引号表示的字符字面量:‘a’,‘1’
- java使用Unicode来表示字符,可以表达包括汉子在内的多种文字
例题:将大写的A转换成小写的a
package hello;
import java.util.Scanner;
public class Shiyongdx {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System.in);
char c = 'A';
char d = (char)(c + 'a'-'A');
System.out.println(c);
}
}
逃逸字符
字符 | 意义 |
\b | 回退一格 |
\t | 到下一个表格位 |
\n | 换行 |
\r | 回车 |
‘’ | 双引号 |
’ | 单引号 |
\ | 反斜杠本身 |
包裹类型
- 每一种基础类型都有对应的包裹类型
基础类型 | 包裹类型 |
boolean | Boolean |
char | Character |
int | Integer |
double | Double |
byte | Byte |
short | Short |
long | Long |
float | Float |
包裹类型的用处(举一个简单的例子):
- 获得该类型的最大最小值
- Integer.MIN_VALUE
- Integer.MAX_VALUE
.运算符
- 当需要让一个类或对象做事情的时候,用.运算符
- 点的左边是一个对象或者是一个类,点的右边是这个对象或者这个类能够提供给我们的一些服务、数据或者它能够做的动作。
例如:
Math
用来提供一些基本的数学操作 - abs:用来算绝对值
- pow:用来算幂次
- random:能够给一个随机数
- round:用来做四舍五入
package hello;
import java.util.Scanner;
public class Shiyongdx {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println(Math.abs(-12));
System.out.println(Math.round(10.654));
System.out.println(Math.random()*100);
System.out.println(Math.pow(2, 3));
}
}
“这些操作就是所谓的函数”
字符串变量
- String s;
- String是一个类,String的变量是对象的管理者而非所有者,就像数组变量是数组的管理者而非所有者一样
new = 创建
String s = new String(“a string”);
创建了一个String的对象
用“a string”初始化这个对象
创建管理这个对象的变量s
让s管理这个对象
初始化字符串变量
- String s = “hello”;
- 编译器帮你创建一个String类的对象交给s来管理
字符串连接 - 用加号(+)可以连接两个字符串
- “hello”+“world”->“helloworld”
- 当这个+的一边是字符串而另一边不是时,会将另一边表达为字符串然后做连接
输入字符串
- in.next();读入一个单词,单词的标志是空格
- 空格包括空格、tab和换行
- in.nextLine();读入一整行
package hello;
import java.util.Scanner;
public class Shiyongdx {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String a;
a = in.next();
System.out.println(a);
}
}
package hello;
import java.util.Scanner;
public class Shiyongdx {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String a;
a = in.nextLine();
System.out.println(a);
}
}
对象变量的赋值
字符串的赋值和数组一样是管理者不是拥有者。
String a = “hello”;
String b = a;
这个意思就是创建一个字符串b,和a一样管理hello。
- 在使用“==”时,是在比较他们是否是在管理同一个东西
- 使用.equals时,是在比较他们的内容是否一样
字符串操作
- 字符串是对象,对它的所有操作都是通过"."这个运算符来进行的
- 字符串.操作
- 它表示对.左边的这个字符串做右边的那个操作
- 这里的字符串可以是变量也可以是常量
Strings大小的比较
两个字符串可以比较大小:
s1.compareTo(s2)
如果s1比s2小,那么结果是负的;如果s1和s2相等,那么结果是0;如果s1比s2大,那么结果是正的
compareToIgnoreCase可以不区分大小写地来比较大小
用length()函数来获得String的长度
访问String里的字符
- s.charAt(index)
- 返回在index上的单个字符
- index的范围是0到length()-1
- 第一字符的index是0,和数组一样
- 但是不能用for-each循环来遍历字符串
- 可以用s.substring(n)得到从n号位置到末尾的全部内容
- 可以用s.substring(b,e)得到从b号位置到e号位置之前的内容
寻找字符
- s.indexOf(c):得到c字符所在的位置,-1表示不存在
- s.indexOf(c,n):从n号位置开始寻找c字符
- s.indexOf(t):找到字符串t所在的位置
- 从右边开始找:a.lastIndexOf©;a.lastIndexOf(c,n);
a.lastIndexOf(t);
以上所有操作对字符串都是不可改变的,输出的字符串还会是以前的字符串。
第七章:函数
什么是函数
- 函数是一块代码,接收零个或多个参数,做一件事情,并返回零个或一个值
- 可以先想像成数学中的函数
- y=f(x)
函数的定义
调用函数
- 函数名(参数值)
- ()起到了表示函数调用的重要作用
- 即使没有参数也需要()
- 如果有参数,则需要给出正确的数量和顺序
- 这些值会被按照顺序依次用来初始化函数中的参数
函数返回 - 函数知道每一次是哪里调用它,函数结束的时候会返回到正确的地方
从函数中返回值 - return停止函数的执行,并送回一个值
- return;
- return 表达式;
没有返回值的函数 - void 函数名(参数表)
- 不能使用带值的return,可以没有return
- 调用的时候不能做返回值的赋值
调用函数 - 如果函数有参数,调用函数时必须传递给它数量、类型正确的值
- 可以传递给函数的值是表达式的结果,这包括:字面量、变量、函数的返回值、计算的结果
- Java语言在调用函数时,永远只能传值给函数 。