Java学习日记


title: Java学习笔记
date: 2018-05-18 12:00:00
tags:

  • Java
  • 学习笔记

Perface

因为 Minecraft 接触到 Java,很想写 Minecraft 的插件/MOD,可惜今年寒假才算开始入门,到了现在大一下学期(18 年 5 月)断断续续地学,没有具体的学习安排所以没坚持下来,最近看了这篇文章Java 心得感觉又活过来了,就开始在这里更新学习日记吧做一个长久一点的规划,比如大二上学期要学会什么,下学期要学会什么

Day 1(#0518)

20180518

重读《Java 从入门到精通》,14 年购入,此书较实用不适合深入学习

因为上学期有 C 基础,快速略读了 1-4 章,漏读位操作符,需要时再补

晚上在知乎搜Java 项目时看到这篇文章Java 心得
这不就是我想成为的那种人吗

JavaWeb

每天 10 小时写代码...利用好时间

未接触但较为重要的数据结构 算法 数据库
接下来试着做个项目吧,虽然 API 都没怎么看过
啃书吧,不懂就看视频,可以去下个离线视频看


Day 2(#0519 8hrs)

通读第 5 章字符串 String 与第 6 章数组 Arrays ,早上 6 点尿憋醒又睡到 9 点...12 点出发,自习室 8 小时今天睡得比较多,白天都在学也不太困,大概就是晚起的好处...

昨天看了那篇文章后就打算啃书了,也可以坚持下来,看不懂的再去看视频吧~

第 5 章 字符串 String

主要讲了 String 字符串类的使用(java.lang包)

声明创建,连接字符串

String str = "Hello";    声明创建
String s = str + " " + str;    连接

获取字符串信息

str.length();    获取字符串长度
int size = str.indexOf("a");    查找字符串索引位置
str.charAt(index);    获取字符串索引位置的字符

字符串操作

字符串截取 | 去空格 | 替换 | 判断开头结尾 | 判断相等 | 比较 Unicode 顺序 | 转换大小写 | 分割

str.substring(0,3);    截取字符串
str.trim();    去除字符串空格
str.replace("a","B");    字符串替换
str.startsWith(" ");    判断是否字符串的开头/* boolean */
str.endsWith(" ");    判断是否字符串的结尾
str.equals(str2);    判断字符串是否相等
str.compareTo(str2);    比较Unicode值顺序

str.toLowerCase();    转换为小写字符串
str.toUpperCase();    转换为大写字符串

str.split(",");    分割字符串

格式化字符串

str.format();
日期时间格式化
import java.util.Date;
Date date = new Date();
String s = String.format("%tc",date);    参考日期|时间|组合|常规转换符表!

使用正则表达式判断格式正误

String RegEx = "\\p......"
if (str.matches(RegEx))
参考正则表达式写法

字符串生成器

通过 StringBuilder 类快速生成字符串,省时间高效率

StringBuilder builder = new StringBuilder();
append();  insert();  delete();  追加|插入|删除

小结

字符串的创建 | 连接方式 | 获取字符串信息 | 常用字符串操作格式化字符串 | 使用正则表达式 | 字符串生成器


第 6 章 数组 Arrays

数组创建及声明

数组是具有相同数据类型的一组数据的集合创建及声明 | 遍历数组 | Arrays 类的使用(填充|排序|复制|查询)
数组排序算法明天看:p

int[] arr = new int[5];
int[] arr = {1,2,3,4,5};
int[][] arr2 = {{1,2},{5,6}};

遍历数组


Arrays 类的使用

Arrays.fill(arr,8);    填充
Arrays.sort(arr);    排序
Arrays.copyOf(arr,5);    复制
int index = Arrays.binarySearch(arr,0,1,8);    数组查询

明天看数组排序算法第7章面向对象


Day 3 (#0520)

通读了数组排序算法,理解的算不上深刻
学习算法应该多读几遍代码再尝试自己写


数组|数组排序算法 (P114~P120)

冒泡排序|直接选择排序|反转排序

冒泡排序

基本思想是对比相邻的元素值,如果满足条件就交换值,把较小的元素移动到数组前面,反之把达的元素移动到数组后面(也就是交换两个元素的位置),这样较小的元素就像气泡一样从底部上升到顶部。

算法示例:冒泡算法由双层循环实现,外层循环控制排序轮数,一般为要排序的数组长度减一次(因为最后一次循环只剩下一个元素无需再对比了)内层循环主要用于对比数组中的每个临近元素的大小,以确定是否交换位置,对比和交换次数随着排序轮数而减少

public class BubbleSort {
    public static void main(String args[]) {
    //先创建一个乱序数组
    int[] array = {24,56,11,66,32,8};
    //创建冒泡排序类的对象
    BubbleSort sorter = new BubbleSort();
    //调用下面的排序方法
    sorter.sort(array);
    ...

直接选择排序

基本思想是将指定排序位置与其他数组元素分别相比,如果满足条件就交换元素值(不是交换相邻元素),而是把满足条件的元素与指定的排序位置交换,这样好的位置逐渐扩大,最后整个数组都成为已排序好的格式算法示例:每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序地放在已排好序的数列的最后,直到全部待排序的数据元素排完

public class SelectSort {...}

反转排序

就是把数组最后一个元素与第一个元素替换,倒数第二个元素与第二个元素替换,以此类推,直到所有数组元素反转替换反转排序是对数组两边的元素进行替换,所以只需要循环数组长度的半数次,如数组长度为 7,那么 for 只要循环 3 次

public class ReverseSort {...}

数据结构与算法是程序员求职路上的必经之路...
学习算法最好通读三四遍,真正理解了之后再尝试自己写


第 7 章 类和对象 Classes and Objects

https://docs.oracle.com/javase/tutorial/java/javaOO/index.html

面向对象设计实质上就是对现实世界的对象进行建模操作

对象 Object

通常对象划分为两个部分,静态部分动态部分
静态部分,顾名思义就是不能动的部分,这个部分被称为属性,任何对象都会具备其自身属性,如一个人的高矮胖瘦,而这个人可以说话、行走,这些事这个人具备的行为,也就是动态部分
在计算机世界中,面向对象程序设计的思想要以对象来思考问题,首先要将现实世界实体抽象为对象,然后考虑这个对象具备的行为(动态部分)

类 Class

类就是同一类事物的统称,如果将现实世界的一个事物抽象成对象,类就是这类对象的统称在 Java 语言中,类中对象的行为是以方法的形式定义的,对象的属性是以成员变量的形式定义的,而类包括对象的属性和方法

封装 Package

将对象的属性和行为封装起来,其载体就是类,类通常对客户隐藏其实现细节,这就是封装的思想

{...}

继承

继承思想可以缩短软件开发的时间,复用那些已经定义好的类,可以提高系统性能,减少系统在使用过程中出现错误得几率

{...}

多态

{...}

this 关键字

this关键字代表本类对象的引用

类的构造方法

构造方法是一个与类同名的方法,对象创建就是通过构造方法完成的每当类实例化一个对象时,类都会自动调用构造方法

构造方法没有返回值
构造方法的名称要与本类的名称相同

static 静态

被声明为 static 的变量、常量和方法被称为静态成员,静态成员属于类所有,区别于个别对象,可以在本类或其他类使用类名和.运算符调用静态成员,语法为:类名.静态类成员在静态方法中不可以使用this 关键字调用非静态方法

类的主方法

public static void main(String[] args) {...}

主方法是静态的,直接调用方法也必须是静态的,主方法没有返回值,性参为数组,其中 args[0]~args[n]分别代表程序的第一个参数到第 n 个参数,可使用 args.length 获取参数个数

对象

Test test = new Test();

对象被创建出来时,就是一个对象的引用,并在内存中为对象分配了存储空间每个对象都算相互独立的,在内存中占据独立的内存地址,并且每个对象都具有自己的生命周期,当一个对象的生命周期结束时,对象就变成垃圾,由 Java 虚拟机自带的垃圾回收机制处理,不能再被使用

public class CreateObject {
    public CreateObject() {
        System.out.println("创建对象");
    }
    public static void main(String args[]) {
        new CreateObject();
    }
}

在上述实例的主方法中使用 new 操作符创建对象创建对象的同时,将自动调用构造方法中的代码

访问对象的属性和行为

使用对象.类成员获取对象的属性和行为

对象的比较

使用==运算符与equals()方法前者为比较引用地址是否相等
后者为String类方法,比较内容

对象的销毁

每个对象都有生命周期,当对象的生命周期结束时,分配给给对象的内存地址将会被回收对象引用超过其作用范围,这个对象将被视为垃圾对象赋值为null

总结

本章学习了面向对象的概念 类的定义 成员方法 类的构造方法 主方法 对象的应用
在此基础上可以编写类 定义类成员 构造方法 主方法
类及类成员可以使用权限修饰符进行修饰,对象的创建 比较 销毁 十分重要

本章只点到了类和对象,仍需通过编码去深刻理解面向对象 OOP 的概念


第 8 章 包装类


第 9 章 数学类

鉴于此类属于 api 的范畴,先重点学面向对象的特性,这些内容可以以后需要时再补充


Day 4 (#0521)

上午英语课期中考试寫完试卷就来图书馆看书了,周一周二的课又多又无趣

今天看到了焦虑的话题,回想这几天,有了专一的学习目标(Java!)并且充分利用好了时间,完全没有以前那种焦虑的感觉了(以前是目标太分散,又不想玩又不想学,所以很焦虑)

今天学习面向对象的概念不太容易,是否应该边看代码边敲边思考


第 10 章 继承、多态与接口

本章为 Java 面向对象特性的学习,一下子不太好理解,需要多花点时间琢磨,多回来看看,写代码体验特性

继承 extend

在 Java 中使用extends关键字来标识两个类的继承关系

class Father {...}
class Son extends Father {...}

这里 Son 类继承了 Father 类(类名不重要)

super 关键字

super()语句调用父类的构造方法
super关键字调用父类的成员方法但子类没有权限调用父类中被修饰为privite的方法,只可调用publicprotected的成员方法

重写与重构

重写就是在子类中将父类的成员方法的名称保留,重写成员方法的实现内容,更改成员方法的存储权限,或是修改成员方法的返回值类型

当重写父类方法时,修改方法的修饰权限只能从小的范围到大的范围改变

重构就是子类与父类的成员方法返回值、方法名称、参数类型及个数完全相同唯一不同的是方法实现内容**

Object 类 所有类的爸爸

在 Java 中,所有的类都直接或间接继承了java.lang.Object
Object 类是比较特殊的类,它是所有类的父类,是 Java 类层中最高层类

由于所有的类都是 Object 类的子类,所以任何类都可以重写 Object 类中的方法

getClass()方法

是 Object 类定义的方法,它会返回对象执行时的 Class 实例,然后调用 getName()方法可以取得类的名称

getClass().getname();

可将 getClass()方法与 toString()方法联合使用

toString()方法

是将一个对象返回为字符串形式

equals()方法

==比较的是两个对象的引用是否相等,而equals()比较两个对象的实际内容

书中此处有个实例,与上文反道而行之,不太懂

对象类型的转换 向上转型|向下转型

暂未理解

使用instanceof判断对象类型

可使用instanceof操作符判断是否一个类实现了某个借口,也可判断一个实例对象是否属于一个类

myobject instanceof ExampleClass

表达式返回值为布尔boolean值,true & false,可搭配if等语句使用...

方法的重载

为了让方法名相同而形参不同的构造方法存在,必须用到方法重载

方法的重载就是在同一个类中允许同时存在一个以上的同名方法,只要这些方法的参数个数或类型不同即可

不定长参数方法:

public static int add(int...a) {...}
返回值 方法名(参数数据类型...参数名称)

不定长参数a就是一个数组,可搭配循环语句使用

多态

hmmm...not easy to understand

抽象类 abstract

在解决实际问题时,一般将父类定义为抽象类,需要使用这个父类进行继承与多态处理,继承树越中越是在上方的类越抽象

在Java中设置抽象类不可实例化对象,但它的子类可以

抽象类的语法

public abstract class TestClass{
    abstract void testAbstarct();   //定义抽象类方法
}

抽象类没有方法体,这个方法本身没有意义,除非它被重写,而承载这个抽象方法的抽象类必须被继承,抽象类除了被继承之外没有任何意义

只要类中有一个抽象方法,此类就被标记为抽象类

抽象类被继承后需要实现其中所有的抽象方法,也就是保证相同的方法名称、参数列表和相同返回值类型创建出非抽象方法,当然也可以是抽象方法

接口 interface

接口是抽象类的延伸,可以将它看作是纯粹的抽象类,接口中的所有方法都没有方法体

public interface drawInterface{
    void draw();    //接口内的方法省略abstract抽象关键字
}

一个类实现一个接口可以使用implements关键字

class PXSbianxing extends Sbianxing implements drawInterface{...}
实现

在接口中定义的方法必须被定义为public或abstract形式,在接口中定义的任何字段都是static和final的

Java中不允许多重继承,但使用接口就可以,可以将所有需要继承的接口放置在implements关键字后并逗号隔开


总结

了解继承与多态的机制,掌握重载类型转换,学会使用接口与抽象类

依然不好懂


Day 5 (#0522)

面向对象的特性确实不易懂,囫囵吞枣地学或者找点视频看,通读几遍概念,过段时间再回来回顾一下应该就可以了


第 11 章 类的高级特性

Java类包 package

Java中提供了一种管理类文件的机制,就是类包
为了防止类名冲突,将两个同名类放置在不同的包中

java.util.Date date = new java.util.Date();
package 包名    //定义包
import 包名     //导入包

导入静态成员并使用

import static java.lang.Math.max;
import static java.lang.System.out;

class ImportTest {
    public static void main(String args[]) {
    //直接使用静态成员
        out.println("1和4的较大值为" + max(1, 4))
    }
}

final 变量

final关键字可用于变量声明,设置后不可改变该变量的值,通常final定义的变量为常量
final关键字定义的变量必须在声明时赋值

final double PI = 3.14;     //常量名 通常大写

定义为final的数据无论是常量、对象引用还是数组,在主函数中都不可以被改变

final定义的对象引用只能指向一个对象,不可再指向其他对象,但对象本身的值是可以改变的
使用static final关键字使内存区域的值恒定不变

声明final变量不赋值的,称为空白final,可在构造方法中赋值
构造方法就是和类名相同的方法

final 方法

定义为final的方法不能被重写

但是父类被定义为private final的方法似乎可以被子类覆盖

class Parents {
    private final void doit() {
        System.out.println("First doit");
    }

    final void doit2() {
        System.out.println("First doit2");
    }

    public void doit3() {
        System.out.println("First doit3");
    }
}

class Sub extends Parents {
    public final void doit() {
        System.out.println("Sub doit");
    }
    //final void doit2() {}     //final方法不能覆盖
    public void doit3() {
        System.out.println("Sub doit3");
    }
}

public class Finals {
    public static void main(String[] args) {
        Sub s = new Sub();
        s.doit();
        Parents p = s;  //向上转型
        //p.doit();     //不能调用private方法
        p.doit2();
        p.doit3();
    }
}

可见final方法不能被覆盖,向上转型操作后,对象p只能调用正常覆盖的doit3()方法,却不能调用doit()方法,可见子类中的doit()方法并不是正常覆盖,而是生成一个新的方法

final 类

定义为final的类不能被继承

如果将某个类设置为final形式,则类中的所有方法都被隐式设置为final形式

但是final类中的成员变量可以被定义为final或非final形式

//final class
final class FinalClass {
    int a = 3;
    void doit() {
    }

    public static void main(String[] args) {
        FinalClass finalClass = new FinalClass();
        finalClass.a++;
        System.out.println(finalClass.a);
    }
}

内部类

如果在类中再定义一个类,称为内部类

成员内部类

在内部类中可以随意使用外部类的成员方法以及成员变量,尽管成员修饰为private

内部类的实例一定要绑定在外部类的实例上,如果从外部类中初始化一个内部类对象,那么内部类对象就会绑定在外部类对象上。

内部类初始化方式与其他类初始化方式相同,都是用new关键字。

//innerClass
class OuterClass {
    innerClass in = new innerClass();

    public void out() {
        in.inf();
    }

    class innerClass {
        innerClass() {
        }

        public void inf() {
        }

        int y = 0;
    }

    public innerClass doit() {
//        y = 4;
        in.y = 4;
        return new innerClass();
    }

    public static void main(String[] args) {
        OuterClass out = new OuterClass();

        OuterClass.innerClass in = out.doit();
        OuterClass.innerClass in2 = out.new innerClass();
    }
}

内部类可以访问它的外部类成员,但内部类成员只有在内部类的范围内是可知的,不能被外部类使用。

在实例化内部类对象时,不能在new操作符之前使用外部类名称实例化对象,而是应该使用外部类的对象来创建其内部类的对象。

内部类向上转型为接口

{...}

使用this关键字获取内部类与外部类的引用
如果在外部类中定义的成员变量与内部类中哦的成员变量名相同,可以使用this关键字

public class TheSameName {
    private int x;      
    private class Inner {   //Inner内部类
        private int x = 9;
        public void doit(int_x) {
            x++;                    //^^^
            this.x++;               //Inner class
            TheSameName.this.x++;   //TheSameName class
        }
    }
}

局部内部类

内部类不仅可以在类中进行定义,也可以在类的局部位置定义,如在类的方法或任意的作用域中均可以定义内部类

如果需要在方法体中使用局部变量,该局部变量需要被设置为fina类型

方法中定义的内部类只能访问方法中final类型的局部变量,这是因为在方法中定义的局部变量相当于一个常量,它的生命周期超出方法运行的生命周期,由于该局部变量被设置为final,所以不能在内部类中改变该局部变量的值

匿名内部类

class OuterClass4 {
    public OutInterface2 doit() {
        return new OuterInterface2() {  //声明匿名内部类
            private int i = 0;
            
            public int getValue() {
                return i;
            }
        };          //匿名内部类定义结束分号
    }
}
匿名内部类语法如下
return new ClassName() {
    //...
};

匿名内部类使用默认构造方法来生成OutInterface2对象
定义结束后要加;分号,代表创建OutInterface2引用表达式

静态内部类

在内部类前添加static就变为静态内部类了

一个静态内部类中可以声明static成员,但是在非静态内部类中不可声明静态成员

静态内部类的特点:

不可使用外部类的非静态成员(所以静态内部类较为少见)

创建静态内部类的对象,不需要其外部类的对象

内部类的继承

内部类也可以继承但比继承普通类复杂,需设置专门的语法来完成

//extend InClass
class ClassA {
    class ClassB {
        
    }
}

class OutClass extends ClassA.ClassB {  //继承内部类ClassB
    public OutClass(ClassA a) {
        a.super();
    }
}

在某个类继承内部类时,必须给予这个类一个带参数的构造方法,并且该构造方法的参数为需要继承内部类的外部类的引用,同时在构造方法体中使用a.super()语句,这样才为继承提供了必要的对象引用

总结

本章学习了Java语言的包 final关键字 内部类

学会如何导入包 定义final变量 final方法 final类 内部类的用法

OOP不算很好懂。


你可能感兴趣的:(Java学习日记)