JAVA学习笔记

java 常用指令.

Scanner in = new Scanner(System.in); //初始化输入模块
System.out.println(); //输出指令
in.nextlnt(); //读下一个整数
in.next(); // read the input only till the space. It can’t read two words separated by space.
in.nextLine(); //reads input including space between the words (that is, it reads till the end of line \n).

java的 数字类型

基本同C.
但是float类型的数字后面要跟f,double类型的数字要跟d(或者省略).
比如: float price,num;
num = price * 1.2;
那么绝对会报错. cannot convert double to float.
因为1.2 默认是double.
应该这么写: num = price * 1.2f
则ok.
10 是整型.
10.0 是double型.
10.0f 是float 型.
在Java里推荐使用double型,而不是float.
使用float需要强制类型转换. 默认小数输入进去即可与double进行计算. 整数与浮点数运算后会自动变为浮点数.

break

一般break 都是只会跳出当前循环,但是如果在循环前打上标号(相当于给循环起了名字):
在循环前可以放一个标号来标识循环. break 后+ 标号 ,则会跳出标号的循环.
如;
QUEEN: //标识加冒号
for{
for{
for{
` break QUEEN;}}}
则会直接跳出最大那个循环.

数组

  1. <类型>[]<名字> = new<类型>[元素个数]
    如:
    int[] grades = new int[100];
    double[] averages = new double[20];
  2. 注意:
    元素个数必须是整数.
    元素个数必须给出.
    元素个数可以是变量.
    java的数组使用new创建后自动就是各项为0;
    也可以
    int[] qwasd ={85,5,2} 这样来初始化

3… 数组变量是数组的管理者,而并非数组本身.
数组必须创建出来后交给数组变量来管理.
数组变量之间的赋值是 管理权限的赋予.
数组变量之间的比较是判断是否管理同一个数组.

int[] a={1,2,3};
int[]b =a ;
b[0]++;
则a[0]会变为2.不再是1.
因为a和b本质上指向的是同一块地址.
如果需要重新创建一片区域,则必须使用遍历的方法,对原数组的内容进行拷贝.

for each循环
for(<类型> <变量> : <数组>)
{
}
此循环中,k会自动的从数组的第一个元素遍历到最后一个元素.类似于python中的for循环.

二维数组:
int[][]a = new int[5][6];
也可以初始化:
int [][]a = {
{1,2,3,4},
{1,5,8},
};
每行一个{},逗号分隔.
逗号可以存在. 省略表示补零.

字符串

创建字符串
String s = new String("<初始化的内容>");
也可以:
String s = “<初始化的内容>”;

字符串的比较:

== 比较的是两个字符串是否管理着同一块区域。
而equals( )函数则会比较两个字符串的内容是否相同.
如:s.equals§ 是比较 s和p两个字符串的内容是否相同.
而 s==p 是判断s和p是否管理着同一片区域.

字符串的其他函数.

String s = new String();
s.length() // 求字符串s的长度.
s.charAt() // 访问字符串中某个特定位置的字母 index的范围是从0到length-1 但是不能用for-each来遍历.
s.substring(n) //获取子串. 从第n位开始到末尾.
s.substring(b,e) //获取子串,从第b位到第e位 首包含 尾不包含
s.indexOf© // 获取c字符在s中的位置,若返回-1 则表示不存在
s.indexOf(c,n) //获取c字符在s中的位置,从n开始寻找. 若返回-1 则不存在.
s.indexOf(t) //获取字符串t在s 中的位置.
s.lastindexOf©
s.lastindexOf(c,n)
s.lastindexOf(t) //从尾部向首部 寻找位置(倒着来)
s.startsWith(t)
s.endsWith(t) //查询字符串s是否是以字符串t开头或结尾的
s.trim() //删除字符串两端的空格.
s.replace(c1,c2) //将字符串s中的c1全部替换为c2
s.toLowerCase //将字符串中的所有字母都变成小写
s.toUpperCase //将字符串中所有的字母都变成大写
所有字符串都是不可变的,所以以上所有操作都不可改变原来的字符串,而是新产生字符串.因为他们只是管理者.

switch case 中的case也可以使用字符串
case"this"
case"that"

Math类函数

Math.abs(n) 求n的绝对值.
Math.round(n) 四舍五入求n的整数值.
Math.random() 会产生一个0到1之间的随机数.
Math.pow(m,n) 求m的n次幂.m n可以为浮点数.

值传递

java函数中永远进行的只是值传递,而不是变量的传递.

		a=5;
		b=6;
		public static void swap(a,b)
		{
		int t;
		t=a;
		a=b;
		b=t;
		}

这个函数并不能实际交换ab的值,因为java函数只进行的值交换.
本地变量不会被默认初始化

对象与类

对象是实体,需要被创建,可以为我们做事情.
而类是规范,根据类的定义创建对象.
对象=属性+服务.
蛋图(数据是蛋黄,对数据的操作是蛋清.)
把数据和对数据的操作放在一起,称为封装.

this 指代的是当前操作的对象.在使用成员函数的时候,<对象名>.<成员函数>会用this这样一个内置的对象返回对象的id.
在一个成员函数中调用另一个成员函数不需要加this.他会自动以当前对象来执行.

成员变量的作用域是在类的各个函数域内.

未初始化的成员变量在new时会自动被赋予初始值0.
而未初始化的本地变量不行,会报错.
成员变量在初始化的时候可以直接赋值,也可以调用成员函数.

构造函数

  1. 如果有一个成员函数的名字和类的名字完全相同,则在创建这个类的每一个对象的时候都会自动调用这个函数. 这个函数称为构造函数.
    2.构造函数坚决不能有返回值. void类型也不可以.构造函数直接写<类名>+大括号就可以了.

函数重载(OverLoad)

一个类可以有多个构造函数.同个类中,函数名相同但是参数表不同的情况叫做函数重载.
如 VendingMachine(){}
VendingMachine(int price)
这两个构造函数就是重载的关系.编译器通过给的参数的不同选择使用不同的函数.
在一个构造函数中,还可以在首行通过this()来调用其他的构造函数,不过必须在第一行,也只能调用一次.

private

成员变量无特殊理由,一般都要声明为private类型.
private类型只有类的内部可以访问.
类的内部指类的成员函数与类的初始化.
private的边界是针对类的,而非针对对象的.所以两个同一类的不同的对象可以相互访问她的private.

public

public是指开放的访问属性.
任何人都可以调用public声明的函数.
如果一个函数或一个类前没有声明"public"或者"private",那么他就是"friendly"属性.
friendly属性的函数和类只能被在同一个包中的其他文件中调用.
如果对类进行public,那么这个类, 必须放在和他自己类名相同的编译单元里(即一个.java)文件.否则编译不会通过.
一个编译单元里只能有一个public 的类.

类变量

public static int step = 2;
如果一个类里面有被static修饰的变量(step),那么这个变量称为类变量.
类变量不同于其他的成员变量,成员变量是隶属于单独的对象,而类变量属于自己的类.
也就是说 只要对象属于这个类,那么这个step的值一定一样的. step这个类变量是类自带的,而不属于任何一个对象.
在这里插入图片描述

类函数

被static 修饰的函数称为类函数,类函数不属于某一个对象,它属于这个类.
类函数只能调用类变量.(静态方法只能访问静态变量).
因为你如果要访问其他的成员变量的时候,他找不到.

容器类

ArrayList notes = new ArrayList();
容器类有两个类型. ArrayList是类名,代表容器类.String是元素类型,代表这个容器内装的是String. 而notes是这个ArrayList 的对象的名字.

ArrayList 的成员函数:
<对象名>.add(); 增加一个对象进入容器中.
<对象名>.size(); 现在容器中有多少个对象.
<对象名>.get(); 获得对应下标处的文本.
<对象名>.add(int index; element) 往指定位置中加入元素.
<对象名>.remove(index) 删除指定位置的元素,返回被删除的元素.
<对象名>.toArray)(String[] a) 将容器中的字符串装入a中.

对象数组

对象数组中,每个元素都是对象的管理者,而非对象本身.
所以在没有初始化的时候,相当于对象数组中的管理者还没有管理任何东西.
这是不同于普通类型的数组的.
对象数组的FOR-EACH循环不同于普通数组的FOR-EACH循环
如对 int[] 数组. for-each循环中如果给每个遍历的k进行k++;是不会起到任何效果的.
但是对于一个string[]数组,对于每次遍历中的k执行操作,是会对相应index位置上的string起作用的.这是因为在令k = String[]时,相当于k也变成了管理者.

HashSet容器

HashSet也是一种对象容器.
它与ArrayList不同,HashSet是一个数学概念的上集合.
所以里面的元素不会重复(即使你输入了两次同一个内容)
元素也没有顺序,只会随机的读出所包含的元素.

String toString() 函数

我们在实测中发现,对于对象容器 ArrayList 还有HashSet ,可以直接
System.out.println(<某对象容器的名称>);
来输出对象容器中所包含的元素.
究其原因,是因为ArrayList和HashSet中都包含了一个成员函数String toString().
只要一个类中含有这样一个成员函数,必须名字就是’‘toString’’. 那么就可以直接println这个类的对象.

HashMap类型

HashMap类型称为hash表. 一般用于两种不同类型的变量进行对应.
初始化方法:
HashMap<<包裹类型>,<包裹类型>> <对象名> = new HashMap<<包裹类型>,包裹类型>();
注意:
<>内的两个数据类型分别代表了两个表中要装的数据类型.
这两个数据类型必须是包裹类型,而不是一个基本数据类型.(如int不能写为int,要写Integer).
HashMap中有许多内置函数.
常用的有:
<对象名>.put(key,value); 向表中添加元素.
<对象名>.get(key) 查询对应key的value值.
<对象名>.containsKey(key) 查询是否有key值对应的value.
<对象名>.keySet() 获得所有key的HashSet的容器集合.

还需要注意的是:
Hash表中同一个key值只能对应一个Value,所以:
先输入的key对应的value 会被后输入的同一个key的value所覆盖.

继承关系: 父类与子类

如果现在有两个类:DVD和CD 他们成员变量都有title,都有time等等相同的地方,那么代码的重复度会很高.这个时候需要引入父类.
我们假设有一个父类叫做item:
父类和子类之间的关系称为继承.继承指的是子类会继承父类的成员变量以及成员函数,在需要时自动调用之.
public class CD extends item. 表示CD继承item.
所以我们就可以创建一个父类item,将cd和dvd类中的重复的成员变量与成员函数集成到父类来.
若调用了某个成员变量或者成员函数,对于子类,一般步骤是先去查询父类的成员函数与成员变量,再查询子类的成员变量和成员函数.
class item{
private title}
那么这样可以吗?
答案是不行的.

父类的变量声明:protected

父类的变量声明如果用的是private.那么子类不能调用这个成员变量,会提示invisible.
所以我们应该用protected声明,用protected声明的成员变量可以被包内的其他类和子类调用.

super()函数与子类的构造.

我们知道子类的很多成员变量是声明在父类中的,那么在构造时,应该怎么做呢?
答案是 super()函数.
super(<数据类型>)函数的意思是: 去寻找父类的符合括号内数据类型的构造函数.
public class item{
public time;
public title = ok;
item(int t)
{
item.time = t;
}
而子类的构造函数应该写作:
cd(int t)
{
super(t);
}
在构造一个子类时: 执行顺序是:先初始化父类的成员变量,再执行super函数.再初始化子类的成员变量,最后执行子类的构造.
即使子类的构造函数不需要调用父类的构造函数,在程序执行时,不管你写没写super(),程序都会自动去执行super()即参数为空的一个父类的构造函数. 所以父类一定要有一个参数为空的构造函数,否则会报错.

父类成员变量与子类成员变量

子类若含有和父类同名的成员变量的话,在实际的存储区其实是会有两个同名成员不同id的成员变量的.
在子类中操作时,默认赋值的是子类的成员变量. 而对父类操作时,是对父类的成员变量操作.另一个都是隐藏状态.

多态

一个对象变量有两种态: 声明类型 和 动态类型.

动态绑定和静态绑定

在调用对象函数的时候,使用当前动态类型的成员函数称为动态绑定.
使用声明类型的成员函数称为静态绑定.
在JAVA中,都是动态绑定.
也就是说 一个父类的对象在使用一个具有覆盖关系的函数时,要看它的动态类型处于哪一个子类的状态.然后调用该子类的函数.

覆盖(overload)

父类和子类中存在着 函数名 和 参数表 均相同的函数.
这种函数称为覆盖函数.overload
具有覆盖类型的函数在调用时,遵循动态绑定原则.

造型

造型分为向上造型和向下造型.
向上造型是指 子类的对象被当做父类对象,调用给需要父类对象的函数或接口使用.
向下造型是指 父类的对象被当做子类对象,调用给需要子类对象的函数或接口使用.
通过对继承的学习,我们知道:

  1. 向上造型是始终安全的.
  2. 向下造型需要父类当前的动态类型确实是子类的时候,才可以向下造型.
  3. 造型并没有改变任何东西,它只是将一个类型的对象"看做"另一个类型的对象在使用.
  4. 造型的方法: 括号加造型的类名+ 变量名. 如(CD) item.

Object 类.

Java是一个单根系统. 也就是说所有的类其实都是object的子类.Object是一个Root.

toString() 函数

toString函数是一个可以将任何对象转换为String输出的函数.
在使用String时,必须对子类声明一个覆盖的toString()函数.
可以使用Source功能来构造overload的toString函数.
之后便可以直接把该类的对象当做string来输出.

equals()函数

equals()是一个判断两个同类型的对象是否相等的函数
可以通过构造具有覆盖关系的成员函数来实现.(source功能也可以帮助构造.)

耦合

  1. 在写代码的过程中,经常会遇到两个类有很多出口与代码相关.
  2. 这种类与类之间的关系称之为耦合.
  3. 耦合是一种不好的现象,他会降低代码的可扩展性. 理想的代码状态是低耦合状态. 所以我们说耦合越低越好,保持距离是形成良好代码的关键.

抽象

接口

接口是纯抽象类。
所有成员函数都是抽象函数。
所有变量都是public static final。
类用extends继承,接口用implements 实现。
在Java中不允许多继承,但是允许实现多个接口。
接口可以继承接口,但不能继承类,更不能实现接口。

面向接口的编程模式

设计程序时先定义接口。
任何需要在函数内传入传出的一定是接口,而不是某个特殊的类。

控制反转

JButton的ActionListener,回调函数都属于控制反转。
当对某类中某一事件关心时,可以预留出一个接口,在类中构造一个成员变量Listener,并编写一个注册函数。在需要对事件进行处理时,通过实现这个接口来覆写接口中预留出的函数,通过函数注册进去。调用时,系统会反过来调用你写的函数。
这便是控制反转,具体可以参考系统分析第一次作业。

MVC设计模式

MVC设计模式中:
M 指的是 model 数据模型。
V 指的是 view 可视界面。
C 指的是 control 控制。
MVC设计模式,指的是将 数据,界面,控制三者分离进行设计的一种思路。三个模块都十分单纯,只管自己的。尤其是V与C之间毫无干涉。 三个模块之间的交互通过接口来实现。
关系图

异常机制

异常是Java中的一种报错的方式。在程序运行中,可能出现异常,譬如内存泄漏等情况,这种时候就需要对异常进行处理。
对异常进行处理的方法是:try catch 具体操作如下:
try{
//可能产生异常的代码
}catch(Type id1)
{//处理type1类型的异常
}catch(Type id2)
{//处理type2 类型的异常
}

异常处理机制

拿到了异常后可以进行的操作:

  1. String getMessage();
  2. String toString();
  3. void printStackTrace(); // 追溯异常发生的地方以及它的调用过程。
  4. throw e //再度抛出,捕捉到后觉得处理不了,移交给上级进行处理。

抛出异常的函数

如果你调用一个声明抛出异常的函数,那么你必须:

  1. 把函数放在try块里,并用catch捕捉其所有的异常情况.
  2. 或者 声明自己会抛出无法处理的异常.

异常声明遇到继承关系

  1. 当覆盖一个函数时,子类不能声明抛出比父类更多的异常.
  2. 在子类的构造函数中,必须声明父类可能会出现的全部异常.

  1. 流是输入输出的方式.
  2. 流是一维单向的.

字节流

InputStream
OutputStream

文件流

FileInputStream
FileOutputStream
对文件做读写操作。 在实际操作中已经较少使用了。 只能写字节。

流过滤器

以一个介质流对象为基础层层构建过滤器流,最终形成的流对象能在数据的输入与输出过程中,逐层使用过滤器流的方法来读写数据。
如:
DataOutputStream out = new DataOutputStream(
new BufferedOutputStream(new FileOutputStream(“a.dat”)));

这样就实现了不止一个字节的读写。二进制文件

文本流

二进制数据使用InputStream 和 OutputStream。
文本数据采用Reader 和 Writer。
在流的基础上通过过滤器来建立流的输入和输出:
如:PrintWriter pw = new PrintWriter(
new BufferedWriter(
new OutputStreamWriter (
new FileOutputStream("abc.txt’ ))));

读入常常使用的是BufferedReader,通过readLine()来一行行读入文本。
实例如下:
翁恺老师源码
后面的那个While语句,是为了让他读到末尾时停下来。

汉字问题

在Java中,默认国标码读汉字是不存在问题的。但是当汉字使用UTF8等编码时,可能会存在乱码的问题。这是由于File流的问题所导致的。
我们可以通过以下方式处理。
在这里插入图片描述

流的选择

如何选择流

阻塞/非阻塞

在这里插入图片描述

对象串行化

我们如果想要把一个对象中的所有成员变量保存在一个文件中,以供存读。那么应该怎么办呢?
答案是对象串行化。
首先在构建类的时候,该类必须实现一个叫做Serializable的接口,也应该实现toString的方法。
类的声明
然后我们便可以用

可以使用这些方法来处理对象。

实例如下:
在这里插入图片描述
使用ObjectOutputStream 向外输出。
使用ObjectInputStream 读取内容。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值