Fork me on GitHub

数据库的建立

数据库的建立

初学MySQL数据库,还不会使用cmd创建数据库。因此我通过可是化的软件在实现数据库的建立

SQLyog的使用

我们下载号SQLyog后,可以再对MySQL链接一下,通过可视化的操作建立数据库

注意 在创建时一定要使用UTF-8字符集

在核对时一定要选择utf-8_general_ei

这样的选择可以对中文融合

检索数据

SELECT语句

我们检索数据 重要使用的是SQL语句,SQL语句中最经常使用的是SELECT语句

在SQL语句中的大小写

SQL语句不区分大小写,因此SELECT和select是相同的

  • 我们将SQL中的关键字使用大写
  • 我们将列和表名使用小写

检索单个列

语法结构

1
2
SELECT 列名
FROM 表名;

这是最简单的检索,既没有过滤数据,也没有排序

检索多个列

语法结构:

1
2
SELECT 第一个列名,第二个列名,第n个列名
FROM 表名;

在选择多个列时,一定要在列名之间加上逗号,最后一个列名不加,否则会出现错误

检索所有的列

SELECT语句可以检索所有的列而不必逐个列出列名,只需要在列名位置用(*)代替即可

1
2
SELECT *
FROM 表名;

检索不同的行

意义为:将一列中相同的元素剔除,只留下一个。输出列值都不同

语法结构

1
2
SELECT DISTINCT 列名
FROM 表名;

限制效果

通过使用限制效果,我们可以返回第一行或前几行

语法结构

1
2
3
SELECT 列名
FROM 表名
LIMIT 阿拉伯数字;

在上述的阿拉伯数字有两种形式:

  • 单一的阿拉伯数字:表示前n行数据
  • n,m :表示从行n取到行m

注意:在MySQL中,行是从行0开始的

(n,m)这种形式也可以写为 (m OFFSET n)表达的意思一样

get文件form多重文件夹

图片抽取程序

最基础的文件读写

最基础的文件读写是通过IO流来实现的,格式比较固定,只能实现文件到文件的程序处理

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
package com.dwx.getImage;

import java.io.*;
//这是一个简单的文件读写 只能实现文件到文件
public class getImage {
//获得文件是一个递归函数
public void getImage(File fileIn,File fileOut) throws IOException {
//对于这个方法需要两个变量 一个是目标文件fileIn 一个是终点文件fileOut
//在java中 文件的存储方式是集合(list)
//通过InputStream来存储源文件 通过OutputStream来表示目标地址
FileInputStream fi = null;
FileOutputStream fo = null;
try {
//为目标文件创建成一个流
fi = new FileInputStream(fileIn);
fo = new FileOutputStream(fileOut);
//创造一个数组来存取这个文件
byte[] buffer = new byte[1024];
int len;
while ((len = fi.read(buffer))!=-1){
fo.write(buffer,0,len);
}

} catch (FileNotFoundException e) {
e.printStackTrace();
}finally {
//对于用完的资源要及时关闭
try {
fi.close();
} catch (IOException e) {
e.printStackTrace();
}
}

}
}

实现对文件的遍历

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
package com.dwx.getImage;

import java.io.*;

//这个类我们来测试一下从文件夹中得到文件,并指定输出到我们想到的位置
public class getImageDemo02 {
//这个方法已经实现了对文件的遍历
public void getImage(File fileIn,File fileOut){
//我们要知道 文件类型可能是文件,也可能是文件夹
//这里我们来判断是否是一个文件夹
//通过 fileIn.listFiles就能把一个文件夹转化成list
//通过递归来实现对整个文件夹的遍历
// System.out.println(fileIn.isDirectory());
// for (File f : fileIn.listFiles()){
// System.out.println(f);
// }
//对于文件遍历 若是文件夹 就在进入下一次 如果是文件 return
if (fileIn.isDirectory()){
for(File fi:fileIn.listFiles()){
System.out.println(fi);
getImage(fi,fileOut);
}
}
//如果不是就直接返回
else{
//System.out.println(fileIn.getAbsolutePath());
return;
}

}

public static void main(String[] args) {
getImageDemo02 getImageDemo02 = new getImageDemo02();
File fi = new File("E:/get");
File fo = new File("E:/out");
getImageDemo02.getImage(fi,fo);
}
}

