java笔记

第一周总结

系统变量,基本语法,循环控制

★看到有相似的“排比式”代码,要想办法用循环,数组,归纳为方法来尽量缩短代码的量。

 

 

★一种较常用的for格式

for (int i = 1 ; i < 10 ; i++ )

{

for (int j = 1 ; j <= i  ; j++ )

{

                

                }

           }

用于打印输出九九乘法表,判断是否为素数,

 

★如何获取用户输入的数字串的长度?

 

可以用:先将得到的数字串格式画成String类型的,然后调用String的length方法,得到长度

 

关于int转String的三种方法:

1》String.valueOf(i)

2》 Integer.toString(i)

3》 i+""

 

比如int a = 214;

String s1 = a + “”;

s1.length;  //此处得到a的长度。

 

★关于如何依次取出一个字符串类型的数字的每个位数的写法

for(int  q = 0;q < num.length();q ++)

{

a=((int)(c/Math.pow(10, q)%10));

}

 

★关于一个方法 a ,里面包含三个参数,方法b要调用到方法a,此时应在方法b中的形参列表也写好三个参数,以此来对应相应的方法a中的需要的三个参数的要求。

 

★常用的三个math方法

Math.pow(a, b);    返回a的b次方

Math.sqrt(a);       开根号a,返回一个double型的值

Math.max(a, b);    返回a和b之中最大的值。利用连续的两次取大函数,来确定三个数中间哪个数最大,如:Math.max(Math.max(c, a), b);

★ 关于获取屏幕的输入的文字,然后传入程序中的流程:

 

Scanner 的三个经常用的方法,nextInt(),nextLine(),next()

 

Scanner sc = new Scanner(System.in); 注意要写出红字部分,经常忘

System.out.pirintln(“请输入文字:”);

Int num = sc.nextInt();

此时num就保存了从屏幕上输入的一个int型值。

nextInt()方法会读取下一个int型标志的token.但是焦点不会移动到下一行,仍然处在这一行上。当使用nextLine()方法时会读取改行剩余的所有的内容,包括换行符,然后把焦点移动到下一行的开头。

而next()方法是以换行或者空格符为分界线接收下一个String类型变量。

 

★ 关于老师给的”开关“的结构思想,可以先在循环体或者执行体框架之前设置一个boolean变量,设置为true。在循环体或者执行体中运行时,如果符合相关条件,可以更改此boolean的值,此时可以结束当前次的循环,并可以在循环体或者执行体内根据此值来输出想要的结果,在整个循环体即将结束时,要记得重置此boolean变量,将其还原为初值设置的状态。

 

★ 关于随机数:

最简单的随机数产生:通过Math.random() 来产生一个【0.0,1.0)的随机double数值。可以利用这个返回函数来改造出想要符合具体要求的随机数产生函数。

比如要产生1~100的:(int)(Math.random()*100) + 1;

要产生任意数到任意数之间的:

(int)num1+(int)(Math.random()*(num2-num1));

上式中的num1是第一个任意数,num2是第二个任意数,利用的是产生的随机数转化为比例值,然后乘以两数之差,然后加上第一个数当级数,从而达到产生产生任意数到任意数之间的随机数的效果。

 

★ 访问控制符们

 

 

同一个类

同一个包

子类

所有类

private

*

 

 

 

default

*

*

 

 

protected

*

*

*

 

public

*

*

*

*

 

1

面向对象初步,方法,封装

★ 可以将自己常用的小函数写成一个Tools集,每个方法可以设置成static修饰的。

用的时候可以直接导包调用。

如:产生随机数,返回输入值(int型,String型等)。

 

★ 参数传递最好不要超过四个。

★ java中最先加载的三个部分的先后顺序:

Static 静态初始化块→初始化块→构造方法。

 

★ 关于this:代表当前这个对象,即是当前对象的4字节地址。

作用:传递到方法里,帮助方法确定具体要调用哪个对象。

一个类下的方法的相互调用,也是通过this来传递地址的。即它们前面都默认有一个   this.  的标记。

 

★ 一个程序有好的架构是及其重要的,直接影响到了程序员的工作量,所以架构师的工资完爆程序员,个人感觉很公平。

 

★ toString方法就是直接输出对象时,要打印的方法,也就是相当于程序的介绍方法,根据不同的需求来改写这个方法,以达到描述对象的目的。

 

★ 有参的构造器后面,一定要跟着写一个无参的构造器,养成习惯,因为系统不会再给你那个默认的无参数构造器了。

 

