本篇包括:数据类型、代码风格与运算符、流程控制语句、集合、面向对象的编程、枚举和异常处理、IO操作、字符串操作与数学运算

1.数据类型

1.1 常用数据类型

数据类型类型范围长度(byte)默认值
byte整形-2^7~2^7(-128~127)10
short整形-2^15~2^12(-32768~32767)20
int整形-2^31~2^31(-2,147,483,648~2,147,483,647)40
long整形-2^63~2^6380l
float浮点型-3.4*10^38~3.4*10^3840.0f
double浮点型-1.7*10^308~1.7*10^30880.0
boolean布尔型true/false1false
char字符型u0000~uffff2必须初始化
Object引用类型引用类型,长度可变-必须初始化,可赋值为null
String引用类型引用类型,长度可变-必须初始化,可赋值为null,初始化后默认值为空串""

注意:

 1. 所有浮点类型均存在精度丢失,不可存储精确数值或者相比较。若要进行精确数值的计算,考虑**java.math.BigDecimal**。

1.2 类型转换

1.2.1 隐式转换

  1. 同种类型的数据类型(如同为整形、同为浮点型)长度短的数据类型可以隐式转换为长度长的数据类型。
  2. 整形与浮点型相转换时,长度相等或较短的整形可以隐式转换为长度较长的浮点型数据类型。但是浮点类型不可隐式转换为整形。
  3. 字符类型可以隐式转换为数值类型,反过来不行。
  4. 所有其他数据类型不能隐式转换为boolean,若要进行判断,需要给出判断条件。

1.2.2 显式转换

强制类型转换

常用于长度较短的数据类型转换为长度较长的数据类型,会有精度丢失现象。

int i = 100;
short s = (int)i;

包装类构造函数转换

被包装类包装的数据类型可以进行更多快捷操作,如果考虑后期使用方便,也可以使用这种转换方式。

float f1=100.00f;
Float F1=new Float(f1);
double d1=F1.doubleValue();//F1.doubleValue()为Float类的返回double值型的方法

其他数据类型转换为字符串

//被包装类包装过的数据类型可以调用其toString()方法
Float f = new Float('0.1');
System.out.println(f.toString());
//当然,直接隐式转换是最常用的方法
int i =10;
System.out.println(i);

字符串转换为其它数据类型

一般使用包装类中的静态方法“parse类型名(字符串)”来进行转换。

int i = Integer.parseInt("10");
double d = Double.parseDouble("99.9");

1.3 进制表示

使用不同的前缀来区分进制。

System.out.println(100);//十进制
System.out.println(0b100);//二进制           
System.out.println(0100);//八进制           
System.out.println(0x100);//十六进制 

2.代码风格与运算符

2.1 代码风格

  1. 类名使用pascal命名规则
  2. 方法名、参数名、成员变量、局部变量使用camel命名规则
  3. 常量命名全部大写,单词间用下划线隔开
  4. 包名统一使用小写,点分隔符之间有且仅有一个自然语义的英语单词。

详细→(https://www.cnblogs.com/scholar-hwg/p/12093084.html)[https://www.cnblogs.com/scholar-hwg/p/12093084.html]

2.2 注释

普通注释方式通用,下面介绍文档注释。

文档注释以/**开始,以/*结束,文档注释可以使用javadoc工具生成文档。

/**
* 计算指定目录中特定后缀名的文件数量
* @param path 目标目录
* @param suffix 要计算的文件后缀名
* @return 文件总数
*/
public int getFileCount(String path,String suffix)
{
    //实现方式略
}

文档注释参数见→(https://www.runoob.com/java/java-documentation.html)[https://www.runoob.com/java/java-documentation.html]

2.3 运算符

优先级由高到低:

运算符分类结合顺序运算符
分隔符左结合. [] ( ) ; ,
一元运算符右结合! ++ -- - ~
算术运算符移位运算符左结合* / % + - << >> >>>
关系运算符左结合< > <= >= instanceof(Java 特有) = = !=
逻辑运算符左结合! && ¦¦ ~ & ¦ ^
三目运算符右结合布尔表达式?表达式1:表达式2
赋值运算符右结合= = /= %= += -= <<= >>= >>>= &= = \=

3. 流程控制语句

3.1 分支语句

  1. switch后的表达式只能是byte,short,int,char,枚举(>=JDK5),字符串(>=JDK7)

3.2 循环语句

3.2.1 带标签的for/break嵌套循环

public class GotoDemo {
    public static void main(String[] args) {
        label: for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 8; j++) {
                System.out.println(j);
                if (j % 2 != 0) {
                    break label;
                }
            }
        }
    }
}