对完整的实现文件遍历并且下载的实现

程序作用

在得到一个多重文件夹时,提取文件夹中的文件会十分麻烦,因此,我编写了一个程序。程序能够遍历整个文件夹中的文件,并且把文件复制到我们的目标文件夹。

程序的基本思想

编写程序时的基础思想为:如果读入的是一个文件夹,就操作文件夹中的元素(文件通过file.listFiles( )将文件转换成list,通过for循环进行遍历)。如果读入的是一个文件,就copy这个文件到目标文件夹

程序的技术支持

  • I/O流 IO流的使用把文件读为一个流 对流的处理会比较简单
  • 递归的使用:程序的基本思想是递归的,因此,使用递归思想写程序更加方便,且易于理解
  • 文件名的获得:file.getName()就能获得文件的文件名 + 目标文件夹名 就能创造出一个新的文件 通过流对其进行操作

copy方法的实现

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
package com.dwx.getImage;

import java.io.*;
//这是一个简单的文件读写 只能实现文件到文件
public class getImage {
//获得文件是一个递归函数
public void getImage(File fileIn,File fileOut) throws IOException {
//对于这个方法需要两个变量 一个是目标文件fileIn 一个是终点文件fileOut
//在java中 文件的存储方式是集合(list)
//通过InputStream来存储源文件 通过OutputStream来表示目标地址
FileInputStream fi = null;
FileOutputStream fo = null;
try {
//为目标文件创建成一个流
fi = new FileInputStream(fileIn);
fo = new FileOutputStream(fileOut);
//创造一个数组来存取这个文件
byte[] buffer = new byte[1024];
int len;
while ((len = fi.read(buffer))!=-1){
fo.write(buffer,0,len);
}

} catch (FileNotFoundException e) {
e.printStackTrace();
}finally {
//对于用完的资源要及时关闭
try {
fi.close();
} catch (IOException e) {
e.printStackTrace();
}
}

}
}

遍历(递归)方法的实现

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
package com.dwx.getImage;

import java.io.*;

//这个类我们来测试一下从文件夹中得到文件,并指定输出到我们想到的位置
public class getImageDemo02 {
//这个方法已经实现了对文件的遍历
public void getImage(File fileIn,File fileOut){
//我们要知道 文件类型可能是文件,也可能是文件夹
//这里我们来判断是否是一个文件夹
//通过 fileIn.listFiles就能把一个文件夹转化成list
//通过递归来实现对整个文件夹的遍历
// System.out.println(fileIn.isDirectory());
// for (File f : fileIn.listFiles()){
// System.out.println(f);
// }
//对于文件遍历 若是文件夹 就在进入下一次 如果是文件 return
if (fileIn.isDirectory()){
for(File fi:fileIn.listFiles()){
getImage(fi,fileOut);
}
}
//如果不是就直接返回
else{
getImage getImage = new getImage();
System.out.println(fileIn);
System.out.println("文件名字为"+fileIn.getName());
File file = new File(fileOut+"\\"+ fileIn.getName());
System.out.println("写到了"+file.getName());
try {
getImage.getImage(fileIn,file);
} catch (IOException e) {
e.printStackTrace();
}
return;
}

}

// public static void main(String[] args) {
// getImageDemo02 getImageDemo02 = new getImageDemo02();
// File fi = new File("E:/get");
// File fo = new File("E:/out");
// getImageDemo02.getImage(fi,fo);
// }
}

主方法(main)方法

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
package com.dwx.test;

import com.dwx.getImage.getImageDemo02;

import java.io.File;
import java.util.Scanner;

public class test {
public static void main(String[] args) {
// getImage getImage = new getImage();
// File fi = new File("E:\\get\\1.jpg");
// File fo = new File("E:\\out\\1.jpg");
// try {
// getImage.getImage(fi,fo);
// } catch (IOException e) {
// e.printStackTrace();
// }
String fileInName;
String fileOutName;
Scanner scanner = new Scanner(System.in);
System.out.print("请输入源文件夹:");
fileInName = scanner.nextLine();
System.out.print("请输入目标文件夹:");
fileOutName = scanner.nextLine();
File fileIn = new File(fileInName);
File fileOut = new File(fileOutName);
getImageDemo02 getImageDemo02 = new getImageDemo02();
getImageDemo02.getImage(fileIn,fileOut);
}
}