★ 封装:关于给私有属性写get和set方法,可以在这两个方法中根据不同的要求来做手脚:比如set中加入信息过滤。

快速生成get和set 方法: 鼠标移动到类中,右键→source→generate Getters

And Setters...选中你喜欢的成员变量,来一发默认的封装方法吧

 

★ 所谓“黑社会原则”,哈哈。

 

★ 一 加载类 二 初始化static 三 堆中开辟空间来初始化对象和成员变量

这就说明了static修饰的东西为何不能调用非static修饰的变量或方法,因为static先于非static出现于内存中,所以“现在的不能调用将来的”

 

 

 

 

 

★ 一个著名异常: nullpointerException 空指针异常,具体情况就是拿一个空的引用变量来访问或者调用任何方法或者属性,应该去检查相应行中,所给的引用变量是否为Null。

 

★ java中方法参数传递的是值传递,即是拷贝一份给之,原来的属性值并没有发生变化。比如一个对象A来了,方法拷贝一份给A,B来了,方法再拷贝一份给B。

 

★ 构造方法的主要作用就是干初始化的,要先给成员变量开空间,才能用构造方法进行初始化,重写的构造器是为了迎合不同的需求。

 

★ 成员变量如果和局部变量重名,对于方法来说,总是把这个变量看成是离他最近的那个变量,即局部变量。

 

★ 遇到new,必然在堆里开空间。

 

 

★ 关于字符串,因为其为String类下的一个对象,因此在堆中的String类型的变量名也是一个引用变量,它保存的是一个地址,指向的是串池中的具体字符串。

相同的字符串在串池中的地址是相同的,即如果定义了三个String变量,他们都是abcde的话,其地址是一样的。

 

★ equals比较的是内容,看两个对象是否相同,有时候需要根据自己的需求重写的。

==是比较对象地址,是整形的比较。

★ 在自动补全中:charAt(int index)  char -String

                   ↑      ↑        ↑     ↑

                方法名  参数列表 返回值 这个方法所在的类名

★ 方法重载与返回值无关!仅看方法名(一样),参数列表(类型,个数,顺序不一样)

★关于static:它的作用是将类的成员变成类相关。

第三周总结

包装类、继承、多态、抽象、接口、内部类、异常

 

★千万不要在循环中改变集合的长度!可以通过设置开关的方法来实现增删的功能。

 

★ instanceof 判断左边的变量是否是右边的类型,或者左边的类是否是右边的子类。

★ NumberFormatException 数字格式异常:转型代码有错误,或者是输入的数字类型混入了别的类型。

 

★ 何时用private?类中不需要向外界透露的,自己用于内部的运算的。内部的成员变量和方法,只要是不需要和不能像外界暴露,都可以用private来修饰。

使用private来增强代码的可识别性。

 

★ 继承:

关键字 Extends 表示的是 is - a 的关系,在java中,两类中相同性较大的时候,可以考虑继承。 

继承中的父类想要被继承的成员变量用protected 修饰。

在子类中调用父类的构造器super(),父类的方法super().父类方法

重写父类的方法:方法名,参数列表,返回类型要完全一致。

加载子类时,该子类的一个直接父类和所有的间接父类也会被一并加载(包括Object)。

在new子类的时候,先调用父类的构造器,再调用子类的构造器。

所以父类若没有无参数构造器,子类必须用super()来满足父类。

★ this()和super()不能同时出现!!

 

 

★ 关于包装类:将基本类型放入包装类中,将其变成一个对象。

比如:  Integer a = new Integer(10); 

之后就可以调用变量a来使用Integer的各种方法,比如获取长度,获取HashCode值,valueof之类的方法。

包装类在内存中的运行大概是这样的:

 

★ 关于自动拆装箱

      Integer a =new  Integer(10);

int b = a.intValue(); //拆箱

int f = Integer.parseInt("12345");//可以直接使用Integer的 方法。

 

Integer i = 10;//自动装箱

int e = i;//自动拆箱

可以显示的拆装箱,也可以直接对Integer的引用变量进行赋值,系统会自动将上述的 i 变量包装成 Integer 对象,在要使用 i 变量对e变量进行赋值时,系统相当于使用了 i.intValue() 将i的值进行拆箱。

 

★ 多态:

引用变量被什么类型所修饰,决定了能调用什么类型的方法,拥有谁的成员变量。

所谓多态,就是编译时使用父类的类型,运行时细化到具体子类。

用父类的引用变量来创建子类的对象。

