HelloWorld

img

1
2
3
4
5
public class HelloWorld{
public static void main(String[] args) {
System.out.println("Hello World");
}
}

需要保存为HelloWorld.java。(大小写敏感)HelloWorld作为标识符,由数字字母下划线美元符组成,不以数字开头,不能是关键字,区分大小写,运用驼峰命名法。

Java 程序由public static void main(String[] args)方法开始执行。

img

描述一类对象的行为和状态,对象是类的一个实例。

方法就是行为,一个类可以有很多方法。

每个对象都有实例变量,能决定对象的状态。

注释

1
2
3
4
5
6
7
8
9
10
11
public class HelloWorld {
/* 这是第一个Java程序
* 它将输出 Hello World
* 这是一个多行注释的示例
*/
public static void main(String[] args){
// 这是单行注释的示例
/* 这个也是单行注释的示例 */
System.out.println("Hello World");
}
}

关键字

static:表示该方法是静态类方法,可以直接使用类名来调用,无需创建对象实例。

对于一般的方法,必须使用 publicprivateprotected这些修饰符中的一个来标识该方法可以被哪些代码访问。同时,对于实例方法,不需要加 static 修饰符,因为这些方法只有在对象实例化之后才可以调用。

但是对于类方法(即使用 static 关键字修饰的方法),它们不依赖于实例对象的状态,可以通过类名直接调用,所以在方法的定义时就需要使用 static 修饰符了。

public void 是方法的返回类型声明,public 表示该方法的访问修饰符是公开的,void 表示该方法不会返回任何值。如果一个方法需要返回值,则需要在 void 前面指定对应的返回类型,举个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class Main {
public static void way1() {
System.out.println(6);
}

static class WAY2 {
public void way2() {
System.out.println(6);
}
}

public static int way3(int a, int b) {
return a + b;
}

static class WAY4 {
public int way4(int a, int b) {
return a + b;
}
}

public static void main(String[] args) {
way1();
WAY2 way = new WAY2();
way.way2();
System.out.println(way3(3, 3));
WAY4 wayy = new WAY4();
System.out.println(wayy.way4(3, 3));
}
}
访问控制
protected 受保护的
public 公共的
default 默认
private 私有的
类、方法和变量修饰符
class
extends 扩充,继承
final 最终值,不可改变的
implements 实现(接口)
interface 接口
native 本地,原生方法(非 Java 实现)
new 新,创建
static 静态
strictfp 严格,精准
synchronized 线程,同步
transient 短暂
volatile 易失
abstract 声明抽象
程序控制语句
case 定义一个值以供 switch 选择
continue 继续
do 运行
else 否则
for 循环
if 如果
instanceof 实例
return 返回
switch 根据值选择执行
while 循环
break 跳出循环
错误处理
catch 捕捉异常
finally 有没有异常都执行
throw 抛出一个异常对象
throws 声明一个异常可能被抛出
try 捕获异常
assert 断言表达式是否为真
包相关
package
import 引入
基本类型
byte 字节型
char 字符型
double 双精度浮点
float 单精度浮点
int 整型
long 长整型
short 短整型
boolean 布尔型
变量引用
this 本类
void 无返回值
super 父类,超类
保留关键字
const 是关键字,但不能使用
goto 是关键字,但不能使用

super和this

在Java中,super和this都是关键字,可以用于引用当前实例或父类实例的成员变量、方法或构造函数

this关键字用于引用当前类实例的成员变量或方法。例如:

1
2
3
4
5
6
7
8
9
10
11
public class Person {
private String name;

public Person(String name) {
this.name = name;
}

public String getName() {
return this.name;
}
}

在上面的代码中,构造函数使用this关键字来引用当前实例的name变量,而getName()方法也使用this关键字来返回当前实例的名字

super关键字用于引用父类实例的成员变量或方法,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Employee extends Person {
private String jobTitle;

public Employee(String name, String jobTitle) {
super(name);
this.jobTitle = jobTitle;
}

public String getJobTitle() {
return this.jobTitle;
}

public String getName() {
return super.getName();
}
}

在上面的代码中,子类Employee中的构造函数使用super关键字来调用父类Person的构造函数,以初始化Person类中的name变量。在Employee类中,getName()方法通过super关键字来调用父类Person中的getName()方法获取名字

instanceof

instanceof关键字用于判断一个对象是否是特定类或其子类的实例

1
2
3
4
Object obj = new String("hello");
if (obj instanceof String) {
System.out.println("obj is a String instance");
}

在这个例子中,我们声明了一个Object类型的变量obj,并将其初始化为一个String对象。然后我们使用instanceof操作符来判断obj是否是String类的实例。由于obj确实是String类型的实例,所以obj instanceof String条件为true,程序会输出”obj is a String instance”。

源文件声明规则

一个源文件只能有一个public类,可以有多个非public类。

源文件的名称应该和 public 类的类名保持一致。

类和对象

创建一个简单的类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Dog {
String breed;
int size;
String colour;
int age;

void eat() {
}

void run() {
}

void sleep(){
}

void name(){
}
}

一个类可以拥有多个方法,在上面的例子中:eat()、run()、sleep() 和 name() 都是 Dog 类的方法。

构造方法

每个类都有构造方法。如果没有主动为类定义构造方法,Java 将会为该类提供一个无参数的构造方法。

1
2
3
4
5
6
7
8
public class Puppy{
public Puppy(){
}

public Puppy(String name){
// 这是一个构造方法,有一个参数name
}
}

创建对象

在java中使用 new 关键字来创建新的对象。

创建对象步骤:声明(对象名称和对象类型)+实例化(new)+初始化。

1
2
3
4
5
6
7
8
9
public class Puppy{
public Puppy(String name){
System.out.println("小狗的名字是 : " + name );
}
public static void main(String[] args){
// 下面的语句将创建一个Puppy对象
Puppy myPuppy = new Puppy( "tommy" );
}
}

访问变量和方法

1
2
3
Object referenceVariable = new Constructor(); 
referenceVariable.variableName;
referenceVariable.methodName();

在第一行中,使用new关键字创建了一个类的实例,并将其赋值给一个引用变量referenceVariable。referenceVariable可以用于调用该实例中的方法或访问其成员变量。