未来(已来)

对于这个程序还有很多能够完善的

加上下载时间

已经加上了各个图片的下载时间 时间是以毫秒为单位的

特定文件类型的获取

我给出的解决方案:增加一个过滤器,当查询到文件后,让文件后缀跟过滤器比较,比较成功就进行操作

已经实现

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
package com.dwx.filter;

import java.io.File;

//这是一个过滤器,用来特殊过滤文件
public class Filter {
//对于一个过滤器,他有的属性就是文件后缀名
String FileLastName;
//在类被加载时就对这个属性进行初始化

public Filter(String fileLastName) {
FileLastName = fileLastName;
}
//过滤器的方法
public boolean FileFilter(File fileIn){
//立一个布尔类型的标记 来判断是否是合适的后缀文件
boolean flag = false;
//如果输入的是all 则操作所有的类型
if (FileLastName.equals("all")){
return true;
}
//获取文件的名字
String fileInName = fileIn.getName();
//获取文件名字的后缀
//字符串以.切割 然后存放到String数组中
String[] fileLastName = fileInName.split("\\.");
//通过这种方式 保证了获取到的一定是文件的后缀
int length = fileLastName.length;
if (fileLastName[length-1].equals(FileLastName)){
flag = true;
}
return flag;
}

// public static void main(String[] args) {
// Filter filter = new Filter("jpg");
// filter.FileFilter(new File("E:\\get\\1.jpg"));
//
// }
}

解决程序健壮性问题

目标文件重名问题

在原程序中 目标文件重名后是会被重写的,这不符合实际应用中的情况,因此需要进行判断是否目标文件会重名

我给出的解决方案是:在增加一个filter来过滤是否文件重名

已经较初级得解决了文件重名问题 即判断是否重名,对重名的文件重新命名

加入的过滤器

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
package com.dwx.filter;

import java.io.File;

public class SameFileFilter {
//在实际的文件书写过程中 可能会存在
//实际是对目标文件进行遍历
//问题在于 这个目标文件是会一直改变的 不知道能否成功
public boolean SameFileFilter(File fileOut,File file) {
boolean flag = false;
for (File f : fileOut.listFiles()){
if (f.equals(file)){
//如果在类表中找到该文件 将flag改为true
flag = true;
}
}
return flag;
}

public static void main(String[] args) {
SameFileFilter fileFilter = new SameFileFilter();
boolean b = fileFilter.SameFileFilter(new File("E:/out"), new File("E:/out/1.jpg"));
System.out.println(b);
}
}

发生改变的程序

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
package com.dwx.getImage;

import com.dwx.filter.Filter;
import com.dwx.filter.SameFileFilter;

import java.io.*;
import java.util.Objects;

//这个类我们来测试一下从文件夹中得到文件,并指定输出到我们想到的位置
public class getImageDemo02 {
//这个方法已经实现了对文件的遍历
public void getImage(File fileIn, File fileOut,String fileLastName) {
//我们要知道 文件类型可能是文件,也可能是文件夹
//这里我们来判断是否是一个文件夹
//通过 fileIn.listFiles就能把一个文件夹转化成list
//通过递归来实现对整个文件夹的遍历
// System.out.println(fileIn.isDirectory());
// for (File f : fileIn.listFiles()){
// System.out.println(f);
// }
//对于文件遍历 若是文件夹 就在进入下一次 如果是文件 return
if (fileIn.isDirectory()) {
for (File fi : Objects.requireNonNull(fileIn.listFiles())) {
getImage(fi, fileOut,fileLastName);
}
}
//如果不是就直接返回
else {
Filter filter = new Filter(fileLastName);
if (filter.FileFilter(fileIn)) {
getImage getImage = new getImage();


//用目标文件夹+源文件名就组成了目标文件名(全路径)
File file = new File(fileOut + "\\" + fileIn.getName());

//插入一个过滤同名文件的过滤器
SameFileFilter sameFileFilter = new SameFileFilter();
//如果这个if成立 就说明有重名文件 就把文件名在加个(00)
if(sameFileFilter.SameFileFilter(fileOut, file)){
file = new File(fileOut+"\\"+"(same)"+fileIn.getName());
}
//如果条件不成立 文件名就不会发生改变
try {
getImage.MygetImage(fileIn, file);
} catch (IOException e) {
e.printStackTrace();
}
}
}

}
}