这样对子类的调用更灵活,省去了类型判断,向下转型,可以完成对”未来“的编码,忽略不必要的细节,也规范了调用方法(即只能调用父类中出现的方法)。

 

★ 继承中初始化时构造器的调用情况

 

★ 什么情况下父类可以调用子类的方法?

①要有多态

②子类必须重写父类的方法

调用子类的成员变量呢?  

向下转型,但也仅限于访问非private 修饰的子类成员变量

 

★ 关于TDD测试驱动式:先写测试代码,再根据错误的提示来一步步补全功能。

 

★ 什么是java的垃圾回收机制?

是java虚拟机提供的能力,用于在空闲的时间以不定时的方式动态回收无任何引用所指向的对象占据的内存空间。

上色的字是关键,必须有。

 

★ java程序员几乎不用关心内存的控制和释放情况。

 

 

★ 抽象类的那些事事儿:

Abstract 避免了子类设计的随意性。

由关键字 abstract 修饰的类即是抽象类,不允许被实例化(new)。

抽象类里面可以包含普通方法和抽象方法。

抽象方法里面没有隐藏的this!

 

如果一个类继承了抽象类,然后这个类并没有全部实现抽象类中的抽象方法,那么这个类也只能是抽象类,等待着下一个子类将其实现。

 

抽象方法,无方法体,必须被子类重写,不能执行,调用不到,仅可调用被重写后实例化的同名方法。

抽象类只能被继承使用,因为它中可能有抽象方法。

抽象类中的抽象方法的访问控制权限应该小于等于实现抽象方法的类的访问控制权限。

 

抽象类一定要有构造器,符合子类的创建对象的规则。

必须有子类

不可以用final修饰。

 

在继承时,abstract类的所有抽象方法都被实现的时候,就可以被调用,也就是说被实例化,此时内存中有Object类,abstract类,实现类三个对象。(被实例化)

 

 

★ 一个抽象类的进化形态,接口

一个抽象类里全是抽象方法的话,可以将其写成接口 interface

写法:用interface来代替class 即可

 

interface SwitchableDevice

{

boolean isOn();//返回一个是否打开开关的boolean值的方法。

void change();//改变开关状态的方法。

}

 

★ 接口的特性:

接口中的方法没有方法体(即花括号)

接口不能被实例化,就是来让子类实现的 implements

 

接口中的方法默认是:public abstract型

接口中的成员变量是默认:public static final 修饰,所以他们必须是常量。

常量的命名规则:所以字母都大写,不同的单词用下划线来链接

如:BEIJING_SXT_JOB_CLASS_NUMBER

 

和抽象类类似的是,接口的实现类必须实现接口里面的所有抽象方法,如果没有,那么这个类也得是abstract修饰。

 

接口可以多继承接口,更贴切的来说是不同的接口可以相互继承来扩展自己。

[访问控制符] interface 接口名 extends interface1,interface2,,interface3.....

 

一个类可以实现多个接口。

Class a implements interface1,inteface2,interface3,....

 

★ 引用变量最好用接口类型!方便按规则办事,防止子类冒出自己的不入流方法

 

 

 

★ 内部类:当你定义一个类,它不具备通用性时。可以将其定义为内部类

 

内部类可以访问外部类的private成员

使用语法 : 外部类名.this.外部类private成员

内部类的成员变量的使用跟一般类的使用没什么区别:this.成员变量

内部类的方法中的局部变量,直接用变量名,跟一般方法的局部变量的使用没区别。

 

在外部类以外的地方创建非静态内部类的实例必须使用外部类的实例和new来调用非静态内部类的构造器:

 OuterClass.InnerClass inner = new OuterClass().new InnerClass();

 

而static修饰的内部类属于外部类本身,故new 的时候可以省去一个new关键字:

OuterClass.StaticInnerClass ast = new OuterClass.StaticInnerClass();

 

★ 内部类的class文件名字的形式:外部类名$内部类名.class

★ 匿名内部类:

适用于那种只需要实现一次的类。

语法: new 实现接口() | 父类的构造器(实参列表)

       {

             //匿名类的类体部分

       }

例子:

      // 调用test方法的时候,要传入一个Product参数

// 此时要使用匿名内部类,以传入其匿名实现类的实例

ta.test(new Product()

{

public String getName()

{

return "格力空调";

}

public double getPrice()

{

return 6600.5;

}

}

);

Stringkamo = newString("mldn");创建了几个String类的实例对象?