在第二行中,variableName表示要访问的成员变量的名称。可以使用referenceVariable.variableName来访问该变量。

在第三行中,methodName表示要调用的方法的名称。可以使用referenceVariable.methodName()来调用该方法,如果方法有参数,则可以在括号中传递参数。

成员方法是定义在类中的方法,可以被类的对象调用。成员方法可以访问和修改类的域,也可以定义局部变量。Java中的方法需要指定返回类型,如果方法不返回任何值,可以使用void关键字来表示。

常用的访问修饰符包括public、protected、private和默认访问修饰符。默认情况下,成员方法的访问修饰符是默认的,只能被在同一个包中的其他类访问,而不是全局可见。

在Java中,方法可以带有参数,也可以不带参数。方法的参数可以是基本类型或引用类型,一个方法可以带有多个参数。参数可以是按值传递或按引用传递,基本类型是按值传递,而引用类型是按引用传递。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class Puppy{
int puppyAge;
public Puppy(String name){
System.out.println("小狗的名字是 : " + name );
}

public void setAge( int age ){
puppyAge = age;
}

public int getAge( ){
System.out.println("小狗的年龄为 : " + puppyAge );
return puppyAge;
}

public static void main(String[] args){
/* 创建对象 */
Puppy myPuppy = new Puppy( "tommy" );
/* 通过方法来设定age */
myPuppy.setAge( 2 );
/* 调用方法获取age */
myPuppy.getAge( );
}
}

得到输出:

1
2
小狗的名字是 : tommy
小狗的年龄为 : 2

Java中的域是类或者接口中的变量。一个类或接口可以包含多个域,每个域可以有不同的访问修饰符,如public、protected、private或默认。除了基本类型的域,Java还支持用户自定义类型的域,即类类型(Class Type)或接口类型(Interface Type)。

类中的域可以是实例域或类域,实例域是对于一个类的每个对象都有自己的一份,而类域是类的所有对象共享的。在Java中,可以使用关键字static来定义类域。

类的域可以被其他成员方法访问和修改,它们也可以暴露给外部类或包,或使用getter和setter方法通过封装访问。

有参构造和无参构造

当你创建一个Java类时,Java编译器会自动创建一个无参构造方法。例如,以下是一个名为Person的类,它包含一些成员变量:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Person {
private String name;
private int age;

// 无参构造方法
public Person() {
this.name = "Unknown";
this.age = 0;
}

// 有参构造方法
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}

在这个例子中,无参构造方法会将所有实例变量初始化为默认值。当你通过调用 new Person() 来创建一个新对象时,编译器会调用 Person() 方法,然后返回一个实例化的Person对象。

另一方面,有参构造方法允许在创建对象时传入参数来设置成员变量的初始值。例如,以下代码演示了如何通过使用有参构造方法来创建Person对象:

1
2
Person person1 = new Person(); //  无参构造
Person person2 = new Person("John", 30); // 有参构造

在这个例子中, person1 通过无参构造方法来创建,而 person2 通过有参构造方法来创建并传入名字和年龄参数。

Scanner类

1
import java.util.Scanner;

Scanner类是Java中常用的用于读取用户输入和文件内容的类,它包含多个方法可以读取不同类型的数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import java.util.Scanner;
//导包,找Scanner类

public class Main {
public static void main(String[] args) {
//创建对象,使用Scanner这个类
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个整数:");

//接收数据
int num = scanner.nextInt();
System.out.println("您输入的整数是:" + num);
}
}

上面的代码中,首先创建一个Scanner对象,并传入System.in表示从控制台读取输入。然后使用nextInt()方法读取一个整数,并将其保存到变量num中,最后输出该整数。

对于数据输入,还可以使用 Scanner 类的 next() 与 nextLine() 方法获取输入的字符串,在读取前我们一般需要 使用 hasNext 与 hasNextLine 判断是否还有输入的数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import java.util.Scanner; 

public class ScannerDemo {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
// 从键盘接收数据

// next方式接收字符串
System.out.println("next方式接收:");
// 判断是否还有输入
if (scan.hasNext()) {
String str1 = scan.next();
System.out.println("输入的数据为:" + str1);
}
scan.close();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import java.util.Scanner;

public class ScannerDemo {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
// 从键盘接收数据

// nextLine方式接收字符串
System.out.println("nextLine方式接收:");
// 判断是否还有输入
if (scan.hasNextLine()) {
String str2 = scan.nextLine();
System.out.println("输入的数据为:" + str2);
}
scan.close();
}
}

next() 不能得到带有空格的字符串,nextLine() 以Enter为结束符,也就是说 nextLine()方法返回的是输入回车之前的所有字符,包括空格。

对于整数和小数都有不同的方法进行输入:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import java.util.Scanner;

public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
// 从键盘接收数据
int i = 0;
float f = 0.0f;
double d;
System.out.print("输入整数:");
if (scan.hasNextInt()) {
// 判断输入的是否是整数
i = scan.nextInt();
// 接收整数
System.out.println("整数数据:" + i);
} else {
// 输入错误的信息
System.out.println("输入的不是整数!");
}
System.out.print("输入小数:");
if (scan.hasNextFloat()) {
// 判断输入的是否是小数
f = scan.nextFloat();
// 接收小数
System.out.println("小数数据:" + f);
} else {
// 输入错误的信息
System.out.println("输入的不是小数!");
}
System.out.print("输入小数:");
if (scan.hasNextDouble()) {
// 判断输入的是否是小数
d = scan.nextDouble();
// 接收小数
System.out.println("小数数据:" + f);
} else {
// 输入错误的信息
System.out.println("输入的不是小数!");
}
scan.close();
}
}

重写

重写(Override)是指在子类中重新定义父类中已经存在的方法,注意要保持方法签名一致,方法返回类型、方法名称和参数列表都必须与父类中被重写的方法一致。重写可以实现多态,即同一个方法在不同对象下的实现不同

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Main{
public static void main(String args[]){
class Animal{
public void move(){
System.out.println("动物可以移动");
}
}

class Dog extends Animal{
public void move(){
System.out.println("狗可以跑和走");
}
}

Animal a = new Animal(); // Animal 对象
Animal b = new Dog(); // Dog 对象
a.move();// 执行 Animal 类的方法
b.move();//执行 Dog 类的方法
}
}