JAVA流程控制

用户交互Scanner类——>输入字符串

通过运用Scanner类,我们可以实现人机交互,通过scanner来获取用户输入的数据

基本语法

1
Scanner s = newScanner(System.in);

使用方法:我们一般通过Scanner类的next()和nextLine()方法获取输入的字符串,可以直接使用,亦可以通过判断语句结合hasNext()或hasNextLine()来判断是否有数据的输入

使用步奏

  1. 在main类中new Scanner (System.in),系统自动导入Scanner类
  2. 在刚输入的代码后通过Alt+Enter系统自动封装
  3. 在使用scanner后如果不再使用,一定通过scanner.close()将其关闭

scanner.next1

scanner.next2

我们可以看到,scanner.next可以直接使用,亦可异通过和判断语句结合使用

而在第二次输入的时候可以发现,输入的是hell0 world但输出的是hello,因此,这里引出next()使用的方法

next:

  • 一定要读取到有效字符后才可以结束输入
  • 对输入有效字符之前遇到空白,next()方法会自动去掉
  • 只有输入有效字符后才将其后面的输入的空白作为分隔符或者结束符
  • next()不能得到带空格的字符串

如果我们需要输入带空格的字符串时给怎么做呐

使用nextLine()

nextLine():

  • 以Enter作为结束符,也就是说nextLine方法返回输入回车之前的所有字符
  • 可以获取空白

Scanner输入数字类型

基本步奏和输入字符串时一样,只不过在调用next()时使用的是nextInt()和nextFloat()

java流程结构

顺序结构

顺序结构是java的基本结构,除非特别指明,否则会按照从上到下的顺序依次执行代码。

选择结构

if选择结构

if单选择结构

1
2
3
if(布尔表达式){
语句块;
}

和C语言中的if选择结构一样,当布尔值表达式的结果为True时,输出语句块,否则跳过语句块,执行if()后边的程序。

if双选择结构

1
2
3
4
5
if(布尔表达式){
语句块1
}else{
语句块2
}

当布尔表达式的结果为true时,输出语句块1;否则将执行语句块2。

if三选择结构

1
2
3
4
5
6
7
8
9
10
if(布尔表达式1){
语句块1
}else if(布尔表达式2){
语句块2

}else if(布尔表达式3){
语句块3
}else{
语句块4
}

编译器会从上到下依次读取布尔表达式,谁的表达式结果为true,则执行该表达式对应的语句块,执行结束后就会跳出该结构,即使下边的布尔表达式理论上也可以为真,也不会表达。

注意:在else-else if-else结构中,至少有一个else*语句,切else语句在结构的最后一句。如果某个else if检查语句为true,程序直接跳出结构,不会再继续执行,

switch选择结构

switch-case语句判断一个变量与一系类值中的某个值是否相等,每个值称为一个分支.

switch语句中的变量类型可以是

  • byte,short,int 或者char
  • String从java SE 7也可以使用
  • case标签必须为字符串常量或字面量

switch-case语句格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
switch(表达式){
case value:
<语句>;
break;
case value:
<语句>;
break;
case value:
<语句>;
break;
default: #可选可不选
<语句>;
}

当表达式与某个value相同时,执行其对应的语句,然后借助break跳出循环,不然就会继续向下执行,知道找到break或者default为止。

Java方法详解

什么是方法

这边我以System.out.println();为例

1
2
3
4
System.out.println();/*调用System类中的out对象中的println方法*/
/*类*//*对象*//*方法*/
//整体的使用方法的原理就是,调用类中的对象中的方法

Java方法的大致内容

Java方法是语句的集合,它们在一起执行一个功能

  • 方法是解决一类问题的步奏和有序组合
  • 方法包含于类或对象中
  • 方法在程序中被创建,在其他地方被调用

设计方法的原则

方法的本意是功能快,就是实现某个功能的语句块的集合。我们设计方法的时候应当保持方法的原子性,即一个方法只用于实现一个功能,这样有利于我们的后期拓展