3.2.2 增强型for语句

类似C#的foreach

void forTest(int[] list)
{
    for(int i:list)
    {
        System.out.println(i);
    }
}

4. 集合

4.1 数组Array

声明

java具有灵活的数组声明机制,以下四种方式均可声明三维数组a[][][]:

int a[][][];
int[] a[][];
int[][] a[];
int[][][] a;

初始化

可以对数组动态初始化,下面两个例子分别表示直接静态初始化与后期动态初始化的数组结构:

int b[][];
//直接初始化
b=new int[3][4];
/* b:
    ○○○○
    ○○○○
    ○○○○
*/

//动态初始化
int c[][];
c=new int[3][];
c[0]=new int[1];
c[1]=new int[3];
c[2]=new int[2];
/* c:
    ○
    ○○○
    ○○
*/

java也支持使用数值直接初始化数组,这样就简化了分别初始化与赋值的步骤:

int[][] d={{1,2},{5,6},{8,9}};

4.2 有序列表List

java的List列表是一个接口,该接口定义了有序列表的诸多需实现的方法。使用时一般使用其实现类ArrayList,如:

ArrayList<String> strList = new ArrayList<String>();
ArrayList<Integer> intList = new ArrayList<Integer>();
//泛型不可传入基本数据类型,若要使用基本数据类型,请传入其包装类(如上)

strList.add("string item1");
strList.add("string item2");
System.out.println(strList.get(1))//out:string item1

4.3 无序集合Set

Set集合同样是一个接口,使用时一般使用其实现类HashSet:

HashSet<String> strSet = new HashSet<String>();
HashSet<Integer> intSet = new HashSet<Integer>();

strSet.add("string item1");
strSet.add("string item2");
for(String item :strSet)
{
    System.out.println(item);
}
/*out:
    string item2
    string item1
*/

列表List与集合Set的异同:

列表List集合Set
添加元素add方法add方法
获取元素get方法传入索引、迭代仅可迭代
元素重复性接受重复元素,传入重复元素时为其分配新索引不接受重复元素,传入重复元素时丢弃该元素
元素顺序元素顺序是插入顺序元素顺序根据具体实现方法而定,比如HashSet使用散列码来制定元素顺序

4.4 字典Map

其实java有Dict类,但是已经废弃。新的Map接口使用了与其他集合相同的接口形式定义字典,保证了集合的一致性。在日常使用中常用其实现类HashMap

HashMap<Integer,String> strMap=new HashMap<Integer,String>();
strMap.put(1,"map item 1");
strMap.put(2,"map item 2");

System.out.println(strMap.get(1));//out:map item 1

for(int key :strMap.keySet())
{
    System.out.println(key);
}
/* out:
    1
    2
*/

for(String value :strMap.values())
{
    System.out.println(value);
}
/* out:
    map item 1
    map item 2
*/

5. 面向对象的编程

5.1 封装

5.1.1 可访问性

类/成员类型privatepackageProtectedPublic
类内
包内
子类
无关系类

5.1.1 访问器

java没有像C#的属性那样固定实现访问器的方式,而是通过命名来区分访问器。一般来说,将要修饰的全局变量私有化,然后对外公布一组以get和set开头的函数就可以实现访问器。

5.2 继承

5.2.1 概念

java的继承写法为在类名后接extends+父类的方式。

  • 子类继承父类的非私有(private)方法和属性
  • 子类可拥有自己的方法和属性,也可以重写父类的方法和属性(多态)
  • 子类的构造方法将自动调用父类的无参构造方法,如需调用父类的有参构造方法,使用super关键字。
  • 一个子类只能继承自一个父类,但是一个父类可以被多个子类继承,子类也可以多重继承。
  • 如果不允许类继承,可以使用final关键字修饰类

5.2.2 抽象类

抽象类指示该类不能被实例化只能被继承。抽象类中可以添加抽象方法,抽象方法没有被实现,它等待它的子类将其实现。

抽象类与抽象方法使用abstract关键字修饰。

public abstract class Employee
{
   private String name;
   private String address;
   private int number;
   
   public abstract double computePay();
   
   //其余代码
}

5.2.3 接口

接口可以看作是抽象类又被高度抽象的结果,其只能包括未实现的方法和静态变量或常量。一个类可以实现多个接口,但只能派生自一个父类。接口也可以继承自其他接口。

实现接口时,使用implements关键字。