之所以能编译成功,是因为 Animal 类中存在 move 方法,然而运行时,运行的是特定对象的方法,如果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Animal{
public void move(){
System.out.println("动物可以移动");
}
}

class Dog extends Animal{
public void move(){
System.out.println("狗可以跑和走");
}
public void bark(){
System.out.println("狗可以吠叫");
}
}

public class Main{
public static void main(String args[]){
Animal a = new Animal(); // Animal 对象
Animal b = new Dog(); // Dog 对象

a.move();// 执行 Animal 类的方法
b.move();//执行 Dog 类的方法
b.bark();
}
}

这样并不会成功运行b.bark();,因为b的引用类型Animal没有bark方法。所以,重写其实是运行的是特定对象Animal的方法,只不过这里是Dog 对象。

@Override是Java中的一个注解,用来指示一个方法覆盖(重写)了超类中的方法,它可以提高代码的可读性和可维护性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class Main{
public static void main(String args[]){
class Animal{
public void move(){
System.out.println("动物可以移动");
}
}

class Dog extends Animal{
@Override
public void move(){
System.out.println("狗可以跑和走");
}
}

Animal animal = new Animal(); // 父类引用指向父类对象
Dog dog = new Dog(); // 子类引用指向子类对象
Animal animal2 = new Dog(); // 父类引用指向子类对象

animal.move(); // 调用父类的移动方法
dog.move(); // 调用子类重写的移动方法
animal2.move(); // 调用的是子类重写的方法,因为animal2指向的是Dog对象
}
}

一个有趣的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import java.util.*;

class Student {
int no;
public Student(int no){
this.no=no;
}

public boolean equals(Student t1){
boolean res = false;
if(this.no==t1.no)
res = true;
return res;
}
}

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

Student b1 = new Student(1);
Student b2 = new Student(1);
System.out.println(b1.equals(b2));// true

Object b3 = new Student(1);
Object b4 = new Student(1);
System.out.println(b3.equals(b4));// false
}
}

重载

重载(Overloading)是Java中的一个重要概念,它指的是在同一个类中定义多个方法,这些方法具有相同的名称但参数不同(类型、个数、顺序),使得程序具有更好的灵活性和可读性。

重载的实现方式可以让一个类中拥有多个同名方法,每个方法拥有不同的参数列表。编译器会根据调用的参数类型、数量和顺序来判断要调用哪个方法。当程序调用重载的方法时,编译器会根据具体的参数,自动匹配最合适的方法进行调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Calculator {
public static int add(int a, int b) {
return a + b;
}

public static double add(double a, double b){
return a + b;
}

public static int add(int a, int b, int c) {
return a + b + c;
}

public static void main(String[] args) {
System.out.println(add(1, 2)); // 调用第一个add方法
System.out.println(add(1.1, 2.2)); // 调用第二个add方法
System.out.println(add(1, 2, 3)); // 调用第三个add方法
}
}

在 Java 中,方法的重载不需要添加任何注解。

数据类型

几种基本类型:

byte:八位,$-128—127$。

short:16位,$-32768—32767$。

int:32位,$-2^{31}—2^{31}-1$。

long:64位,$-2^{63}—2^{63}-1$。

long a = 100000L

long b = -200000L

float:32位,加f

double:64位,加d

1
2
3
4
5
double d1  = 7D ;
double d2 = 7.;
double d3 = 8.0;
double d4 = 8.D;
double d5 = 12.9867;

boolean:true,false。

char:单个Unicode编码,最小值是 \u0000(十进制等效值为 0);最大值是 \uffff(即为 65535)。

生成实例:(注意加static)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class Test {
static boolean bool;
static byte by;
static char ch;
static double d;
static float f;
static int i;
static long l;
static short sh;
static String str;

public static void main(String[] args) {
System.out.println("Bool :" + bool);
System.out.println("Byte :" + by);
System.out.println("Character:" + ch);
System.out.println("Double :" + d);
System.out.println("Float :" + f);
System.out.println("Integer :" + i);
System.out.println("Long :" + l);
System.out.println("Short :" + sh);
System.out.println("String :" + str);
}
}

对于整数类型,前面加0为八进制,前面加0x为16进制。

类型转换

自动类型转换

必须满足转换前的数据类型的位数要低于转换后的数据类型

1
2
3
4
5
6
7
8
9
10
public class Main{
public static void main(String[] args){
char c1='a';//定义一个char类型
int i1 = c1;//char自动类型转换为int
System.out.println("char自动类型转换为int后的值等于"+i1);//97
char c2 = 'A';//定义一个char类型
int i2 = c2+1;//char 类型和 int 类型计算
System.out.println("char类型和int计算后的值等于"+i2);//66
}
}

强制类型转换

格式:(type)value

1
2
3
4
5
6
7
public class Main{
public static void main(String[] args){
int i1 = 123;
byte b = (byte)i1;//强制类型转换为byte
System.out.println("int强制类型转换为byte后的值等于"+b);//123
}
}

小数默认是 double 类型浮点型,在定义 float 类型时必须在数字后面跟上 F 或者 f。

特殊字符

\t制表符:

在打印的时候,把前面字符串的长度补齐到8,或者8的整数倍。最少补1个空格,最多补8个空格:

1
2
3
4
5
6
public class Main {
public static void main(String[] args){
System.out.println("name"+'\t'+"age");
System.out.println("Tom"+'\t'+"23");
}
}

输出对齐:

1
2
name    age
Tom 23

\n换行符:

1
2
3
4
5
public class Main {
public static void main(String[] args){
System.out.println("Hello\nWorld");
}
}

输出换行:

1
2
Hello
World

变量