方法的命名规则

方法的命名规则基本上和变量的命名规则相同,高级要求需要首字母小写的驼峰原则

自定义方法的实例

这里我会以add方法作为实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package method;//包名

public class method01 {// 类名
//main方法
public static void main(String[] args) {
int sum = add(1,2);
System.out.println(sum);



}
//我们自己定义的方法是写在类里边,方法外边的
//void 和C语言一样,表示没有返回值, int 有返回值
public static int add(int a,int b){
return a+b;

}

}

为了使自己定义的方法能够被合理的调用,我们使用publicstatic等修饰符来对方法进行修饰

方法的定义

java的方法类似于其它语言的函数,是一段用来完成特定功能的代码片段,一般情况下,定义一个方法包含如下语法:

方法一般包含一个方法头和一个方法ti

  • 修饰符:修饰符是可选的,可以根据自己对方法的要求选择合适的修饰符,修饰符的作用就是告诉编译器这个方法是用来作什么的
  • 返回值类型:方法可能会有返回值。returnValueType是方法返回值的数据类型。有些方法执行所需的操作不需要返回值,这时候returValueType是关键字void
  • 方法名:是方法的实际名称,方法名和参数表共同构成方法签名
  • 参数类型:参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序、参数个数、参数是可运的。方法可以不包括任何参数
    • 形式参数:在方法被调用时用于接收外界的输入数据
    • 实参:调用方法时实际传递给方法的数据
  • 方法体:方法体包含具体的语句,定义函数的功能

方法的格式为

1
2
3
4
5
6
修饰符  返回值类型   方法名(参数类型 参数){
..........
方法体
..........
return 返回值
}

方法调用

调用方法:对象名.方法名(实参列表)

注意:java只有按值传递

java支持两种调用方法的方式:

  • 对于有返回值的方法,使用方法就当做是一个数值

    1
    2
    int lagger = max(a,b);

  • 对于没有返回值的方法,一般调用是为了输出一段语句

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
package method;

import java.util.Scanner;

public class compare {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int a = 0;
int b = 0;
System.out.println("请输入两个整数:");

if(scanner.hasNextInt()){
a = scanner.nextInt();
}
if(scanner.hasNextInt()){
b = scanner.nextInt();
}
int max = max(a, b);
System.out.println(max);
}
public static int max(int a, int b){
if(a > b){
return a;
}
else if(a==b){
System.out.println("相等");
return 0; //这里的return 0说明return不仅可以返回值,亦可以作为方法结束符
}
else{
return b;
}


}
}

for循环

while循环

while循环格式如下:

1
2
3
while(表达式){
<语句块>
}

对于while循环必须注意一下几点:

  • 只要表达式的布尔值为true,循环就会一直持续下去
  • 但大多数情况下我们并不需要一直循环,也需要停止,就需要设计循环破坏条件
  • 一定要避免出现死循环

do-while循环

do-while循环格式如下:

1
2
3
4
do
{
<语句块>;
}while(表达式)

do-while和while一样,使用的方式也一样。

就是由于该程序把while移动到后边来,所以程序会先进行一次,再去判断表达式是否为true,是否继续执行

for循环

for循环的格式如下:

1
2
3
4
for(表达式1;判断式;表达式2)
{
语句块;
}

进入for循环,会先执行表达式1,其实是条件,然后进行判断,如果结果为真,进行执行语句块,然后进行表达式2,再次判断,就这样,一直到判断式为假为止。

括号中的(;;)是断不可以丢的。

其运用要点和C语言一样,不在过分赘述。

关键字break和continue

和C语言中break和continue关键字的作用一样

continue:结束本次循环,仍在循环结构中

break:结束整个循环,跳出循环结构

而且,两者只能结束一层的循环,如果要对多层循环进行操作需要多次使用

稀疏数组

稀疏数组

稀疏数组的使用范围