New出来的算一个,括号里面加双引号的算是一个匿名内部类!

 

★ 异常:

一般的异常是直接交给虚拟机处理的,而虚拟机处理的方式是直接清空栈,结束掉整个方法,这样是很不和谐的,所以要使用自己捕捉异常的方法,来保证程序出现异常的时候能处理异常,然后继续执行之后的程序。

 

就是把可能出错的程序放入try块中,程序可能产生各种错误,然后在Catch块中捕获,并作出反应。

做出反应的情况有处理这个异常或者不处理,不处理就用throw关键字来抛出这个异常,但是这个方法必须声明它抛出了一个异常。

在别的方法来调用这个抛出异常的方法时,也得做出选择:是解决掉这个异常还是继续抛出。

 

Throw表示抛出异常,throws表示方法后有异常出现。

 

非Runtime异常的都是Exception异常,即编译时异常

 

★ 异常发生的try块中,如果第N行出现了异常,那么这行之后的所有try块内的语句都得不到机会执行了,所以要有一个finally块来保证程序的平衡性,用于将某些必须执行的语句来执行,Finally块中的总会执行。

关于这个有一个题目:

package day_15;

 

public class Demo {

public int tettetst() {

int a = 5;

try {

 

return ++a;

} finally {

a += 3;

}

}

 

public static void main(String[] args) {

Demo d = new Demo();

System.out.println(d.tettetst());

}

}

 

会打印多少呢?  6

因为遇到return关键字,就必须进行返回数值,计算完分号之前的东西之后返回,这个方法就结束了。Finally里面的东西会不会执行呢,总会,但是并不会对return值进行改变,属于无用功。

就像在你的回合最后一张牌下了个叫嚣的中士,给已经攻击过的烈焰小鬼拍了+2攻击力,烈焰小鬼确实在回合结束之前攻击力是5,但是有毛用呢。

 

★ 关于catch块的摆放姿势:网眼小的在下面,Exception,越往上网眼越松。即捕捉的异常范围越小。否则如果上来就是个Exception的异常,那么下面的异常都得不到执行了,程序会直接报错。

 

 

 

 

第四周总结

数组,递归,File对象,java中的可变参数,枚举类型,集合,

★ String(byte[] bytes,Charset charset)

前面写要打碎重组的数组,后面写编码规则,例如UTF-8之类。

或者是这样:

//String的构造器,将数组char类型的数组a打散,按照给定的初始和结束下标,组成一个字符串

String str = new String( a , 0,a.length);

 

通过使用指定的 charset 解码指定的 byte 数组,构造一个新的 String。新 String 的长度是字符集的函数,因此可能不等于 byte 数组的长度。 

此方法总是使用此字符集的默认替代字符串替代错误输入和不可映射字符序列。如果需要对解码过程进行更多控制,则应该使用 CharsetDecoder 类。

 

★ ArrayOutOfBoundsException   数组越界异常,下标小于零或者大于等于了数组长度(a.length) 。

★ 一关于Object的equals方法,如果你不给它重写的话,默认的方法是返回false的,所以你需要按照自己的标准来规定equals的重写与否。

快捷方法: 右键→source→Generater hashcode and equals

 

★ 数组的定义方法,老忘呢:

int[] a = new int[5];

int[] b = { 1, 12, 1, 2, 5, 24, 63, 3, 1 };

char[] e = new char[24];

 

int intB[3][2] = { { 1, 2 }, { 2, 3 }, { 4, 5 } };  

//因为动态初始化数组的时候必须要有系统来赋默认的初值。上面的是动态+静态,不伦不类

 

所以要这样写:int intA[][] = { { 1, 2 }, { 2, 3 }, { 3, 4, 5 } };

int[][] doubleArray = new int[3][3];

 

★ 数组的工具类:Arrays   注意是有这个s!

★ 数组排序是用Arrays里面的工具类有sort方法(快速排序),或者自己写方法:冒泡法、选择排序法、插入排序法。

 

★数组内的元素是保持添加顺序的。

 

 

★ 一个Date类和时间格式化:

             //获取当前时间

Date date  =new Date();

long temp = date.getTime();

//按照自己想格式化的习惯格式化系统时间,

SimpleDateFormat sf = new SimpleDateFormat("yyyy年MM-dd  HH:mm:ss  E");

String str = sf.format(date);

System.out.println(str);

知道格式就好

★ 关于File类:

在java语言中File对象标示磁盘中的文件或者是文件夹

             String str = "E:\\f";