Java 语言支持的变量类型有:

  • 局部变量(Local Variables):定义在方法、构造方法或语句块中的变量,作用域只限于当前方法、构造方法或语句块中。局部变量必须在使用前声明,并且不能被访问修饰符修饰。
  • 成员变量(Instance Variables):定义在类中、方法之外的变量,作用域为整个类,可以被类中的任何方法、构造方法和语句块访问。成员变量可以被访问修饰符修饰。
  • 静态变量(Class Variables):定义在类中、方法之外的变量,并且使用 static 关键字修饰,作用域为整个类,可以被类中的任何方法、构造方法和语句块访问,静态变量的值在程序运行期间只有一个副本。静态变量可以被访问修饰符修饰。
  • 参数变量(Parameters):方法定义时声明的变量,作为调用该方法时传递给方法的值。参数变量的作用域只限于方法内部。

定义格式:数据类型 变量名 = 数据值;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Main {
// 成员变量
private int instanceVar;
// 静态变量
private static int staticVar;

public void method(int paramVar) {
// 局部变量
int localVar = 10;

// 使用变量
instanceVar = localVar;
staticVar = paramVar;

System.out.println("成员变量: " + instanceVar);
System.out.println("静态变量: " + staticVar);
System.out.println("参数变量: " + paramVar);
System.out.println("局部变量: " + localVar);
}

public static void main(String[] args) {
Main v = new Main();
v.method(20);
}
}

输出:

1
2
3
4
成员变量: 10
静态变量: 20
参数变量: 20
局部变量: 10

使用变量

定义变量,变量运算,修改变量:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Main {
public static void main(String[] args){
int a = 10;
System.out.println(a);//10

int b = 20;
int c = 30;
System.out.println(b + c);//50

a = 20;
System.out.println(a);//20
}
}

不能重复定义变量,例如第十行改为int a = 20;就是错误的。

一条语句中可以多次定义变量:

1
2
3
4
5
6
public class Main {
public static void main(String[] args) {
int a = 10, b = 20, c = 30;
System.out.println(a + b + c);
}
}

循环结构

while

和c语言类似:

1
2
3
while( 布尔表达式 ) {
//循环内容
}

do…while

1
2
3
do {
//代码语句
}while(布尔表达式);

不同于while,这种方法就算不满足布尔表达式内容也会至少执行一次。

for循环

和c语言类似:

1
2
3
for(初始化; 布尔表达式; 更新) {
//代码语句
}

增强 for 循环

Java5 引入了一种主要用于数组的增强型 for 循环:

1
2
3
4
for(声明语句 : 表达式)
{
//代码句子
}

声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配。其作用域限定在循环语句块,其值与此时数组元素的值相等。

表达式:表达式是要访问的数组名,或者是返回值为数组的方法。

举个例子:

1
2
3
4
5
6
7
8
public class Main {
public static void main(String[] args) {
int[] a={1,2,3,4,5};
for(int t: a){
System.out.println(t);
}
}
}

输出:

1
2
3
4
5
1
2
3
4
5

正则表达式

正则表达式是一种用于匹配字符串的模式,它是一个字符序列,可以用来表达一定规则的字符串集合。正则表达式通常包括普通字符和特殊字符两种类型。

普通字符是正则表达式中的标准字符,它们表示自己本身,例如字母、数字和空格等。

特殊字符是正则表达式中的元字符,它们具有特殊含义,用于表示更复杂的匹配规则。例如,[] 表示字符集,() 表示组,* 表示匹配前面的字符 0 次或多次。

常用的正则表达式:

  • . 匹配任意单个字符,例如 a.c 可匹配 abcaxca#c 等。
  • [] 匹配指定字符集中的任意一个字符,例如 [abc] 可匹配 abc
  • [^] 匹配除指定字符集外的任意一个字符,例如 [^abc] 可匹配除了 abc 以外的任意一个字符。
  • * 匹配前一个字符 0 次或多次,例如 a* 可以匹配空字符串、aaaaaa 等。
  • + 匹配前一个字符 1 次或多次,例如 a+ 可以匹配 aaaaaa 等,但不能匹配空字符串。
  • ? 匹配前一个字符 0 次或 1 次,例如 a? 可以匹配空字符串或 a
  • {m,n} 匹配前一个字符至少 m 次,至多 n 次,例如 a{2,4} 可以匹配 aaaaaaaaa,但不能匹配 aaaaaa
  • () 表示一个组,例如 (ab)+ 表示匹配至少一个 ab
  • | 表示或,例如 a|b 表示匹配 ab
  • \d 匹配任意一个数字字符,相当于 [0-9]
  • \D 匹配任意一个非数字字符,相当于 [^0-9]
  • \s 匹配任意一个空白字符,包括空格、制表符、换行符等。
  • \S 匹配任意一个非空白字符。
  • \w 匹配任意一个数字字符或字母字符,相当于 [a-zA-Z0-9]
  • \W 匹配任意一个非数字字符或非字母字符,相当于 [^a-zA-Z0-9]

实验练习

基本语法实验

要求从键盘读取输入的整数成绩,由百分制转换成五分制输出结果。[0,60)不及格,[60,70)及格,[70,80)中,[80,90)良,[90,100]优,其余显示为:成绩不正确。

输入格式

输入一个整数形式的百分制成绩。

输出格式

输出相应的五分制成绩。

输入样例

1
78

输出样例

在这里给出相应的输出。例如:

1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import java.util.Scanner;

public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int num = sc.nextInt();
if (num > 100 || num < 0)
System.out.println("成绩不正确");
else if (num >= 90)
System.out.println("优");
else if (num >= 80)
System.out.println("良");
else if (num >= 70)
System.out.println("中");
else if (num >= 60)
System.out.println("及格");
else
System.out.println("不及格");
sc.close();
}
}

数据类型-勾股定理

请编程程序,实现如下功能:输入直接三角形的两个直角边的边长,求它们的斜边边长,结果保留2位小数。

提示:在Java中利用Math类的方法——Math.sqrt()求平方根。

java.lang.Math.sqrt(double a) 返回一个double值的正平方根。

输入格式

输入有若干行,每行有2个数值,分别表示直角三角形的两个直角边长度,用空格分隔。

输出格式

对应每行输入数据,输出直角三角形的斜边长度,结果保留2位小数。

输入样例

1
2
3
4
3 4
2.3 3
5 6
10 12

输出样例

在这里给出相应的输出。例如:

1
2
3
4
5.00
3.78
7.81
15.62