//定义接口
public interface NameOfInterface
{
   //任何类型 final, static 字段
   //抽象方法
}

//定义接口并继承自两个已知接口
public interface Interface3 extends Interface1, Interface2
{
   //任何类型 final, static 字段
   //抽象方法
}

//实现接口
public class ImplementClass implements Interface
{
    //需实现接口Interface定义的方法
}

//混合继承父类与实现接口
public class program extends Test implements ITest1,ITest2
{
    //实现ITest1与ITest2的方法
}

5.3 多态

5.3.1 方法重载与重写

重载指的一个类中可以存在多个方法名相同的函数,但是它们的形参必须不同。

重写指的是在子类中修改继承自父类的方法。

注意Java不支持重写运算符和索引器

如果不想让方法在子类被重写,可以使用final关键字来修饰方法。

5.3.2 子类的多态

当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。

class Father
{
    public void say()
    {
        System.out.println("father say");
    }
    
    public void fatherSay()
    {
        System.out.println("method from father");
    }
}

class Son extends Father
{
    public void say()
    {
        System.out.println("son say");
    }
    
    public void sonSay()
    {
        System.out.println("method from son");
    }
}

对于如上两个类,main函数及运行结果如下所示:

Father test=new Son();
test.say();//out:son say
test.fatherSay();//out:method from father
//test.sonSay()无法被直接调用
((Son)test).sonSay();//out:method from son

可见使用父类声明却用子类构造方法得出的对象不能使用子类独有的方法,若要使用需要进行强制类型转换,但是父类子类同有的方法会优先调用子类的方法。

以上方式可以提供多种灵活用法,比如定义一个Father数组,然后将其中对象使用不同Son类实例化,这样在遍历数组调用对象方法时,会调用到不同子类中重写的方法。这种用法称作协变

5.4 泛型

5.4.1 概念

泛型有泛型类、泛型接口和泛型方法,它们可以先实现内部逻辑后确定类型。实现方式分别如下:

//定义泛型类
//此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型
//在实例化泛型类时,必须指定T的具体类型
public class Generic<T>{ 
    //key这个成员变量的类型为T,T的类型由外部指定  
    private T key;

    public Generic(T key) { //泛型构造方法形参key的类型也为T,T的类型由外部指定
        this.key = key;
    }

    public T getKey(){ //泛型方法getKey的返回值类型为T,T的类型由外部指定
        return key;
    }
}

//定义一个泛型接口
public interface Generator<T> {
    public T next();
}

//定义一个泛型方法
public <T> void printMsg( T... args){
    for(T t : args){
        Log.d("泛型测试","t is " + t);
    }
}

//定义静态泛型方法
public class StaticGenerator<T> {
    ....
    ....
    /**
     * 如果在类中定义使用泛型的静态方法,需要添加额外的泛型声明(将这个方法定义成泛型方法)
     * 即使静态方法要使用泛型类中已经声明过的泛型也不可以。
     * 如:public static void show(T t){..},此时编译器会提示错误信息:
          "StaticGenerator cannot be refrenced from static context"
     */
    public static <T> void show(T t){

    }
}

5.4.2 泛型约束

有时我们不想让泛型传入任意类型,或者想使用某种类型作为父类的共有方法,这时就需要进行泛型约束。

泛型约束使用extends

5.5 静态代码

在类中使用static关键字修饰的代码块称为静态代码,它会在类实例化为对象时调用,并且先于构造函数调用。它一般用来修饰类中所有对象共同需要初始化的内容。而构造函数是调用哪个构造函数就初始化成该类的哪种对象。

5.6 类嵌套

5.6.1 外部类与内部类相互调用

  1. 内部类可以直接访问外部类的成员,包括私有成员
  2. 外部类若要访问内部类成员必须创建对象
class Outer{
    private int num =10;

    class Inner{
        public void show(){
            System.out.println(num);
        }
    }
    
    public void method(){
        //找不到符号
//        show();   //使用类内部的东西,必须用对象调用
        
        Inner i = new Inner();
        i.show();
    }
}

5.6.2 其他类访问内部类

实例化:外部类名.内部类名 对象名 = new 外部类构造函数.new 内部类构造函数 ;

public class InnerClassDemo3 {
   public static void main(String[] args) {
//       需求:我要访问Inner类show()方法
//       Inner i = new Inner();       //要经过Outer的同意
//       i.show();
       
       
//     格式:  外部类名.内部类名    对象名   =  外部类对象.内部类对象 ;
       Outer.Inner oi = new Outer().new Inner();
       oi.show();
    }
}