File file = new File(str);

// 用createNewFile方法来在E的目录下创建一个名字为f的文件(注意不是文件夹)

System.out.println(file.createNewFile());

 

File fe = new File("E:\\ff\\cc\\dd");

// 相对路径转绝对路径。

String path = fe.getAbsolutePath();

System.out.println(path);

File f = fe.getAbsoluteFile();

// String getName()

// 返回由此抽象路径名表示的文件或目录的名称。

System.out.println(fe.getName());

System.out.println(f.getParent());

 

 

 

 

 

★ 关于Stringbuffer和Sringbuilder

都是可变的字符序列,其下的增加字符串的长度,删除指定字符以及插入方法比一般的用String方法复制更加节省内存和提高性能,所以要拼接字符串或者对字符串有大量操作的时候,要使用Sringbuilder以及Stringbuffer。

它在底层就是一个初始长度为16的char数组,在加入的长度超过这个数组长度时,将数组的长度直接乘2来构筑新数组继续存放。

 

推荐使用Sringbuilder因为它虽然不执行同步(即说明它是不安全的),但是快。

 

★ 一个递归的写法

先想递归边界条件,然后把这个条件用if或者while括好。

下面再写递归体。即在一个方法中再次调用自己。

递归的底层执行流程:

以如下程序为例

package day_18;

public class DiGuiSystemOut {

int i = 0;

 

public void diguiSyso(int i) {

if (i == 5)

return;

i++;

//将第十行和第九行互换有完全不同的效果

diguiSyso(i);

System.out.println(i);

}

 

public static void main(String[] args) {

DiGuiSystemOut de = new DiGuiSystemOut();

de.diguiSyso(0);

}

}

底层执行情况:

 

 

显然这样写的输出结果就是:

 

 

★ 参数列表可变的写法:public void method(Object ...args)

一个参数列表里面只能有一个可变的参数。

如果方法中除了有可变参数以外,还有其他参数,那么切记,可变参数的位置必须要出现在参数列表的最后的位置。

★ 枚举类型:

枚举类型是在jdk1.5以后才有的。是jdk1.5的新特性。

枚举类型起始就是一个常量类的替代。它默认是public static final修饰

他可以作用在switch里(jdk1.5新特性)。

枚举类是可以遍历的,可以去除所有常量。

for(类型 变量:枚举对象.values()){

     

}

★ 容器!

由Collection标准制定下的List和Set接口,以及独立于其之外的Map

 

List接口:链式结构,因此存入的数据可以保证添加顺序,并且允许重复元素。

其下的实现类有

ArrayList:   特点 读快改慢    线程不安全,内存利用率差。

首先它在底层是用数组实现的,当使用不带参数的构造方法生成ArrayList对象时,实际上会在底层生成一个长度为10Object类型数组, 如果增加的元素个数超过了10个,那么ArrayList底层会新生成一个数组,长度为原数组的1.5倍 +1,然后将原数组的内容复制到新数组当中,并且后续增加的内容都会放到新数组当中。当新数组无法容纳增加的元素时,重复该过程。

对于ArrayList元素的删除操作,需要将被删除元素的后续元素向前移动,价格比较高。

LinkedList 底层采用双向链表实现  改快读慢

 Vector 块链:很古老的东西了,已经不怎么用,

块链是有一块一块的小的数据块链接而成,如同火车车厢,一块如果满了就开启另一块,因此就有点浪费资源,但是随机访问的速度快

 

★ 当执行插入或者删除操作时,采用LinkedList比较好。

 

★ 当执行搜索操作时,采用ArrayList比较好。

 

Set接口:没有顺序,不存放重复数据。

其下的实现类:

HashSet:散列技术,因为是散列存储层数据,所以没有遍历,没有索引

关于不存放重复数据,hashset是先比较Hashcode,在用equals作比较

因此在定义对象的时候,先把equals和hashcode右键resource建好,没坏处。

 

 

Treeset:有排序功能的容器,因此用这个容器的类要自己先实现CompareTo或者比较器(更优先)

★ 关于集合排序的写法:

有两种:第一种是自身类实现comparable接口,重写它下面的CompareTo方法来决定比较排序,但是比较有局限性,毕竟重写的方法只能规定一种排序规则

 

另一种方法是新建一个专门用来比较的比较器类,实现接口comparator 重写compare方法。这样写可以拿自身和外来元素做比较,对于按照不同需求排序的情况,显然这样的排序更加适合。

 

 

★ 一个

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。