------java基础开发文档
一、基本的介绍
1:java的三大体系:
☛java ME micro edition 微型版本
☛java SE standard edition 标板
☛java EE enterprise edition· 企业版本
2:&&就是短路与,||短路或,&,|,!关系运算符
3:通过JVM来实现跨平台的开发,原理图如下所示:
二、变量
1:八大基本的类型范围(2的字节位数次方),还有互相之间的
Float foo=0x123;这个是对的
Float foo=43e1表示可以43e1表示双精度430.0
Float foo=-1;都可以
☛求1234每个数字:第一位(a/1000)和最后一位(a%10)都有规律,从右边往左数
☛注意这个+号的应用,正数放在字符串的前面会先运算之后再使用+号链接
☛无穷大:infinity: 0.0是可以作为除数的位要取反加一,最高位是
3:位运算基本技巧,正数原反补都不用变,负数最高符号位,注意最高位在最前面哦
☛总结一下:计算机最终都是以补码的形式存放
◆注意:+=是自动处理(也就是自动转换)的
◆pushd:可以直接切换到,crtl+shift
◆b=a+b-(a=b),这个也可以进行交换两个数据的交换
- 条件运算符
☛注意:else if()这个满足第一个条件就不会进入第二个条件,而是直接的跳出
☛使用三木运算符进行求最大值
max=(num1>num2?num1:num2)>num3?(num1>num2?num1:num2):num3;
- Debug:F6单步调试,F8调到一个断点,F5进入方法
★拓展知识:GC垃圾回收机制
- 定义数组:数组的长度是属性:length
//定义数组:
/*数组的特质:
1:数据值类型必须是一样的
2:数据是连续的,索引方便查找
3:元素就是指数组中的每一个数据
4:下标都是通过某个具
5:可以存基本的数据类型,引用数据类型
静态数组:类型[] varName={...静态数组};
String[] name={"小高","阿春","杨妮"};
静态数组一步完成,不能换行赋值int[] arr={2,3};
动态数组:
数据类型[] varName=new 数据类型[数据的长度];
double[] d=new double[20];
数据类型[] varName=new 数据类型[]{数据...};//这里不能添加长度
int[] array=new int[]{4,1,42,-11,4,0,12};
- 排序:
1:冒泡排序及原理以及三种常见的数据交换方式
int[] arr=new int[]{8,23,2,1,23,1,344,12};
for (int i = 0; i < arr.length-1; i++) {
for (int j = 0; j < arr.length-i-1; j++) {
if(arr[j]>arr[j+1]){
//定义临时变量进行数据的交换
// int temp=arr[j];
// arr[j]=arr[j+1];
// arr[j+1]=temp;
//一个表达式就可以完成数据交换
//arr[j+1]=arr[j]+arr[j+1]-(arr[j]=arr[j+1]);
//亦或方式
arr[j]=arr[j]^arr[j+1];
arr[j+1]=arr[j]^arr[j+1];
arr[j]=arr[j]^arr[j+1];
}
}
}
2:选择排序:
int[] array=new int[]{8,23,2,1,23,1,344,12};
for (int i = 0; i < array.length-1; i++) {
//j:1,2,3,4=i+1;//这里不需要-1
for (int j = i+1; j < array.length; j++) {
if(array[i]>array[j]){
array[j]=array[i]+array[j]-(array[i]=array[j]);
}
}
}
3:插入排序:
☛插入从第1开始 i=1
- 查找:
1:折半查找
2:二分法查找
public static int binarySerach(int arr[],int num) {
//1:线性查找,就是按照顺序一个一个的查找
//2:二分查找
int max=arr.length-1;
int min=0;//都是从min=0
int mid=(min+max)/2;
while(arr[mid]!=num){
if(num>arr[mid]){
min=mid+1;
}else{
max=mid-1;
}
if(min>=max){
System.out.println("不存在次数");
return -1;//这个用来终止整个方法
//如果变成了break就会执行下面的代码
}
mid=(min+max)/2;
}
return mid;
}
- 数组定义:第二阶段
1:定义一维数组
int[] arr1={2,3,3,3};//静态数组赋值默认就知道长度
int[] arr2=new int[3];//动态数组必须定义长度
int[] arr3=new int[]{2,3,4,4};//动态数组的另外一种数组
//特定:静态默认赋值就知道长度,所以不用赋值长度
//动态数组赋值必须指明长度,另外一种是不需要的
2:定义二位数组:
Int[][] arr=new int[a][]:a表示二维数组的长度,所以一定要声明长度
//int[] a=new int[4]{1,2,3,4};//这样也是不可以的
//因为我们的这个长度和后面的数据个数是相等的
//静态数组:这个是静态的因为长度已经固定
//千万不要无论为这是动态的数组
//静态赋值长度不能够写上去,否编译报错
//这个长度都是看的出来的
int[][] arr=new int[][]{{1,2},{3,4}};
//动态数组:默认值是0
int[][] arr2=new int[2][];//整体固定了长度
int[][] arr3=new int[3][2];//全部固定了长度
//这样是不行的
//int[][] arr4=new int[][3];//X 这样报错
arr3[0]=new int[]{2,3};//要这样赋值就不能够指定长度
arr2[0]=new int[2];//这样就不能{..}这样赋值
3:数组中特别注意我们的这个问题
//特别注意:给二维数组赋值一定要注意
int[][] arr=new int[2][2]; //2,5,1,3
//这里会报出NullPointerException异常
//因为没有初始化一维数组
//arr[0][0]=1;
//arr[0][1]=1;
//arr[1][0]=1;
//arr[1][1]=1;
//静态赋值
arr[0]=new int[]{1,3};//静态赋值长度默认就知道
//动态赋值
arr[0]=new int[2];
arr[0][0]=1;
arr[0][1]=2;
arr[1]=new int[2];
arr[1][0]=3;
arr[1][1]=5;
System.out.println(Arrays.toString(arr[1]));
三、类和对象:
☛属性和方法都是属于对象的,不是属于类的
☛方法定义:四类,返回值和参数列表的有无
1:方法签名包括:方法名字和({参数列表})两部分
四、构造函数
★★参数列表不同包括:个数不同、类型不同和顺序不同。
仅仅参数变量名称不同是不可以的。
跟成员方法一样,构造方法也可以重载。
声明为final的方法不能被重载。
声明为static的方法不能被重载,但是能够被再次声明。
五、方法的重载和构造
方法覆盖的原则:
覆盖方法的返回类型、方法名称、参数列表必须与原方法的相同。
覆盖方法不能比原方法访问性差(即访问权限不允许缩小)。
覆盖方法不能比原方法抛出更多的异常。
被覆盖的方法不能是final类型,因为final修饰的方法是无法覆盖的。
被覆盖的方法不能为private,否则在其子类中只是新定义了一个方法,并没有对其进行覆盖。
被覆盖的方法不能为static。如果父类中的方法为静态的,而子类中的方法不是静态的,但是两个方法除了这一点外其他都满足覆盖条件,那么会发生编译错误;反之亦然。即使父类和子类中的方法都是静态的,并且满足覆盖条件,但是仍然不会发生覆盖,因为静态方法是在编译的时候把静态方法和类的引用类型进行匹配。
☛方法的重载:只关心方法名称和参数列表,其他的都不用管,可以随便修改
前面已经对Java方法重载进行了说明,这里再强调一下,Java父类和子类中的方法都会参与重载,例如,父类中有一个方法是 func(){ ... },子类中有一个方法是 func(int i){ ... },就构成了方法的重载。
☛和方法签名和返回类型有关这就是重写,只是多了一个返回类型
覆盖和重载的不同:
方法覆盖要求参数列表必须一致,而方法重载要求参数列表必须不一致。
方法覆盖要求返回类型必须一致,方法重载对此没有要求。
方法覆盖只能用于子类覆盖父类的方法,方法重载用于同一个类中的所有方法(包括从父类中继承而来的方法)。
方法覆盖对方法的访问权限和抛出的异常有特殊的要求,而方法重载在这方面没有任何限制。
父类的一个方法只能被子类覆盖一次,而一个方法可以在所有的类中可以被重载多次。
☛☛注意细节,在成员中写要向下面这样写
- final的应用
final 修饰的类不能被继承。
Final修饰局部变量,可以被局部内部类使用
final 修饰的方法不能被子类重写。
final 修饰的变量(成员变量或局部变量)即成为常量,只能赋值一次。
final 修饰的成员变量必须在声明的同时赋值,如果在声明的时候没有赋值,那么只有 一次赋值的机会,而且只能在构造方法中显式赋值,然后才能使用。
final 修饰的局部变量可以只声明不赋值,然后再进行一次性的赋值。
- 内部类
这段代码定义了一个外部类 Outer,它包含了一个内部类 Inner。将错误语句注释掉,编译,会生成两个 .class 文件:Outer.class 和 Outer$Inner.class。也就是说,内部类会被编译成独立的字节码文件。
注意:必须先有外部类的对象才能生成内部类的对象,因为内部类需要访问外部类中的成员变量,成员变量必须实例化才有意义。
- 接口:
1:使用常量必须使用显示初始化
public interface FunctionInter {
String a="a";//显示赋值
}
2:使用接口可以多继承
public interface FunctionInter extends FunctionInter1,FunctionInter2{
String a="a";
}
- 字符串:==和equals()区别
☛八大数据类型和String都重新重写了equals方法
1:String str=”min”;//min存在字符串常量池中(在方法区中)
String str=”min”+”helllo”;//开辟了一个空间
☛分别是min,hello,minhello的三个不同的空间
Cat cat=new Cat();
Cat cat2=new Cat();
System.out.println(cat==cat2);F
System.out.println(cat.equals(cat12));//false
//equals()也是表示的比较的内存地址值,String比较的内容
//因为重写了equals()方法,其他的都是比较内存地址
//==真的是表示地址值
★★★特别注意:
String ss="hello"+"wo"+"wo";创建了几个对象?
1个对象,
String ss="hello"+"wo"+"wo"==>String ss="hellowowo";
String str3="2"+"3";//"23"//这个是开辟了一个对象
//使用反编译进行反编译
String str1="2";
String str2="3";
String sss=str1+str2;//总共创建了三个空间
//"你"+"好" 开辟一个个空间,《你/好/你好》这里三个空间
String s4="你"+"好";//这个就是“你好”
☛注意引用的传值都是传输地址
★★重写StringBuffer和StringBuilder()方法
十、变量
//局部变量:要使用就必须初始化
//全局变量(成员变量):默认初始化也可以显示初始化
//区别:
/*
1:默认值:...
2:定义位置:局部在该方法体中有效,全局在方法定义之外
3:作用域:局部变量在所在定义方法体中有效,全局整个类中有效
4:内存分配:局部在栈中,全局在堆中
5:生命周期:局部在随着方法体加载,全局随着对象的消失而消失
☛垃圾回收机制:断开引用的数据成为垃圾,等待垃圾回收骑进行回收
☛System.gc();
☛末尾设为null
*/
◆为什么重写了equals还需要重写hashCode()
◆注意异常
/*异常:程序发生的不正常的发生的问题
* ☛运行时异常:
* 1:Throwable就是他们的超类(Error,Exception)
* 2:Exception分为编译和运行异常
* 3:try{}catch(){}finally{}
* 4:finally一定会执行,不管什么错误都会执行
* 5:try里面从上往下执行有一个发生异常了后面的代码就都不会执行了
* 6:拆开来的catch(Exception)父类必须放到最后一行就可以
* ☛编译时异常(写代码的时候提示你一定要加上surround with/throws Exception)
* 1:ParseException
*
*★第二种异常处理:throws
*直接抛出,让调用这解决
*★第三种throw抛出异常对象new Exception()
*throw抛出那个运行异常可以抛出也可以不抛出
*调用者可以抛出和处理两种选择
* ☛这种方式是不能和父类(父类)共存的
* ☛catch(ArithmeticException | NumberFormatException e)
**/
十一、封装
☛访问权限默认千万不要写出来,会报错
★this的使用:
☛:解决了同名之间的冲突(因为会产生就近原则)
- 继承
/*Inheritance:
* 有点:
* 1:extends
* 2:代码的复用性
* 3:提高代码维护性
* 注意:
* 1:子类不能继承父类private的属性和方法
* 2:创建子类实例化的时候是先调用父类的构造函数进行实例化
* 3:然后系统会自己调用父类的构造函数,因为子类中有隐含的super()
* 4:还要注意:父类构造函数显示子类也要显示,而且必须方法第一行
* 5:super()一定要在子类构造函数的最前面,不能再子类的普通方法调用
* 弊端:
* 1:耦合性增加
* 2:只能单继承
* 4:低耦合,高内聚(程序员的开发原则)
* 耦合:类与类之间的关系紧密
* 内聚:能单独完成某件事,独立性越强越好
* 开闭原则:对修改关闭,对扩展开发,以后接口中会学习
* */
★方法重写中的一个小细节:
☛子类可以抛出运行时异常,子类返回值可以是父类引用
☛注意重写的时候可以使用子类进行接收如上述截图所示,但是改成int就不行了,因为这是两种不同个数据类型
- 多态
public class Test {
public static void main(String[] args) {
/*多态:
*1:存在继承和实现
*2:方法重写
*3:父类指向子类的引用
*4: 如果父类引用要访问子类的特有方法,只需要进行向下转型
*缺点:
*1:父类的引用不能调用子类特有的方法
*2:只有被子类重写的方法才可以调用
*3: 向下转型易造成不安全,就是ClassCastException异常
* 可以使用instanceof进行判断
*静态绑定:final,static,private以及构造函数都可以在编译的时候确定
* 所以叫做静态绑定
*动态绑定:Animal an=new Cat();an.eat()//这个方法不确定
* 到底是子类还是父类的,所以叫做动态绑定
**/
//父类引用指向子类
//开闭原则:对象修改关闭、对扩展开发
/*Teacher teacher=new JavaTeacher();
teacher.teache();
Teacher teacher2=new UITeacher();
teacher2.teache();*/
Student student=new Student();
Animal c=new Dog();//默认向上转型,会丢失子类特有的方法
Dog dog=(Dog)c;//向下转型
//Cat cat=(Cat)c;//ClassCastException
//如果解决这个问题?
//☛在强转之前进行类型判断,通过instanceof进行判断
if (c instanceof Cat) {
Cat cat=(Cat)c;//这里就可以进行判断
cat.eat();
System.out.println("cat.........");
}
student.feed(dog);
student.feed(new Cat());
}
}
//聚合:公司跟员工,一部分可以独立的存在
//组合:公司跟部门(这里一部分不能独立存在)、
//关联(单项,双向关联)
- 接口
- 设计模式
- 枚举:保存常量
☛switch中可以使用的类型:int short string enum byte char
十七、String,StringBuilder,StringBuffer
//stringDemo();//StringBuilder()进行追加数据进行存储
//地址一般是不变,可以节约内存,默认长度是16个字符
StringBuilder stringBuilder=new StringBuilder();
stringBuilder.append("你好");
//StringBuffer同步的,但是运行效率低
//StringBuilder不同步,运行效率高
//append可以添加任何数据类型
System.out.println(stringBuilder.toString());
☛判断一个类型引用的传值类型StringBuffer
☛扩展知识:设置字符编码
十二、线程原理图:
☛Run方法可以抛出RuntimeException()异常
十三、接口:
☛接口中默认的时访问权限就是public,接口加了public在其他包的子类就可以进行实现该类
十四、泛型:
- 集合框架:
1:list也可以通过Collections工具类调用
synchronizedList(list)做到线程安全,所以Vector被淘汰了
1:删除重复元素:
for (int i = 0; i < list.size(); i++) {
String str=(String)list.get(i);
if(!list2.contains(str)){//删除重复元素
list2.add(str);
}
}
for (int i = 0; i < list.size()-1; i++) {
for (int j = i+1; j < list.size(); j++) {
if(list.get(i).equals(list.get(j))){
list.remove(j);
j--;//记得减回去,因为底层会向前进行偏移
}
}
}
System.out.println("list="+list);
2:统计字符串中出现的次数:
int max=-1;
int maxNum=-1;
for(int i=0;i<arr.length;i++){
Integer num=tm.get(arr[i]);
if(num==null){
tm.put(arr[i], 1);
}else{
tm.put(arr[i], num+1);
if(num+1>max){
max=num+1;
maxNum=arr[i];
}
}
}
3:数组进行扩容的是:
Arrays.copyOf(arr,扩容长度);
☛解题思路:
当要找最大最小值时首先要想到定义临时变量进行存储
☛小细节
☛注意float和dobule还有int类型之间的转换
- Timer定时器:java.util.*包
TimerTask,Timer结合使用
调用Timer中的那个schedule(...)方法
☛
- IO流
1:file可以指文件或者文件夹
2:递归和while循环是差不多多的
3:一个小细节,请注意,否则完蛋
4:File中的delete方法只能删除空目录和单独的一个文件
5:GBK:升级版,UTF-8国际化,GB2312中文,ISO8859-1西欧编码
6:EOFException异常直接catch一下就可以,我们不惜要管他,这里是ObjectInputStream流的使用!
7:记事本中的那个从那个换行的编号就是占用了2个字节
8:UTF-8字节的编码方式
考试细节:
1:write和readLine()是一样的包含\n
2:indexOf(“a”,7)
3:IlleagArgumentException非,继承了RuE...
4:异常精确查找,只能捕获一个异常
5:String str=(String)null;可以避免空
6:set无序集合咩有get()方法
7:效率:map>list>set
- Socket
1:注意细节:
☛使用我们的这个BufferedWriter进行socket编程时一定要注意加bufw.write(buff);bufw.newLine()
Bufw.flush()进行,还有注意读最好使用readLine()进行读取,因为有自动的换行
☛PrintWriter就可以设置true表示为自动的刷新,使用println就不需要newLine()方法了,如果使用write()就必须加上newLine(),因而为包装类中的读和写都是看换行来表示一行代码的结束
十八、JSON格式:
☛注意小细节:就是属相要相一致(其实是和setName(),getName()是一样的)
/*
* 1:json:一种轻量级的数据转换格式,,特点:key-value
* 2:json要么是对象{},要么是数组:
* 3:多个key-value用逗号隔开,但是最后一个不用使用逗号
* 4:记住一定要注意要有空的构造函数和set和get方法
*
*/
private static void demo4() {
String person="{'name':'龚为明1','age':23}";
JSONObject json=JSON.parseObject(person);
/*Student stu=new Student(json.getString("name"),json.getIntValue("age"));
System.out.println(stu);*/
//快速的方法进行我们的封装成bean对象
Student stu=JSON.parseObject(person, Student.class);
System.out.println("stu="+stu.toString());
}
private static void demo3() {
String person="["
+ "{'name':'龚为明1','age':23},"
+ "{'name':'龚为明2','age':13},"
+ "{'name':'龚为明3','age':33}]";
/*//存储多个对象使用[]进行括起来
String person="[{'name':'龚为明1','age':23},{'name':'龚为明2','age':13},{'name':'龚为明3','age':33}]";
List<Student> list=new LinkedList<Student>();
JSONArray arr=JSON.parseArray(person);
System.out.println(arr.size());
for(int i=0;i<arr.size();i++){
JSONObject obj=arr.getJSONObject(i);
System.out.println(obj);//这就是一个对象
list.add(new Student((String)obj.get("name"),(int)(obj.get("age"))));
}
System.out.println("list="+list);*/
//快速封装成一个list集合对象
List<Student> list=new LinkedList<Student>();
list=JSON.parseArray(person, Student.class);
System.out.println(list);
}
private static void demo2() {
String person="{'id':1001,'name':'李四','age':12}";
//使用paraseObject解析之后的json就是一个map集合
//将他当做map集合进行解析并读取
JSONObject json=JSON.parseObject(person);
System.out.println("json="+json.get("id"));
Set set=json.keySet();
Iterator it=set.iterator();
while(it.hasNext()){
Object str=it.next();
System.out.println(str+":"+json.get(str));
}
//使用第二种方法
for(Iterator<Entry<String, Object>> it2=json.entrySet().iterator();it2.hasNext();){
Entry<String, Object> entrySet=it2.next();
System.out.println("1"+entrySet.getKey()+":"+entrySet.getValue());
}
}
public static void demo1() {
String str="{'name':'张三','age':123}";
JSONObject json=JSON.parseObject(str);
String name=(String)json.get("name");
System.out.println("name="+name);
String str2=json.getString("name");
System.out.println("str2="+str2);
int age=json.getInteger("age");
System.out.println("age="+age);
System.out.println(json.containsKey("age"));
System.out.println(json.containsValue("张三2"));
System.out.println(json.size());
System.out.println(json.containsKey("age"));
}
☛GJSON解析
★注意另一个细节:主要是效率
For(int i=0,n=list.size();i<n;i++){}