6. 枚举和异常处理

try with resource

7. IO操作

8. 字符串操作与数学运算

8.1 字符串查找

String提供了两种查找字符串的方法,即indexOf与lastIndexOf方法。

1、indexOf(String s)

该方法用于返回参数字符串s在指定字符串中首次出现的索引位置,当调用字符串的indexOf()方法时,会从当前字符串的开始位置搜索s的位置;如果没有检索到字符串s,该方法返回-1

1 String str ="We are students";
2 int size = str.indexOf("a"); // 变量size的值是3

2、lastIndexOf(String str)

该方法用于返回字符串最后一次出现的索引位置。当调用字符串的lastIndexOf()方法时,会从当前字符串的开始位置检索参数字符串str,并将最后一次出现str的索引位置返回。如果没有检索到字符串str,该方法返回-1.

如果lastIndexOf方法中的参数是空字符串"" ,,则返回的结果与length方法的返回结果相同。

8.2 获取指定索引位置的字符

使用charAt()方法可将指定索引处的字符返回。

1 String str = "hello word";
2 char mychar =  str.charAt(5);  // mychar的结果是w

8.3 获取子字符串

通过String类的substring()方法可对字符串进行截取。这些方法的共同点就是都利用字符串的下标进行截取,且应明确字符串下标是从0开始的。在字符串中空格占用一个索引位置。

1、substring(int beginIndex)

该方法返回的是从指定的索引位置开始截取知道该字符串结尾的子串。

1 String str = "Hello word";
2 String substr = str.substring(3); //获取字符串,此时substr值为lo word

2、substring(int beginIndex, int endIndex)

beginIndex : 开始截取子字符串的索引位置

endIndex:子字符串在整个字符串中的结束位置

1 String str = "Hello word";
2 String substr = str.substring(0,3); //substr的值为hel

8.4 去除空格

trim()方法返回字符串的副本,忽略前导空格和尾部空格。

8.5 字符串替换

replace()方法可实现将指定的字符或字符串替换成新的字符或字符串

oldChar:要替换的字符或字符串

newChar:用于替换原来字符串的内容

如果要替换的字符oldChar在字符串中重复出现多次,replace()方法会将所有oldChar全部替换成newChar。需要注意的是,要替换的字符oldChar的大小写要与原字符串中字符的大小写保持一致。

1 String str= "address";
2 String newstr = str.replace("a", "A");// newstr的值为Address

8.6 判断字符串的开始与结尾

startsWith()方法与endsWith()方法分别用于判断字符串是否以指定的内容开始或结束。这两个方法的返回值都为boolean类型。

1、startsWith(String prefix)

该方法用于判断当前字符串对象的前缀是否是参数指定的字符串。

2、endsWith(String suffix)

该方法用于判断当前字符串是否以给定的子字符串结束

8.7 判断字符串是否相等

1、equals(String otherstr)

如果两个字符串具有相同的字符和长度,则使用equals()方法比较时,返回true。同时equals()方法比较时区分大小写。

2、equalsIgnoreCase(String otherstr)

equalsIgnoreCase()方法与equals()类型,不过在比较时忽略了大小写。

8.8 按字典顺序比较两个字符串

compareTo()方法为按字典顺序比较两个字符串,该比较基于字符串中各个字符的Unicode值,按字典顺序将此String对象表示的字符序列与参数字符串所表示的字符序列进行比较。如果按字典顺序此String对象位于参数字符串之前,则比较结果为一个负整数;如果按字典顺序此String对象位于参数字符串之后,则比较结果为一个正整数;如果这两个字符串相等,则结果为0.

1 str.compareTo(String otherstr);

8.9 字母大小写转换

字符串的toLowerCase()方法可将字符串中的所有字符从大写字母改写为小写字母,而tuUpperCase()方法可将字符串中的小写字母改写为大写字母。

1 str.toLowerCase();
2 str.toUpperCase();

8.10 字符串分割

使用split()方法可以使字符串按指定的分隔字符或字符串对内容进行分割,并将分割后的结果存放在字符数组中。

1 str.split(String sign);

sign为分割字符串的分割符,也可以使用正则表达式。

没有统一的对字符串进行分割的符号,如果想定义多个分割符,可使用符号“|”。例如,“,|=”表示分割符分别为“,”和“=”。

1 str.split(String sign, in limit);

该方法可根据给定的分割符对字符串进行拆分,并限定拆分的次数。

标签: Java

添加新评论