为了保留两位小数,可以使用DecimalFormat类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import java.text.DecimalFormat;
import java.util.Scanner;

public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
DecimalFormat de = new DecimalFormat(".00");
while (sc.hasNext()) {
double a = sc.nextDouble();
double b = sc.nextDouble();
double c = Math.sqrt(a * a + b * b);
System.out.println(de.format(c));
}
sc.close();
}
}

或者直接用printf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import java.util.Scanner;

public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
double a = sc.nextDouble();
double b = sc.nextDouble();
double c = Math.sqrt(a * a + b * b);
System.out.printf("%.2f\n",c);
}
sc.close();
}
}

输出水仙花数

所谓的水仙花数是指一个n位数n>=3 && n<=7,它的每个位上的数字n次幂之和等于本身。
例如,3位数153是水仙花,各位数字的立方和13+53+33=153。
要求:输出所有位数为3的水仙花数。

输入格式

输出格式

位数为3的所有水仙花数,每行一个。

输入样例

1

输出样例

1
2
153

直接逐个遍历即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Main {
public static void main(String[] args) {
int i;
for (i = 100; i < 1000; i++) {
int sum = 0;
int num = i;
while (num != 0) {
int digit = num % 10;
sum += Math.pow(digit, 3);
num /= 10;
}
if (sum == i) {
System.out.println(sum);
}
}
}
}

求圆的面积

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
按要求完成程序的编写。
1、定义圆类Circle,其中包括:
(1)成员变量:private int radius
(2)无参构造方法 ,给radius赋值为2,并输出信息:"This is a constructor with no para.";
(2)有参构造方法 ,接收用户给的radius赋值,并输出"This is a constructor with para."(如果给的半径小于等于0,则赋默认值为2);
(3)为radius添加set方法,接收用户输入的半径,如果用户输入半径为<=0,则让半径的值为2;
(4)为radius半径添加get方法,返回用户输入的半径;
(5)求圆面积方法getArea(), π使用Math.PI代替;
(6)定义toString方法,public String toString( )方法体为:
return "Circle [radius=" + radius + "]";

2、定义Main类,在main方法中,完成下列操作:
(1)定义并创建Circle类对象c1,输出c1对象,求c1的面积并输出;
(2)定义并创建Circle类对象c2,输出c2对象,求c2的面积并输出;
(3)从键盘接收整数半径,赋值给c2的半径,输出c2对象,求c2的面积并输出;
(4)从键盘接收整数半径,用有参构造方法创建Circle类对象c3,输出c3对象,求c3的面积后输出。

输入格式

输入有多行。每行包括一个整数的圆的半径。

输出格式

按照题目要求,输出圆构造方法的输出信息、圆对象的字符中描述信息、及圆的面积(其中圆的面积保留2位小数)。上述信息各占一行。

输入样例

1
2
4
5

输出样例

1
2
3
4
5
6
7
8
9
10
11
This is a constructor with no para.
Circle [radius=2]
12.57
This is a constructor with no para.
Circle [radius=2]
12.57
Circle [radius=4]
50.27
This is a constructor with para.
Circle [radius=5]
78.54
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import java.util.Scanner;

class Circle {
private int radius;

//无参构造方法
public Circle() {
radius = 2;
System.out.println("This is a constructor with no para.");
}

//有参构造方法
public Circle(int r) {
if (r <= 0) {
radius = 2;
} else {
radius = r;
}
System.out.println("This is a constructor with para.");
}

//设置半径
public void setRadius(int r) {
if (r <= 0) {
radius = 2;
} else {
radius = r;
}
}

//获取半径
public int getRadius() {
return radius;
}

//求面积
public double getArea() {
return Math.PI * radius * radius;
}

//toString方法
public String toString() {
return "Circle [radius=" + radius + "]";
}
}

public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);

// 定义并创建Circle类对象c1
Circle c1 = new Circle();
System.out.println(c1.toString());
System.out.printf("%.2f\n", c1.getArea());

// 定义并创建Circle类对象c2
Circle c2 = new Circle();
System.out.println(c2.toString());
System.out.printf("%.2f\n", c2.getArea());

//从键盘接收半径,设置c2的半径,输出c2对象,求c2的面积并输出
int r1 = sc.nextInt();
c2.setRadius(r1);
System.out.println(c2.toString());
System.out.printf("%.2f\n", c2.getArea());

//从键盘接收半径,用有参构造方法创建对象c3、输出c3对象,求c3的面积并输出
int r2 = sc.nextInt();
Circle c3 = new Circle(r2);
System.out.println(c3.toString());
System.out.printf("%.2f\n", c3.getArea());

sc.close();
}
}

小写转大写

大家都知道一些办公软件有自动将字母转换为大写的功能。输入一个长度不超过 100 且不包括空格的字符串。要求将该字符串中的所有小写字母变成大写字母并输出。

输入格式

输入一个长度不超过 100 且不包括空格的字符串。

输出格式

将该字符串中的所有小写字母变成大写字母并输出。

输入样例

1
fuzhouU

输出样例

1
FUZHOUU

这里可以遍历用charAt方法进行索引:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import java.util.Scanner;

public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
String ans = "";
int len = s.length();
for (int i = 0; i < len; i++) {
if (s.charAt(i) >= 'a' && s.charAt(i) <= 'z') {
ans += (char)(s.charAt(i) - 32);
} else {
ans += s.charAt(i);
}
}
System.out.println(ans);
}
}

面向对象实验一

实验要求:设计类Rectangle,定义必要的属性和方法,要求包含两个构造方法,至少实现求面积、求周长并进行测试。

输入格式

输入两个边长。

输出格式

对每一组输入,在一行中输出面积的值和周长的值。

输入样例

在这里给出一组输入。例如:

1
2  3

输出样例

在这里给出相应的输出。例如:

1
6 10

给一种比较简单的做法:

1
2
3
4
5
6
7
8
9
10
import java.util.Scanner;

public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int a=sc.nextInt(),b=sc.nextInt();
System.out.printf("%d %d\n",a*b,2*(a+b));
sc.close();
}
}

题目让设计类,按照题目的要求再做一遍:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import java.util.Scanner;