当一个数组中大部分元素为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
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
public class arry02 {
public static void main(String[] args) {
int [][] array1;
array1 = new int[11][11] ;
array1[1][2] = 1;
array1[2][3] = 2;
System.out.println("打印原始数组");
for (int [] ints :array1) {
for(int anInt : ints){
System.out.print(anInt+"\t");

}
System.out.println();

}
//转换为稀疏数组保存
//获取有效值的个数
int sum = 0;
for(int i = 0; i < 11; i++){
for(int j = 0; j < 11; j++){
if(array1[i][j] != 0){
sum++;
}
}
}
int [][] array2;
array2 = new int [sum+1][3];
array2[0][0] = 11;
array2[0][1] = 11;
array2[0][2] = sum;
int count = 0;
//遍历二维数组,将非0值定义在稀疏数组中
for (int i = 0; i < array1.length; i++) {
for (int j = 0; j < array1[i].length; j++) {

if (array1[i][j] != 0){

count++;
array2[count][0] = i;
array2[count][1] = j;
array2[count][2] = array1[i][j] ;


}

}

}
//稀疏数组的输出
System.out.println("稀疏数组的输出");
for (int i = 0; i < array2.length; i++) {
System.out.println(array2[i][0]+"\t"
+array2[i][1]+"\t"
+array2[i][2]+"\t");

}
//稀疏数组的还原
System.out.println("=======================================");
System.out.println("稀疏数组的还原");
//1.读取稀疏数组的值
int [][] array3;
//这是在还原,通过稀疏数组array2[0][0]代表还原后的行数,array2[0][1]代表还原后的列数
array3 = new int [array2[0][0]][array2[0][1]];
//2.给其中的元素还原值
for (int i = 1; i < array2.length; i++) {
array3[array2[i][0]][array2[i][1]] = array2[i][2];

}
//3.打印
for (int [] ints : array3) {
for (int anInt: ints) {
System.out.print(anInt+"\t");

}
System.out.println();


}





}

输出结果:

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
打印原始数组
0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0
0 0 0 2 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
稀疏数组的输出
11 11 2
1 2 1
2 3 2
=======================================
稀疏数组的还原
0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0
0 0 0 2 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0

Process finished with exit code 0

数组

数组的基本概念

所谓的数组就是若干个相同数据类型的元素按一定的顺序排列的集合。在java语言中,数组元素可以由基本数据类型的量组成,也可以由对象组成。

栈内存和堆内存

java语言把内存分为两种,栈内存和堆内存。

  • 堆内存:堆内存用来存放由new运算符创建的数组或对象,在堆中分配的内存,由java的垃圾回收器来自动管理。

  • 栈内存:在堆中创建一个数组或对象后,同时还在栈中定义了一个特殊的变量,在栈中的这个变量的取值等于数组或对象在堆内存中的首地址。

    数组的特点

  • 数组是相同数据类型元素的集合

  • 数组中的各元素是哟先后顺序的,它们在内存中按照这个先后顺序连续存放在一起

  • 数组元素用整个数组的名字和它自己在数字中的顺序位置来表示。

一维数组

一维数组是最简单的数组,其逻辑结构时线性表。使用一维数组需要经过定义初始化应用等过程

一维数组的定义

java一维数组的定义需要三个步奏:

  1. 声明数组
  2. 分配空间
  3. 创建数组元素并赋值

格式:

1
2
3
4
数据类型   数组名;
数组名 = new数据类型[个数];
/*============或者写为==============*/
数据类型[] 数组名 = new 数据类型[个数]

注意“[]”指明变量是一个数组类型变量,java语言可以将“[]”放在数组名前,也可以像C一样,把“[]”放在数组名后边。但与C语言不同,java在定义数组变量时,不为数组元素分配空间,因此“[]”中不用给出数组长度,但必须在为其分配过内存空间后才能使用

说明:数组用new运算符分配内存空间的同时,数组的每个元素都会自动赋一个默认的值:整数为0,实数为0.0,字符为‘\0’,boolean型为false,引用型为null。

多维数组

java语言中并没有真正的多维数组。所谓的多维数组,就是数组元素也是数组

二维数组

二维数组的声明方式与一维数组类似,内存的分配也一样是用new运算符。声明与分配内存的格式如下:

1
2
3
4
数据类型[][]数组名;
数组名 = new数据类型[行数][列数]
/*==================================================================*/
数据类型[][]数组名 = new 数据类型[列数][行数]

与C语言要求二维数组是一个矩阵不同,java语言的二维数组不一定是规则的矩阵

二维数组的定义

如果要创建一个数组,而且该二维数组还是不是规则的矩阵,则需要先建立高层维数

获得二维数组长度的方法

不仅仅是二维,对任意维度的数组若要获得其长度,只需在数组名后加.length属性即可;若要取得数组中某行元素的个数,则必须在数组名后加上下标,再加上.length

1
2
x.length;    //计算数组x的长度
x[0].length;//计算数组x第一行的长度

注意:与一维数组相同,用new运算符来为数组申请内存空间时,很容易在数组各维数的指定中出现错误,二维数组必须要求指定高层维数

注意:和一维数组一样,ava在定义数组变量时,不为数组元素分配空间,因此“[]”中不用给出数组长度,但必须在为其分配过内存空间后才能使用

字符串

字符串的定义

字符串就是一系列字符的序列。在java语言中字符串是用一对双引号(” “)括起来的字符序列

字符串的分类

字符串分为两大类:第一种:在创建后就不能对其进行修改了;第二种:在创建后依然可以对其进行修改