class Rectangle{
public int length,width;
Rectangle(int p,int q){
this.length=p;
this.width=q;
}
public int getLong(){
return 2*(length+width);
}
public int getSize(){
return length*width;
}
}

public class Main {

public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Rectangle re = new Rectangle(sc.nextInt(), sc.nextInt());
System.out.printf("%d %d\n",re.getSize(),re.getLong());
sc.close();
}
}

面向对象实验二

利用之前完成的类Rectangle,编写子类Square,实现正方形的求面积和求周长功能,并进行测试。

输入格式

输入整数边长。

输出格式

对每一组输入,在一行中输出面积和周长的值。

输入样例

在这里给出一组输入。例如:

1
5

输出样例

在这里给出相应的输出。例如:

1
25 20

加一个重写Rectangle就行了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import java.util.Scanner;

class Rectangle {
int length;
int width;

Rectangle(int length, int width) {
this.length = length;
this.width = width;
}

public int getLong() {
return 2 * (length + width);
}

public int getSize() {
return length * width;
}
}

class Square extends Rectangle {
Square(int side) {
super(side, side);
}
}

public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Square sq = new Square(sc.nextInt());
System.out.printf("%d %d\n", sq.getSize(), sq.getLong());
sc.close();
}
}

这里用到了super关键字:使用 super(side, side)Square 子类中调用了父类 Rectangle 的构造函数来初始化 lengthwidth 变量:

1
2
3
4
5
class Square extends Rectangle {
Square(int side) {
super(side, side); // 调用父类构造函数
}
}

在这里,使用 super() 调用了 Rectangle 中的构造函数,可以把一个参数的 side 赋值给 lengthwidth,实现了正方形继承矩形的操作。

判断登录信息是否正确

从键盘接收用户输入的两个字符串,第一个代表用户名,第二个代表密码。

(1)如果用户名是SwpuIot,并且密码是123456,则输出:Welcome

(2)如果用户名正确,密码不正确,输出:Mismatch

(3)其他情况下,输出:NotExist

要输出的信息,建议从题目中复制,确保精确匹配。

输入格式

用空格分隔开的两个字符串。

输出格式

首字母大写的一个单词或词组。

输入样例

1
SwpuIot 123456

输出样例

1
Welcome

注意java比较字符串相等不用双等于,双等于==比较的是两个字符串是否引用的同一个对象,可以用equals方法来比较:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.util.Scanner;

class User{
String name = "SwpuIot";
String password = "123456";
}

public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
User us = new User();
String name1 = sc.next();
String password1 = sc.next();
if (name1.equals(us.name)&&password1.equals(us.password))
System.out.println("Welcome");
else if (name1.equals(us.name))
System.out.println("Mismatch");
else
System.out.println("NotExist");
sc.close();
}
}

图书价格汇总

假设图书馆中图书信息的格式为:

Java程序设计: 34;Web程序设计: 56;JSP程序设计:20

按要求输出每本图书的名称及价格,计算所有图书的总价格并输出。

输入格式

读入一行图书信息。如:

Java程序设计: 34;Web程序设计: 56;JSP程序设计:20

提示:

(1)每本书的价格是整数,价格与下一本书的名字之间有一个中文;价格前可能有空格,可能没有。

(2)题目中的分号”“和冒号”“为全角字符。

输出格式

分别输出每本图书的名称及价格,一本书占一行,形式为:书名—价格

最后,输出计算的所有图书的总价格,形式为:总价格—总价格

输入样例

1
Java程序设计:34 ;Web程序设计: 56;JSP程序设计:20

输出样例

1
2
3
4
Java程序设计--34
Web程序设计--56
JSP程序设计--20
总价格--110
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import java.util.Scanner;

public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String s = scanner.nextLine();
String[] books = s.split(";");
int totalPrice = 0;
for (String b : books) {
String[] book = b.split(":");
String name = book[0];
int price = Integer.parseInt(book[1].trim());
System.out.printf("%s--%d\n", name, price);
totalPrice += price;
}
System.out.printf("总价格--%d", totalPrice);
scanner.close();
}
}

代码对字符串转换为整数使用了int price = Integer.parseInt(book[1].trim());,由于读入的字符串中,书名和价格之间可能存在空格,因此在解析价格时需要使用 trim 方法将字符串前后的空格去掉,再使用 Integer.parseInt 方法将字符串转换为整数。

子串在整串中出现的次数

编写一个程序,统计一个子串在整串中出现的次数,例如子串“nba”在整串“nbaabcdefnbaxyzmba”中出现的次数为2。要求使用String或者StringBuffer类的常用方法来计算出现的次数。

输入格式

输入两行,每行输入一个字符串。第一个当作整串,第二个当作子串。每个字符串的中间不要出现换行符(Enter)、空格、制表符(Tab)。

输出格式

输出子串在整串中出现的次数,结果是一个大于或等于0的整数。

输入样例1

在这里给出一组输入。例如:

1
2
吃葡萄不吐葡萄皮,不吃葡萄倒吐葡萄皮。
葡萄

输出样例1

在这里给出相应的输出。例如:

1
4

输入样例2

在这里给出一组输入。例如:

1
2
abcdefghijklmn
cdf

输出样例2

在这里给出相应的输出。例如:

1
0

这里需要用到indexOf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import java.util.Scanner;

public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String whole = sc.nextLine();
String sub = sc.nextLine();
int count = 0;
int index = 0;
while ((index = whole.indexOf(sub, index)) != -1) {
count++;
index += sub.length();
}
System.out.println(count);
sc.close();
}
}

indexOf 方法是 String 类中查找某个字符串的方法, 传入一个参数表示要查找的字符串,返回一个整数表示该字符串在整个字符串中第一次出现的位置,如果没找到则返回 -1

1
2
3
String str = "hello world";
int index = str.indexOf("world"); // 查找 “world” 的位置
System.out.println(index); // 输出 “6”

如果想要从指定位置开始查找,可以加入一个参数表示在字符串的哪个索引位置开始查找:

1
2
3
String str = "hello hello world";
int index = str.indexOf("hello", 2); // 从第二个位置开始查找"hello"
System.out.println(index); // 输出 “6”

10个整数最大值……

找出10个整数中的最大值、最小值、偶数的个数、偶数的平均值。(使用Scanner类从键盘输入数据。)

输入格式

在一行中输入10个整数,中间用空格隔开。

输出格式

分四行分别输出最大值、最小值、偶数的个数、偶数的平均值。

输入样例1

1
18 -6 12 27 9 31 -20 42 33 75

输出样例1

1
2
3
4
最大值是75
最小值是-20
偶数的个数是5
偶数的平均值是9.2

输入样例2

1
11 13 15 17 19 21 23 25 27 29

输出样例2

1
2
3
4
最大值是29
最小值是11
偶数的个数是0
偶数的平均值是0.0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import java.util.Scanner;

public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int min, max, evenCount, evenSum;
min = Integer.MAX_VALUE;
max = Integer.MIN_VALUE;
evenCount = 0;
evenSum = 0;
for (int i = 0; i < 10; i++) {
int num = scanner.nextInt();
if (num < min) {
min = num;
}
if (num > max) {
max = num;
}
if (num % 2 == 0) {
evenCount++;
evenSum += num;
}
}
System.out.println("最大值是" + max);
System.out.println("最小值是" + min);
System.out.println("偶数的个数是" + evenCount);
if (evenCount > 0) {
System.out.println("偶数的平均值是" + ((double) evenSum / evenCount));
} else {
System.out.println("偶数的平均值是0.0");
}
scanner.close();
}
}

这里要注意一个地方:

1
2
min = Integer.MAX_VALUE;
max = Integer.MIN_VALUE;

为了寻找最大值和最小值,采用遍历比较覆盖的方式,所以首先为了防止初始值不更新,把最大值设为整数最小值,最小值设为整数最大值,这样可以保证接收到第一个数就能全部更新,防止出错。

冒泡排序

对10个整数进行排序。(使用Scanner类从键盘输入数据。)

请注意:含有main方法的类(class)的名字必须命名为Main,否则调试不成功。

输入格式

在一行中输入10个整数,中间以空格隔开。

输出格式

按从小到大的顺序输出这10个整数,中间以一个空格隔开(最末尾不要空格)。

输入样例

在这里给出一组输入。例如:

1
5 20 34 6 -13 26 72 10 39 -9

输出样例

在这里给出相应的输出。例如:

1
-13 -9 5 6 10 20 26 34 39 72

写个冒泡排序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import java.util.Scanner;

public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int[] nums = new int[10];
for (int i = 0; i < 10; i++) {
nums[i] = scanner.nextInt();
}

for (int i = 0; i < 9; i++) {
for (int j = i + 1; j < 10; j++) {
if (nums[i] > nums[j]) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
}

for (int i = 0; i < 10; i++) {
System.out.print(nums[i]);
if (i < 9) {
System.out.print(" ");
}
}
scanner.close();
}
}

代码使用了两层循环进行冒泡排序:

创建一个大小为 10 的整型数组,将输入的 10 个整数存储在该数组中。

使用冒泡排序算法进行排序。循环从数组第一个元素开始,与后续的元素比较,如果前面的元素大于后面的元素,就交换位置。这样,第一轮循环结束后数组最后一个元素就是最大的元素。第二轮循环就比较数组的前 9 个元素,第二轮循环结束后,数组的倒数第二个元素就是次大的元素。以此类推,直到最后一次循环只比较数组的前 2 个元素为止。

及格与不及格

编写一个程序进行一个班某门课程成绩的录入,能够控制录入成绩总人数,对录入成绩统计其及格人数和不及格人数。设计一个异常类,当输入的成绩小0分或大于100分时,抛出该异常类对象,程序将捕捉这个异常对象,并调用执行该异常类对象的toString()方法,该方法获取当前无效分数值,并返回一个此分数无效的字符串。

输入格式

从键盘中输入学生人数n

从键盘中输入第1个学生的成绩

从键盘中输入第2个学生的成绩

从键盘中输入第n个学生的成绩

(注:当输入的成绩无效时(即分数为小于0或大于100)可重新输入,且输出端会输出此分数无效的提醒。)

输出格式

显示及格总人数

显示不及格总人数

输入样例

在这里给出一组输入。例如:

1
2
3
4
3
100
30
60

输出样例

在这里给出相应的输出。例如:

1
2
2
1

输入样例

在这里给出一组输入。例如:

1
2
3
4
2
200
69
30

输出样例

在这里给出相应的输出。例如:

1
2
3
200invalid!
1
1

给出代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import java.util.Scanner;

public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
int passNum = 0, failNum = 0;
for (int i = 1; i <= n; i++) {
int score = 0;
boolean judge = false;
while (!judge) {
score = scan.nextInt();
if (score < 0 || score > 100)
System.out.println(score+"invalid!");
else
judge = true;
}
if (score >= 60)
passNum++;
else
failNum++;
}
System.out.println(passNum);
System.out.println(failNum);
scan.close();
}
}

注意题目要求了:当输入的成绩无效时(即分数为小于0或大于100)可重新输入,且输出端会输出此分数无效的提醒。这里我们可以写一个循环,接受数据直到符合要求为止:

1
2
3
4
5
6
7
        while (!judge) {
score = scan.nextInt();
if (score < 0 || score > 100)
System.out.println(score+"invalid!");
else
judge = true;
}

计算机类

构造计算机类,其中包含其配置信息:处理器、主板、内存、显示器、硬盘等设备,各个设备均有型号(字符串),特别的,处理器有主频(小数)和内核数(整数)、显示器有尺寸(整型)、内存和硬盘有容量数据(GB为单位)。请你尝试构造合适的类和类的关系来表示计算机,并为该计算机类添加计算价格(各设备价格之和)、打印配置信息等方法。重写相关类的equals方法,使得两个配置完全相同的计算机为相同的计算机。重写相关类的toString函数,打印计算机的配置信息。

提示:
为计算机类和各个组成配件都构造类,分别重写toString和equals方法。
在计算机类中调用各个配件的equals和toString方法。

输入格式

两个计算机对象,包含
CPU:型号、主频、内核
主板:型号
内存:容量
显示器:尺寸
硬盘:容量

输出格式

两个对象是否相等
两个对象的配置信息