  • 对于不可以进行修改的字符串,在java语言中用String类
  • 对于可以进行修改的字符串,在java语言中用StringBuilder类

字符串常量的建立

  • 字符常量是用(’ ‘)括起来的单个字符
  • 字符串常量是用(“ ”)括起来的字符序列

字符串定义时的格式

第一种

1
2
3
4
String 变量名;
变量名 = new String("字符串");
"================================================================================="
String 变量名 = new String("字符串");

第二种

由于字符串是引用型变量,所以其存储方式与数组的储存方式基本相同

1
str = "hello world";

String类的常用方法

java语言使用String类方法的方法为

1
字符串变量名.方法名();
常用方法 功能说明
public int length() 返回字符串的长度
public boolean equals(Object anObject) 将给定字符串与当前字符串相比较,若两字符串相等,则返回true,否则返回false
public String substring(int beginIndex) 返回字符串中从beginIdex开始到字符串末尾的子串
public String substring(int beginIndex,int endIndex) 返回Index指定位置的字符
public char charAt(int idex) 返回index指定位置的字符
public int idexOf(String str) 返回str在字符串中第一次出现的位置
public int compareTo(String anotherString) 若调用该方法的字符串大于参数字符串,则返回大于0的值;若相等,则返回0;若小于,则返回小于0的数
public String replace(char oldChar,char newChar) 以newChar字符替换字符串中所有oldChar字符
public String trim()
常用方法 功能说明
public String toLowerCase() 将字符串中的所有字符都转换为小写字符
public String toUpperCase() 将字符串中的所有字符都转换为大写字符

类与对象

类(class)和对象(object)是面向对象程序设计方法中的最核心概念

类的基本概念

:是对某一类事物的描述,是抽象的、概念上的定义;

对象:是实际存在的属该类事物的具体个体,因而被称为实例

方法:封装在类中的函数,在java语言中函数被称为方法

定义类

定义类,实际上是定义类的属性与方法,在使用类之前,必需先定义它,然后才可利用定义的类来声明相应的变量,并创建对象。

类的一般结构:

1
2
3
4
5
6
7
8
9
10
11
[类修饰符] class 类名称
{
[修饰符] 数据类型 成员变量名称;
.....
[修饰符] 返回值的数据类型 方法名(参数1 ,参数2, ...., 参数n)
{
语句序列;
return [表达式];
}
..........
}

方括号[]中的修饰符是可选项,它是一组限定类,成员变量和成员方法是否可以被程序里的其他部分访问的调用的控制符。其中,类标识符可以分为公共访问控制符抽象类说明符最终类说明符缺省访问控制符四种。

修饰符 含义
public 将一个类声明为公共类,它可以被任何对象访问
abstract 将一个类声明为抽象类,没有实现方法,需要子类提供方法的实现,所以不能创建该类的实例
final 将一个类声明为最终类,即非继承类,表示它不能被其他类所继承
缺省 缺省修饰符时,则表示只有在相同包中的对象才能使用这样的类

一个类可以有多个修饰符,但abstract和final相互对立,所以不能同时应用在一个类的定义中

成员变量

/因为我自己有些C语言基础,所以在理解java语言元素时爱用C语言中的相似元素来类比/

成员变量就好像C语言中的全局变量

格式如下:

1
[修饰符] 变量类型 变量名[ = 初值]

成员变量的修饰符有访问控制符静态修饰符最终修饰符过渡修饰符易失修饰符

修饰符 含义
public 公共访问控制符。指定该变量为为公共的,它可以被任何对象的方法访问
private 私有访问控制符。指定该变量只允许知己的类的方法访问,其他任何类(包括子类)中的方法均不能访问此变量
protected 保护访问控制符。指定该变量只可以被它自己的类及其子类或同一包中的其他类访问
缺省 缺省访问控制符时,则表示在同一个包中的类可以访问此成员变量,而其他包中的类不能访问该成员变量
final 最终修饰符。指定此变量的值不能改变
static 静态修饰符。指定该变变量被所有对象共享,即所有的实例都可以使用该对象
transient 过度修饰符。指定该变量是一个系统保留、暂无特别作用的临时性变量
volatile 易失修饰符。指定该变量可以同时被几个线成控制和修改

修饰符的要求:除了访问控制修饰符有多个以外,其他的修饰符只有一个。一个成员变量可以被两个以上的修饰符同时修饰。

成员方法

声明方法的语法格式如下:

1
2
3
4
5
[修饰符] 返回值的数据类型 方法名(参数1,参数2,...,参数n)
{
语句序列;
return [表达式];
}

如果不需要传递参数到方法中,只需要将方法名后的圆括号写出即可,不必填入任何内容,另外,若方法没有返回值,则返回值的数据类型应该是void,且return语句可以省略。

修饰符 含义
public 公共访问控制符。指定该方法为公共的,它可以被任何对象的方法访问
private 私有访问控制符。指定该方法只允许自己类的方法访问,其他任何类(包括子类)中的方法均不能访问此方法
protected 保护访问控制符。指定该方法只可以被它的类及其子类或同一包中的其他类访问
缺省 缺省访问控制符时,则表示在同一个包中的类可以访问此成员方法,而其他包中的类不能访问该成员方法
final 最终修饰符。指定该方法不能被覆盖
static 静态修饰符。指定不需要实例化一个对象就可以调用的方法
abstract 抽象修饰符。指定该方法只声明方法头,而没有方法体,抽象方法需在子类中被实现
synchronized 同步修饰符。在多线程程序中,该修饰符用于对同步资源加锁,以防止其他线程访问,运行结束后解锁
native 本地修饰符。指定此方法的方法体是用其他语言(如C语言)在程序外编写的

成员变量与局部变量的区别

类额成员变量和方法中的局部变量,其区别和C语言中全局变量和局部变量的区别是一样的。

对象的建立与使用

一个对象的生命周期为:创建->使用->销毁

创建对象

创建步奏只需要两步:

  1. 声明指向“由类所创建的对象”的变量
  2. 利用new运算符创建新的对象,并指派给前面所创建的变量
1
2
Scanner scanner;
scanner = new Scanner;

对象的使用

创建对象后,就可以对对象的成员进行访问,通过对象来引用对象成员的格式:

对象名 . 对象成员

eg:

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
package way;
class Cylinder
{
double radius;
int height;
double pi = 3.14;
void area()
{
System.out.println("底面积="+ pi*radius*radius);
}
double volume()
{
return (pi *radius *radius)* height;
}
}

public class way01 {
public static void main(String[] args) {
Cylinder volu;
volu = new Cylinder();
volu.radius = 2.8;
volu.height = 5;
System.out.println("底圆半径 = "+volu.radius);
System.out.println("圆柱的高 = "+volu.height);
System.out.print("圆柱");
volu.area();
System.out.println("圆柱体积 = " +volu.volume());
}
}

eg2:

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
package way;

import java.util.Scanner;

class student
{
int age;
String name;
char sex;
long number;
void people()
{
System.out.print("学生姓名:%s 性别:%c 年龄:%d 学号:%d".formatted(name,sex,age,number));
}
}


public class way02 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
student std;
std = new student();
std.name ="dasd";
std.age = 19;
std.number = 202545131L;
std.sex = 'M';
std.people();





}
}

由上边的两个例子可以看成,在主方法main()内如果需要访问类的成员,是通过格式

对象名.成员名

进行的。

  • Copyrights © 2015-2023 dwx
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信