输入样例

在这里给出一组输入。例如:

1
2
3
4
5
6
7
8
9
10
Corei7 2.8 4
GIGABYTE-B250M-D3H
xiede-DDR3 8
SamsungC27F39 27
SEAGATE-ST1000DM010 2048
Corei7 2.8 4
GIGABYTE-B250M-D3H
xiede-DDR3 8
SamsungC27F39 27
SEAGATE-ST1000DM010 2048

输出样例

在这里给出相应的输出。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
true
Computer1:
CPU:
Model: Corei7
Frequency: 2.8
Number of Cores: 4
Mainboard:
Model: GIGABYTE-B250M-D3H
Memory:
Model: xiede-DDR3
Size: 8
Screen:
Model: SamsungC27F39
Size: 27
Harddisk:
Model: SEAGATE-ST1000DM010
Size: 2048
Computer2:
CPU:
Model: Corei7
Frequency: 2.8
Number of Cores: 4
Mainboard:
Model: GIGABYTE-B250M-D3H
Memory:
Model: xiede-DDR3
Size: 8
Screen:
Model: SamsungC27F39
Size: 27
Harddisk:
Model: SEAGATE-ST1000DM010
Size: 2048

按照题目要求写的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
import java.util.Scanner;

class CPU {
private String model;
private double frequency;
private int cores;

public CPU(String model, double frequency, int cores) {
this.model = model;
this.frequency = frequency;
this.cores = cores;
}

@Override
public boolean equals(Object obj) {
CPU cpu = (CPU) obj;
return model.equals(cpu.model) && frequency == cpu.frequency && cores == cpu.cores;
}

@Override
public String toString() {
return "CPU:\n" +
"Model: " + model + "\n" +
String.format("Frequency: %.1f\n", frequency) +
"Number of Cores: " + cores;
}
}

class Mainboard {
private String model;

public Mainboard(String model) {
this.model = model;
}

@Override
public boolean equals(Object obj) {
Mainboard mainboard = (Mainboard) obj;
return model.equals(mainboard.model);
}

@Override
public String toString() {
return "Mainboard:\n" +
"Model: " + model;
}
}

class Memory {
private String model;
private int size;

public Memory(String model, int size) {
this.model = model;
this.size = size;
}

@Override
public boolean equals(Object obj) {
Memory memory = (Memory) obj;
return model.equals(memory.model) && size == memory.size;
}

@Override
public String toString() {
return "Memory:\n" +
"Model: " + model + "\n" +
"Size: " + size;
}
}

class Screen {
private String model;
private int size;

public Screen(String model, int size) {
this.model = model;
this.size = size;
}

@Override
public boolean equals(Object obj) {
Screen screen = (Screen) obj;
return model.equals(screen.model) && size == screen.size;
}

@Override
public String toString() {
return "Screen:\n" +
"Model: " + model + "\n" +
"Size: " + size;
}
}

class Harddisk {
private String model;
private int size;

public Harddisk(String model, int size) {
this.model = model;
this.size = size;
}

@Override
public boolean equals(Object obj) {
Harddisk harddisk = (Harddisk) obj;
return model.equals(harddisk.model) && size == harddisk.size;
}

@Override
public String toString() {
return "Harddisk:\n" +
"Model: " + model + "\n" +
"Size: " + size;
}
}

class Computer {
private CPU cpu;
private Mainboard mainboard;
private Memory memory;
private Screen screen;
private Harddisk harddisk;

public Computer(CPU cpu, Mainboard mainboard, Memory memory, Screen screen, Harddisk harddisk) {
this.cpu = cpu;
this.mainboard = mainboard;
this.memory = memory;
this.screen = screen;
this.harddisk = harddisk;
}

@Override
public boolean equals(Object obj) {
Computer computer = (Computer) obj;
return cpu.equals(computer.cpu) && mainboard.equals(computer.mainboard) && memory.equals(computer.memory) && screen.equals(computer.screen) && harddisk.equals(computer.harddisk);
}

@Override
public String toString() {
return cpu + "\n" +
mainboard + "\n" +
memory + "\n" +
screen + "\n" +
harddisk;
}
}

public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);

String cpuModel1 = scanner.next();
double cpuFrequency1 = Double.parseDouble(scanner.next());
int cpuCores1 = scanner.nextInt();
CPU cpu1 = new CPU(cpuModel1, cpuFrequency1, cpuCores1);
String mainboardModel1 = scanner.next();
Mainboard mainboard1 = new Mainboard(mainboardModel1);
String memoryModel1 = scanner.next();
int memorySize1 = scanner.nextInt();
Memory memory1 = new Memory(memoryModel1, memorySize1);
String screenModel1 = scanner.next();
int screenSize1 = scanner.nextInt();
Screen screen1 = new Screen(screenModel1, screenSize1);
String harddiskModel1 = scanner.next();
int harddiskSize1 = scanner.nextInt();
Harddisk harddisk1 = new Harddisk(harddiskModel1, harddiskSize1);
Computer computer1 = new Computer(cpu1, mainboard1, memory1, screen1, harddisk1);

String cpuModel2 = scanner.next();
double cpuFrequency2 = Double.parseDouble(scanner.next());
int cpuCores2 = scanner.nextInt();
CPU cpu2 = new CPU(cpuModel2, cpuFrequency2, cpuCores2);
String mainboardModel2 = scanner.next();
Mainboard mainboard2 = new Mainboard(mainboardModel2);
String memoryModel2 = scanner.next();
int memorySize2 = scanner.nextInt();
Memory memory2 = new Memory(memoryModel2, memorySize2);
String screenModel2 = scanner.next();
int screenSize2 = scanner.nextInt();
Screen screen2 = new Screen(screenModel2, screenSize2);
String harddiskModel2 = scanner.next();
int harddiskSize2 = scanner.nextInt();
Harddisk harddisk2 = new Harddisk(harddiskModel2, harddiskSize2);
Computer computer2 = new Computer(cpu2, mainboard2, memory2, screen2, harddisk2);

scanner.close();
System.out.println(computer1.equals(computer2));
System.out.println("Computer1:\n" + computer1);
System.out.println("Computer2:\n" + computer2);
}
}