- 逻辑运算符+ =
一个)jvm的会自动强转,如图图片
2.字符串的长度
一)字符串的长度是不变,如果变了,那么字符串指向新的字符常量,如图所示
3.注意返回的布尔值
一)看如下代码:
package cn.itcast.String;
import javax.sound.midi.Soundbank;
import java.util.Scanner;
public class Demo08_校验密码是否合法{
public static boolean isV(String s){
if(s.length()<8){
return false ;
} else {
char [] chars = s.toCharArray();
int num =0;
对于(诠释 I =0; I <字符。长度 ;我++){
如果(字符[I]> = 'A' &&字符[I] <= 'Z'){
NUM ++;
}
if((chars [i]> = 'A' || chars [i] <= 'Z')&&(chars [i]> = 'a' || chars [i] <= 'z')&&( chars [i]> = '0' || chars [i] <= '9')){
} else {
return false ;
}
}
如果(NUM < 2 ){
返回false ;
}
return true ;
扫描器(系统。在);
系统。out .println(“请您输入一个字符串:”);
String next = scanner.next();
布尔值 v = isV(下一个);
系统。out .println(“密码是否合法:” + v);
}
}
4.引用类型作为参数或者泛型
一个)最后需遍历,如果不遍历,那么打印出来的就是引用类型的地址,如下代码:
package cn.itcast.ArrayList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;
公共课 Demo11_随机输入多少张牌{
private String point ;
私人字符串颜色 ;
public Demo11_随机输入多少张牌(){}
public Demo11_随机输入多少张牌(String color,String point){
this。point = point;
这个。color = color;
}
公共字符串用GetPoint(){
返回点 ;
}
公共无效设定值(串点){
此。point = point;
}
公共字符串的getColor(){
返回颜色 ;
}
公共无效的setColor(字符串颜色){
此。color = color;
}
public void allCard(){
System。out .println(color + point);
}
}
类测试{
公共静态的ArrayList <Demo11_随机输入多少张牌> allCard(){
ArrayList的<Demo11_随机输入多少张牌>的ArrayList = 新ArrayList的<Demo11_随机输入多少张牌>();
String [] arr1 = { “黑桃”,“红桃”,“梅花”,“方片” };
String [] arr2 = { “A”,“2”,“3”,“4”,“5”,“6”,“7”,“8”,“9”,“10”,“J”,“Q”,“K” };
for(int i = 0 ; i < ARR1。长度 ; i ++){
for(int j = 0; j <arr2。长度 ; j ++){
Demo11_随机输入多少张牌demo11_随机输入多少张牌= new Demo11_随机输入多少张牌(arr1 [i],arr2 [j]);
arrayList.add(demo11_随机输入多少张牌);
}
}
返回数组列表;
}
公共静态的ArrayList <Demo11_随机输入多少张牌> randomCard(INT X){
ArrayList的<Demo11_随机输入多少张牌> arrayList1 = 新的ArrayList <Demo11_随机输入多少张牌>();
if(x < 0 || x> 52 ){
return null ;
} else {
ArrayList <Demo11_随机输入多少张牌> arrayList =allCard();
for( int i =0; i <x; i ++){
Random random = new Random();
int num = random.nextInt(arrayList.size());
Demo11_随机输入多少张牌d = arrayList.get(num);
arrayList1.add(d);
}
}
返回 arrayList1;
}
公共静态无效主要(字串[] args){
扫描仪的扫描仪=新扫描仪(系统。在);
系统。out .println( “请输入您想打出的拍牌数:”);
INTnum = scanner.nextInt();
if(num> 0 || num <= 52 ){
System。out .println(“随机的” + num + “张牌”);
ArrayList <Demo11_随机输入多少张牌> arrayList = randomCard(num);
for(int i = 0 ; i <arrayList.size(); i ++){
arrayList.get(i).allCard();
}
} else {
系统。out .println(“您输入的数字超出范围,请重新输入”);
}
}
}
- 使用第三方变量
A)如下代码
package cn.itcast.Arr;
import java.util.Arrays;
公共类 Demo05_奇左偶右{
公共静态无效主要(字串[] args){
INT [] ARR = {2,5,9,3,6,3,7,4,7};
int [] arr1 = swap(arr);
String s =数组。toString(arr1);
系统。out .println(s);
}
公共静态INT []交换( INT [] ARR){
INT[] arr1 = new int [arr。长度 ];
int index = arr。长度 - 1 ;
int index1 = 0 ;
对于(诠释 I = 0 ; I <编曲。长度 ;我++){
如果(ARR [I]%2 == 0 ){
ARR1 [索引] = ARR [I];
指数 - ;
} else {
arr1 [index1] = arr [i];
index1 ++;
}
}
回 ARR1;
}
}
6.判断语句的嵌套
一)案列:模拟用户登录
package cn.itcast.String;
import java.util.ArrayList;
import java.util.Scanner;
public class Demo09_模拟用户登录{
private String username ;
私有字符串密码 ;
public Demo09_模拟用户登录(String username,String password){
this。username = username;
这个。密码 =密码;
}
公共 Demo09_模拟用户登录(){}
公共字符串getUsername(){
返回的用户名 ;
}
公共无效setUsername(String username){
this。username = username;
}
公共字符串getPassword来(){
回报的密码 ;
}
公共无效 setPassword(字符串密码){
此。密码 =密码;
}
public void show(){
System。out .println(username + “ - ” + password);
}
}
类 TEST03 {
公共静态布尔 M1(ArrayList的<Demo09_模拟用户登录> ArrayList中,一个String){
对于(int i =0; 我<arrayList.size(); i ++){
Demo09_模拟用户登录demo = new Demo09_模拟用户登录();
if(arrayList.get(i).getUsername()== s){
return true ;
}
}
返回false ;
}
公共静态布尔 M1(ArrayList的<Demo09_模拟用户登录> ArrayList中,字符串S1,字符串s2){
对于(诠释 I =0; I <arrayList.size();我++){
Demo09_模拟用户登录演示=新 Demo09 _模拟用户登录(S1,S2);
if(arrayList.get(i)== demo){
return true ;
}
}
返回虚假 ;
}
公共静态无效主要(字串[] args){
ArrayList的<Demo09_模拟用户登录>的ArrayList =新的ArrayList <Demo09_模拟用户登录>();
Demo09_模拟用户登录demo1 = new Demo09_模拟用户登录( “jack”, “1234”);
Demo09_模拟用户登录demo2= new Demo09_模拟用户登录( “rose”, “5678”);
Demo09_模拟用户登录demo3 = new Demo09_模拟用户登录( “tom”, “0000”);
arrayList.add(demo1的);
arrayList.add(DEMO2);
arrayList.add(demo3);
int i =0; 我<arrayList.size(); i ++){
arrayList.get(i).show();
}
扫描仪的扫描仪=新扫描仪(系统。在);
系统。out .println( “请输入用户名:”);
String next1 = scanner.next();
系统。out .println( “请输入密码:”);
String next2 = scanner.next();
if( m1(arrayList,next1)){
//判断用户名和密码if( m1(arrayList,next1,next2)){ System。out .println( “登录成功!”
);
} else {
系统。out .println(“用户名或密码错误”);
}
} else {
系统。out .println(“集合中没有这个用户”);
}
}
}
- 数组
- 冒泡排序,如下代码
package cn.itcast.Arr;
import java.util.Arrays;
公共类 Demo12_冒泡排序{
/ **
*请对15,8,23,123,56,89进行排序
*
*外层循环控制轮数,内层循环控制次数
* / public static void main(String [] args ){诠释 [] ARR = {15,23,56,52,47,82,32}; sort(arr); String s =数组。toString(arr); 系统。out .println(s); }公共静态无效的排序(
INT [] ARR){
//外层循环控制轮数轮数是N - 1 为(诠释 I =0; I <编曲。长度 -1;我++){ //内层循环控制每次的数字比较 / /循环的次数可不-i,-i是为了提高执行性能为( INT J =0。;Ĵ<ARR长度 -1- I; J ++){ //比完大小之后,再进行交换,如果(ARR [J ]> arr [j +1]){ int temp = arr [j]; arr [j] = arr [j +1]; arr [j +1] = temp; } }
}
}
}
b)中选择排序,代码如下
package cn.itcast.Arr;
import java.util.Arrays;
公共类 Demo14_选择排序{
公共静态无效主要(字串[] args){
INT [] ARR = {15,23,56,52,47,82,123,32};
sort(arr);
String s =数组。toString(arr);
系统。out .println(s);
}
公共静态无效排序(诠释 [] ARR){
对于( INT I =0; 我<arr。长度 - 1 ; 我++){
对于(INT J = + 1 ;Ĵ<编曲。长度 ; J ++){
如果(ARR [I]> ARR [J]){
INT临时= ARR [I];
arr [i] = arr [j];
arr [j] = temp;
}
}
}
}
}
C)注意:统计字符出现的次数
package cn.itcast.Arr;
public class Demo06_字符次数{
public static void main(String [] args){
char [] arr = { 'a', 'l', 'f', 'm', 'a', 'f', 'o ', 'b', 'b', 's', 'n', 'a' };
int [] arr2 = new int [123];
printCount(arr,arr2);
[] ARR2){
对于(诠释 I = 0 ; I <编曲。长度 ;我++){
INT指数= ARR [I]; //获取的是AscII arr2 [index] = arr2 [index] +1; // ARR2 [指数]获取的是数组里存的值,初始值为0,在0的基础上加1 } 为(INT J = 0 ;Ĵ<ARR2。长度 - 1 ; J ++){ 如果(ARR2 [ j]!= 0 ){ 系统。out .println(arr2 [j] + “” +(char)j); } } }
}
- 对于循环,注意对循环的嵌套
外层循环控制行,内层控制列
一个)打印菱形,如下代码
package cn.itcast.For;
/ *
*打印一个菱形
* *
* * *
* * * *
* * * * *
* * * * * *
* * * * * * *
* * * * * *
* * * * *
* * * *
* * *
* *
*
* * /
public class Demo01_菱形{
public static void main(String [] args){
three();
for( int i =0; i <5; i ++){
for( int j =0; j <= i; j ++){
System。出.print(“”);
}
对(INT J = 0 ;Ĵ< 5 - I; J ++){
系统。out .print(“*”);
}
系统。out .println();
}
}
公共静态无效 3(){
对于(诠释 I = 0 ; I <= 6 ;我++){
对于(INT J = 0 ;Ĵ< 6 - I; J ++){
系统。out .print(“”);
}
对(INT J = 0 ;Ĵ<I; J ++){
系统。out .print(“*”);
}
系统。out .println();
}
}
}
b)中打印九九乘法表,如下代码
package cn.itcast.For;
公共课 Demo05_九九乘法表{
/ **
* 1 * 1 = 1
* 1 * 2 = 2 2 * 2 = 4
* 1 * 3 = 3 2 * 3 = 6 3 * 3 = 9
* ...
* / public static void main(String [] args){ for( int i =1; i <=9; i ++){ for( int j =1; j <= i; j ++){ System。out .print(j + “*” + i + “=” + i * j + “”); } 系统。出
.println();
}
}
}
- 集合
- 集合集合
- 数据结构
- 数据结构的概念和作用:
- 概念:就是指”存储和管理”大量数据的一种方式
- 作用:每种数据结构都会影响到数据的排序方式,从而影响增删改查的执行效率。
2.常见的数据结构
- 数组 - ArrayList:查询快,增挂慢
- 链表 - LinkedList:查询慢,增快快
- 哈希表 - HashSet:查询,增离都快,但所有的操作都会产生一个哈希值
- 树 - TreeSet:对元素排序
- 图 - 地图
- 栈 - 先进后出
- 队列 - 先进先出
- 数据结构的存储视图数组:
1.ArrayLIst集合的内部就是使用数组结构
特点:
-
-
- 查询快,增删慢
- 涉及到数组的拷贝和移动
- 内部存储是连续的
- 不属于先进先出(属于根据索引随意出)
- 查询快,增删慢
-
- LinkedList的内部使用的是” 链表结构”
-
- 查询慢,增删快
- 删除,只需把被删除元素后的一个地址保存在被删除元素前的值就可以,所以比较快
- 增加,把增加的地址保存在前一个元素的前边,然后把增加元素的地址保存在后一个元素中,所以快。
- 查询慢,增删快
b)各个节点之间是通过地址来连接的
- 栈
- 栈结构:关注存,去取的方式
特点:
- 先进后出
- 运算受限的线性表(只能在一端进行插入,删除)
(想象成桶,只有一个口,插入和删除只能在这一个口中进行操作)
- 只能在”栈顶”进行插入和删除
4.队列
1.栈结构:关注存,去取的方式
特点:
- 先进先出(必须按顺序一个一个出,不能随意出)
- 运算受限的线性表(在一端插入,在另一端删除)
(想成日常中的排队,先进先出)
- 红黑数
- 树结构:关注”存,去”的方式
- Java的集合体系结构图
- 收藏常用的功能
- 添加
public boolean add(E e):添加一个元素;
添加成员返回:真,对于清单集合,永远返回真;
对于设置集合,当添加重复元素时,返回:假的;
- 删除
Public void clear():清空集合
Public boolean remove(object o):在集合中删除元素o,成功返回true,如果集合中没有此元素,则返回false。
- 判断
公共布尔包含(对象o):判断集合中存在对象o,存在返回true,不存在则返回false。
底层图:o.equals(集合中的元素);
Public boolean isEmpty(): 判断该集合是否为空
- 获取
Public int size():返回集合中元素的数量
Public object [] toarry():将集合内的所有元素转换为object数组;
Public Iterator iterator():获取一个迭代器;用于遍历集合元素的对象;
- 名单
①特点:有序的,可以添加重复元素
②方法:增删改查
1)。增加:public void add(int index,E ele):将元素ele添加到index位置。
2)。删除:public E remove(int index):移除列表中指定位置的元素,返回的是被移除的元素。
3)。改:public E set(int index,E ele):用指定元素替换集合中指定位置的元素,返回值的更新前的元素。
4)。查:public E get(int index):返回集合中指定位置的元素。
注意:上面所有方法都有一个 “索引(索引)” 参数;这个索引在使用时要保证在正确的范围,否则抛异常;
③ArrayList无特有的方法,都继承自父类
④LinkedHashList有一些特有的方法,用于模拟栈,队列
1).addFirst():可以模拟压栈
2).addLast():可以模拟排队;
3).push():可以模拟压栈
4).pop():从列表的开头取出,并删除一个元素;可以模拟弹栈;
轮询():从列表的开头取出,并删除一个元素;可以模拟弹栈;(如果列表为空,不抛异常,比较常用);
2)内部是。“ 链表” 实现;查询慢;增删快;
- 组
①特点:无序的,不能存储重复元素
②HashSet:哈希表实现
③LinkedHashSet:集的特例,有序的。
链表+哈希表
链表:保证存储元素的顺序
哈希表:保证存储元素的唯一性
4.迭代器
- 迭代器迭代器接口的使用
public class Demo {
public static void main(String [] args){
Collection <String> list = new ArrayList <>();
list.add( “ 孙悟空”);
list.add( “ 珠宝街”);
list.add( “ 铁扇公主”);
list.add( “ 红孩儿”);
Iterator <String> it = list.iterator();
while(it.hasNext()){
System。out .println(it.next());
}
}
}
- 迭代器的实现原理
③,常见错误
1。
public static void main(String [] args){
Collection <String> list = new ArrayList <>();
list.add( “ 孙悟空”);
list.add( “ 珠宝街”);
list.add( “ 铁扇公主”);
list.add( “ 红孩儿”);
Iterator <String> it = list.iterator();
while(it.hasNext()){
String s = it.next();
系统。out .println( it.next());
}
}
- 并发异常
不能再遍历集合的迭代器中调用集合的去除方法对集合进行增删,否则会报 - 并发异常。
3.迭代器只能遍历数组和集合接口中的子类,不能遍历集合中Map
④,增强了循环
- 作用:遍历数组
int [] arr = {1,43,24,32,54};
for(int n:arr){//编译成:普通for循环
的System.out.println(N);
}
- 作用:遍历集合
ArrayList <String> list = new ArrayList <>();
list.add(“ 孙悟空”);
list.add(“ 猪八戒”);
list.add(“ 沙和尚”);
list.add(“ 唐三藏”);
for(String s:list){ //编译成:迭代器
System。out .println(s);
}
注意:
S:代表集合中的元素
步增语句自动增加
小号前的数据类型必须和集合的数据类型一致
- 地图集合
- 概述
①双列集合
2.常用的子类
①注意:Map内部也使用了“数据结构”,任何的数据结构都是应用在“键”上。
②Map(接口):
| --HashMap(子类):”键”是哈希表结构
| --LinkedHashMap(子类):“键”是链表+哈希表结构
- 地图集合接口常用的方法
①添加,修改
Public V put(K key,V value):把指定的键和指定的值添加到Map集合中。
此方法在正常添加情况下返回空
当添加重复”键”的时候,会使用”新值”替换集合内的”旧值”,并且返回。
②删除
Public V remove(Object key):把指定的键所对应的键值对元素在map集合中删除,返回被删除元素的值。
③查询
Public V get(Object key):根据指定的键,在Map集合中获取对应的值
④遍历方式
公共集<K> keySet():获取Map集合中所有的键,存储到集合合中。
公共集<Map.Entry <K,V >> entrySet():获取到Map集合中所有的键值对对象的集合(Set集合);
地图集合遍历_键值对对象_entry对象说明:
- 地图接口中有一个”内部接口”:入口,里边定义了两个方法:
- 信息getKey():
- 的getValue();
2.HashMap中有一个”内部类”节点实现了Map.Entry的接口。
3.当我们向HashMap中添加一个“键值对”时,HashMap会将这个“键值对”直接封装到一个节点对象中。
4.我们可以通过HashMap的entrySet()方法,将所有的Node对象封装到一个Set中,并返回,然后遍历。
- 遍历方式Demo01
public static void main(String [] args){
Map <String,String> map = new HashMap <>();
map.put( “绿巨人”, “王宝强”);
map.put( “老王 ”, “宋喆”);
map.put( “美女”, “马蓉”);
map.put( “影帝”, “黄渤”);
设置<String> set = map.keySet();
for(String key:set){
System。out .println( “键:” + key + “值:” + map.get(key));
}
}
- 遍历方式Demo02
public static void main(String [] args){
Map <String,String> map = new HashMap();
map.put( “绿巨人”, “王宝强”);
map.put( “老王 ”, “宋喆”);
map.put( “美女”, “马蓉”);
map.put( “影帝”, “黄渤”);
设置<Map.Entry <String,String >> entries = map.entrySet();
for(Map.Entry <String,String> entry:entries){
String key = entry.getKey();
String value = entry.getValue();
系统。“值:” +值);
}
}
- 注意
- 自定义对象做键,需要重写:hashCode()方法和等于方法,不然会添加重复的键值。
- LinkedHashMap的是一个有序的地图
-
10.关键字
a)Static
1.类变量的使用
a.类变量 直接可以使用 类名.类变量 去访问
b.类变量 不属于任何一个对象,属于这个类
也就是说类变量 在内存中只有一份,所有对象可以共享他
2.static修饰方法(类方法)
a.定义格式
public static 返回值类型 方法名(参数列表){}
b.类方法的使用
可以直接通过 类名.静态方法名() 调用
类方法的注意事项
静态方法可以直接访问类变量和静态方法。
静态方法不能直接访问普通成员变量或成员方法。反之,成员方法可以直接访问类变量或静态方法
总结: 静态只能访问静态 非静态既可以访问非静态 也可以访问静态
静态---> 先人(秦始皇)
非静态--->我们
静态方法中,不能使用this关键字。
3.静态代码块(在数据库时,有用)
格式:
static{一句或者多句代码}
定义位置:
定义在类的成员位置
作用:
a.给静态成员赋值
b.用于数据库加载驱动
特点:
a.在同一个类型中,优先于构造,优先main方法执行
b.只会执行一次,类加载完毕之后立刻执行(那时候还没有对象)
b)、super和this
访问成员变量:
this.成员变量名: 优先访问子类成员变量
成员变量名: 优先访问局部变量
super.成员变量名: 直接访问父类的成员变量
访问成员方法:
this.成员方法名(); 优先调用子类成员方法
成员方法(); 优先调用子类成员方法
super.成员方法();//直接调用父类的成员方法
[补充]调用构造:
a.子类的任意构造方法,第一行默认使用super() 调用父类的无参构造
为什么要在子类构造的第一行调用父类的无参构造
因为Java设计时,遵循一个原则,单一职责原则
子类的成员变量由子类的构造负责初始化
父类的成员变量由父类的构造负责初始化
c)、final
1.final修饰类: 太监类
格式:
public final class 类名{....}
特点:不能被继承
2.final修饰方法: 最牛逼的方法
格式:
public final 返回值类型 方法名(){....}
特点:该方法不能被子类重写
3.final修饰局部变量
格式:
public static void main(String[] arg){
final int age;
age = 100;
或者
final int age = 100;
}
特点:只能赋值一次,a.定义同时赋值 b.先定义后赋值
4.final修饰成员变量
格式:
public class Dog{
final int age = 10;
或者
final int age;
public Dog(){
this.age = 10;
}
}
特点:
只能赋值一次
a.定义成员变量时,直接赋值
b.在构造方法中赋值
扩展: 如果有多个构造,那么要保证每个构造都必须赋值
通过对象名.final成员变量名 是不能赋值的
5.final修饰引用类型的变量
格式:
final Dog d = new Dog();
d = new Dog();//不行,因为d只能赋值一次
d.age = 10;
d.name = "旺财";
//以上这两步是可以的,除非age和name成员变量也是final修饰的,那么不能再次赋值
特点:
final修饰引用类型变量,不能给引用类型变量重新赋值,
但是可以修改引用类型变量所指向的空间中其他变量值
- String的类
-
1.String
- 字符串的特征
-
a.不可变性,字符串的值在创建后不能被更改。
只要你觉得它的值改变了,那肯定是又创建了一个新的字符串对象
b.共享性:
因为String对象是不可变的,所以它们可以被共享。
c.等价性;
"abc" 等效于 char[] data={ 'a' , 'b' , 'c' }。
- 方法
-
第一组:判断功能
public boolean equals (String anString);//判断两个字符串的内容是否相等
public boolean equalsIgnoreCase (String anString);//忽略大小写判断两个字符串的内容是否相等
public boolean startsWith(String anString);//判断字符串是不是以指定字符串开头的
public boolean endsWith(String anString);//判断字符串是不是以指定字符串结尾的
第二组:获取功能
public int length();//获取字符串的长度
public String concat(String str);//连接字符串,返回新的字符串
public char charAt(int index);//获取指定索引处的字符
public int indexOf (String str);//获取子串在本串中第一次出现的索引
public String substring (int beginIndex);//从开始索引截取子串,返回截取出来子串
public String substring (int beginIndex,int endIndex);//从开始到结束索引截取字符串,
包含开头不包含结尾,返回截取出来子串
第三组:转换功能
public String toUpperCase();//转成大写字符串
public String toLowerCase();//转成小写字符串
public char[] toCharArray();//转成字符数组
public byte[] getBytes();//转成字节数组
public String replace (String target, String replacement);//把目标字符串替换为指定字符串
第四组:分割功能
public String[] split(String regex);//以指定的切割符,切割字符串,返回字符串数组
- StringBuilder
- 概述:
-
java.lang.StringBuilder(类):它常用来代替字符串的"+"运算符,进行多字符串连接的。
当进行“字符串连接”时,使用string以及+运算符,会产生很多的垃圾,降低程序的效率;
所以以后当需要进行字符串连接时,可以使用:StringBuilder类;
- 工作原理:
-
它内部有一个“缓存区(字符数组)”,当进行字符串连接时,会将新字符串添加到这个缓冲区
末尾,但StringBuilder对象只有一个。
- 方法:
- .public StringBuilder append(各种类型) : 将各种类型数据转换为String,并添加到当前StringBuilder对象的末尾。
-
- String类和StringBuilder类的区别小结:
-
1).String表示一个“字符串”,是“不可变的”;
String s = "Hello";
2).StringBuilder不能表示一个字符串,它只是一个字符串的工具类,内部是“可变的”。
StringBuilder bld = "Hello";//错误
StringBuilder bld = new StringBuilder("Hello");//OK的
当需要做“字符串连接时”,建议使用“StringBuilder”;
- 继承
- 继承的特点
-
面向对象的三大特点:
封装: 提高代码安全性
继承: 提高了代码的复用性
多态: 提高了代码的扩展性(灵活性)
- 继承之后,成员变量以及成员方法的调用
-
根据就近原则,优先调用子类自己的成员
注意:如果子类需调用父类的成员方法,一般也用super来调用
c)this和super
this:
this.成员变量名 : 优先访问本类的成员变量,如果本类没有该成员变量,也会访问父类的成员变量
如果仅仅 写 成员变量名,那么优先访问局部变量
this.成员方法名(): 优先调用本类的成员方法,如果本类没有该成员方法,也会调用父类的成员方法
如果仅仅调用 成员方法() <====>this.成员方法()
super:
super.成员变量名: 直接访问父类的成员变量
super.成员方法名();直接调用父类的成员方法
d)构造方法的调用
a.构造方法子类不存在继承这种说法
b.子类的任何一个构造,第一句会默认使用super()调用父类的无参构造
使用父类的无参构造给父类继承而来的成员变量赋默认值的,接着子类自己的无参构造给自己的成员变量赋默认值
注意:如果子类需调用父类的构造方法,一般用super来调用
- 抽象
- 抽象方法的定义格式
-
public abstract 返回值类型 方法名(参数列表); 抽象方法,必须有abstract
b)抽象类的注意事项
抽象类不能创建对象
抽象类中,可以有构造方法
抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
抽象类的子类,必须重写抽象父类中所有的抽象方法
- 接口
- 接口的定义
-
接口是方法的集合,接口中只能定义方法,不能定义成员变量
接口中的各种方法
抽象方法,静态方法,默认方法,私有方法
b)接口的实现
接口和抽象类是相似的,都不能创建对象
接口是天生作为父接口,让实现类 实现的
继承用 extends
实现用 implements
implements 作用类似 extends 都是把父的非私有的成员继承过来
c)实现类
a.调用抽象方法,必然调用重写后的方法
b.调用默认方法,如果实现类重写了那么调用重写后,如果实现类没有重写调用接口中默认方法
c.静态方法 就是通过接口名或者类名调用
d.私有方法,接口内部自己调用
非静态的私有方法,由接口中默认方法调用
静态的私有方法,由接口中的静态方法调用,当然默认方法也能调用
d)继承和实现的优先级
一个类 可以在继承一个类的同时,实现多个接口
格式:
public class 子类/实现类 extends 父类 implements 接口1,接口2..{
}
如果有多个抽象方法同名,只需重写一次
如果父类的方法和接口的默认方法同名,那么可以不重写,调用是优先调用父类的
e)接口中其他成员的特点
a.接口中,无法定义成员变量,但是可以定义常量,其值不可以改变
固定格式: public static final 数据类型 变量名 = 值;
b.接口中,没有构造方法,不能创建对象。
c.接口中,没有静态代码块。
f)面试题:Java中可以不可以支持多继承???
如果是类与类之间,只能单继承
如果是接口与接口之间,可以多继承
如果是类与接口之间不称为继承,称为实现,多实现
- 多态
- 多态的前提和体现
-
a.必须有继承关系,或者 实现关系
b.必须有方法的重写(没有方法重写,多态就失去了意义)
多态体现的文字描述:父类类型的变量 指向了 子类类型的对象
- 多态调用方法的特点
-
编译阶段: 多态调用方法 只看父类
运行阶段: 多态调用方法 运行子类
总结: 编译看父类,运行看子类
多态调用方法时,必须保证子父类都有这个方法
c)多态的好处
案例: 定义一个方法,喂狗.猫吃饭
a.定义类,抽取共性
b.多态的好处在于,使用父类类型作为参数,就可以接收任何一个子类类型的对象,提高代码的扩展性
d)多态的弊端
多态的调用方法特点;
编译看父类,运行看子类,也就说只有子父类都有的方法,多态才能调用成功
弊端:多态不能调用子类特有的方法
f)多态的解决方案转型
向上转型(自动类型转换):
把子类类型 转成 父类类型
Animal an = new Dog();//多态
向下转换(强制类型转换)
Animal an = new Dog();
Dog dd = (Dog)an;
g)转型出现的问题以及解决方案
1.可能出现类型转换的问题,而这个问题编译时根本没有任何提示,运行时程序直接崩
Animal an = new Dog();//多态
Animal an = new Dog();
Cat cat = (Cat)an; //没有任何提示,运行时程序直接崩
解决方案
2.instanceof关键字的介绍
运算符: instanceof
使用格式:
对象名 instanceof 类型
作用:
判断 左边的对象名 到底属于或者不属于 右边的类型
结果: true/false
总结; 向下转型之前,必须用instanceof进行判断,如果是才能向下转型
16.匿名内部类
- 语法糖:
-
是创建抽象类的子类或者接口的实现类对象的快速格式
如果不是使用匿名匿名内部类:
需求: 定义一个抽象类,创建子类对象,并调用方法
a.定义抽象类
b.定义子类 继承 抽象类
c.子类要重写抽象类的所有抽象方法
d.创建子类对象,测试这些方法
2.格式:
抽象类的子类对象
抽象类类型 对象名 = new 抽象类名(){
//重写抽象类的所有抽象方法
};
接口的实现类对象
接口类型 对象名 = new 接口(){
//重写接口的所有抽象方法
};
-
- object类
-
1.Object概述
java.lang.Object类:使用是不需要导包;Object类是所有引用类型的父类。
2.object的方法
toString:
主要作用:打印对象的属性:打印的是两个对象的
getClass().getName() + '@' + Integer.toHexString(hashCode())
比较两个对象需复写此方法
Equals:
比较的是两个对象的地址是否相同,如需比较里两个对象的所有的属性,则应该覆写此方法。
Objects类:
java.util.Objects(类):使用时要导包;
对象操作的工具类,里边包含一些”对象操作的静态方法”;
Objects中的equals方法:
- 作用:可以判断obj1和obj2两个对象是否“相等”
- 它内部也基于被判断对象内部的equals()的实现
- 可以有效的防止“空指针异常。
-
- Date类
- date对象
-
Date date = new Date();
System.oyt.println(date);
打印出来的是时间并不是地址。
例如:Sat Aug 11 10:43:17 CST 2018
- date的方法
-
Gettime:获取1970年01月01日到当前对象的时间的毫秒值
Settime:设置毫秒值
- DateFormat
- java.text.DateFormat(抽象类)
-
它可以对日期进行“格式化”。它是“抽象类”,我们可以直接使用它的子类:java.text.SimpleDateFormat(类):Simpleformat
成员方法:
public String format(Date date):将一个Date对象转换为String对象;
public Date parse(String text,ParsePosition pos):将一个字符串的时间转换为Date;
“模式”说明:
1).y : 代表“年”; 2).M : 代表“月”;
3).d : 代表“日”; 4).H : 代表“小时”;
5).m : 代表“分钟”; 6).s : 代表“秒”;
- Calendar
- .java.util.Calendar(抽象类):它是抽象类,我们可以使用它的静态方法,getInstance()来获取它的一个子类对象;
- .常用方法:
-
public int get(int field):获取某个字段的值;
public void set(int field,int value):设置指定字段的值;
public void add(int field,int value):将指定的字段的值增加value。
- System
- 概述
-
java.lang.System(类):包含了一些实用的静态方法;
- 方法
-
1.复制数组
public static void arraycopy(Object src,//原数组
int srcPos,//原数组的起始位置
Object dest,//目标数组
int destPos,//目标数组的起始位置
int length //复制长度
);
- 获取当前系统时间的毫秒值
-
public static long currentTimeMillis()
作用:计算代码的执行时间;
- 泛型
- 概述
-
ArrayList<String> list = new ArrayList<>();
好处:可以约束这个集合中只能存储String类型,如果存储其他类型,编译直接报错,可以减少很多我们在使用集合时容易发生的错误。
- 泛型的类
-
1.定义泛型的类(相当于集合的类)
public class MyArrayList<E> {
public void add(E e){
}
public E get() {
return null;
}
} - 使用(在类名后直接跟泛型,后的泛型符号可以省略)
-
public static void main(String[] args) {
MyArrayList<String> list = new MyArrayList();
list.add(string类型);list.get();//String类型;
} - 定义泛型的语法
-
class MyArrayList<E>{
}
格式说明:
- <E>:表示定义”泛型”
- E:是随意定义,可以是一个字符,也可以是多个字符;
- 可以同时定义”多个泛型”,中间用”,”号隔开;
-
public class MyArrayList<E,A,B,C> {
public void add(E e){
}
public E get() {
return null;
}
public void show(A a,B b){
}
public void fun(C c){
}
} - 泛型方法
-
示例代码:
public class MyArrayList {
public static <T> void show(T t1,T t2,T t3,T t4,T t5){
System.out.println("t1 = " + t1);
System.out.println("t2 = " + t2);
}
}测试类
public class Demo {
public static void main(String[] args) {
MyArrayList.<Integer>show(10,20,30,40,50);
MyArrayList.<String>show("aa","bb","cc","dd","ee");
}
} - 泛型接口
-
定义具有泛型的接口,同泛型类一样:
public interface IA<E>{
public void show(E e);
}
- 泛型的通配符
- <?>: 表示:具有”任何泛型”的集合都可以:
-
public static void main(String[] args) {
Collection<Student> stu = new ArrayList<>();
print1(stu);
Collection<Teacher> tea = new ArrayList<>();
print1(tea);
Collection<String> str = new ArrayList<>();
print1(str);
}
//定义一个方法,可以接收"具有任何泛型的集合对象"
public static void print1(Collection<?> list){
} - <? extends E>: 表示:具有”E或者E的任何子类泛型”的集合都可以:
-
public static void main(String[] args) {
Collection<Student> stu = new ArrayList<>();
print2(stu);//OK的
Collection<Teacher> tea = new ArrayList<>();print2(tea);//OK的
Collection<String> str = new ArrayList<>();
print2(str);//错误
}
//定义一个方法,可以接收"具有Student和Teacher泛型的集合"
public static void print2(Collection<? extends Person> list){
} - <? super E>: 表示:具有”E或者E的任何父类泛型”的集合都可以:
-
public static void main(String[] args) {
Collection<Student> stu = new ArrayList<>();
print3(stu);//OK的
Collection<Teacher> tea = new ArrayList<>()// print3(tea);//编译错误
Collection<Person> per = new ArrayList<>();
print3(per);//OK的
Collection<Object> obj = new ArrayList<>();
print3(obj);//OK的
}
//定义一个方法,可以接收"具有Student和Person泛型的集合"
public static void print3(Collection<? super Student> list){
} - 可变参数
-
1.特点
①可变参数可以是任何类型(基本数据类型、引用数据类型)
②调用时,对于”可变的形参”,可以不传实参,也可以传任意多的实参
③在一个方法的形参列表,最多只能有一个”可变参数”。
④在一个方法的形参列表中,可以同时出现”可变参数”和”普通参数”,但”可变参数”必须位于参数列表的末尾。
⑤”可变参数”编译后就是”数组”,在方法的内部,按照数组处理即可。
- Demo
-
public class Demo {
public static void main(String[] args) {
sum(10, 20);
sum(10, 20, 3, 40, 532, 43, 24, 324, 324, 324, 324, 43);
p1();//不传实参
p1("43l","fdsaf","fsjklsdjfs","fsdf");//可以传任意多的实参
}
public static int sum(int... arr) {//语法糖:编译后:就是"数组"
int sum = 0;
for(int i = 0;i < arr.length; i++){
sum += arr[i];
}
return sum;
}
public static void p1(String ... arr){
}
} - Collections集合的工具类
- 概述
-
java.util.Collections(工具类):里面包含了一些对Collection集合操作的工具类
- 常用的方法
-
①public static <T> boolean addAll(Collection<T> c, T. . . elements) : 往集合中添加一些元素。
示例代码:
ArrayList<Integer> intList = new ArrayList<>();
Collections.addAll(intList,10,24,4324,2,432,4,24,324,32432,4);
System.out.println(intList);②.public static void shuffle(List<?> list) 打乱顺序 :打乱集合顺序。
示例代码:
System.out.println("打乱顺序:");
Collections.shuffle(intList);
System.out.println(intList);③.public static <T> void sort(List<T> list) :将集合中元素按照默认规则 排序(自然排序,升序)。
基于被排序对象的:compareTo()方法(需要实现Comparable接口)
示例代码:
System.out.println("排序:");
Collections.sort(intList);
System.out.println(intList);④.public static <T> void sort(List<T> list,Comparator<? super T>):将集 合中元素按照指定规则排序。
使用比较器(Comparator)可以允许被排序对象不实现Comparable接口。但是 要制作一个比较器(Comparator的子类),具体例子见:17
- Collections工具类的比较方式
- Comparable接口
-
①作用:添加比较的方法:CompareTo()
②java类库中的一些常用类:String、Integer(各种包装类)都实现了这个接口,所以可以使用Collections工具类的sort()方法进行排序。
③要对”自定义类”进行排序,就需要实现Comparable接口,并实现compareTo()方法
④示例代码
自定义对象:
public class Student implements Comparable {
String name;
int age;
......
@Override
public int compareTo(Object o) {
Student stu = (Student)o;
return this.age - stu.age;
}
}测试类:
public static void main(String[] args) {
List<Student> stuList = new ArrayList<>();
stuList.add(new Student("张三",20));
stuList.add(new Student("李四",18));
stuList.add(new Student("李四2",17));
stuList.add(new Student("李四",19));
stuList.add(new Student("李四",13));
Collections.sort(stuList);//排序--内部调用Student的compareTo()方法。
System.out.println(stuList);
} - Comparator接口
-
①Demo
public class Demo {
public static void main(String[] args) {
List<Student> stuList = new ArrayList<>();
stuList.add(new Student("jack",20));
stuList.add(new Student("rose",17));
stuList.add(new Student("anna",18));
stuList.add(new Student("anna",19));
stuList.add(new Student("tom",13));
Collections.sort(stuList,new Comparator(){//比较器
@Override
public int compare(Object o1, Object o2) {
Student stu1 = (Student)o1;
Student stu2 = (Student)o2;
//1.先按姓名排升序
int num = stu1.name.compareTo(stu2.name);
//2.如果姓名相同,按年龄降序排
int num2 = (num == 0 ? stu2.age - stu1.age : num);
return num2;
}
});
System.out.println(stuList);
}
} - 异常
- 概述
- 概念:是指代码在执行过程中,出现了一些JVM无法处理的数据,一旦这种情况,JVM将会终止程序的执行(程序卡死,程序闪退),这种情况叫异常。
- 如果程序一旦出现异常,我们程序员和用户都不希望程序被终止,这是Java提供了一种语法机制,可以在”异常情况”出现时,使我们的程序继续健康的执行下去。
- 异常处理解析:
-
①:JVM执行到有异常的代码
②:JVM识别出这个异常
③:JVM到类库中找到描述这个异常的情况”异常类”,并创建对象;
④:判断我们的程序是否有catch语句来捕获这个异常:
有:执行这个catch语句,之后,继续行下执行;
否:将异常信息打印到控制台,将程序结束。
- 异常的体系和分类
- 这里讲的”异常”全部是指:程序已通过编译,在运行时出现异常。
-
Throwable(顶层的异常类):
|--Error(错误):不希望我们程序捕获的一些重大异常。(不用掌握)
|--Exception(异常):希望程序进行捕获的一些异常情况(必须掌握)
|--RuntimeException(运行时异常):
|--除RuntimeException外的其它异常(编译期异常):不是“编译时的语法错误”。
指这种异常必须要“处理”,否则无法编译通过。(这跟写代码时的语法错误是不同的。)
- 异常类的作用
-
①每个异常类,都描述了一种异常情况。
②:异常类的类名就是指出了这个异常是什么情况;类内部还包含了一个String的变量,来存储这种异常的”异常信息”,还有一些方法做一些其他操作。
- 异常处理方式一
- 基本语句
-
try{
//可能出现异常的代码:
}catch(异常类名 变量名){
//如果出现了跟“异常类名”匹配的异常,将会执行这个catch.
//执行完毕,将会继续执行catch的后续语句,程序就起死回生了。
}
注意:catch中的”异常类型”必须和try中产生的异常类型匹配,才能被执行,否则不能被执行。
- 常见的异常
- NullPointerException 空指针异常
- ArrayIndexOutOfBoundsException 数组下标越界异常
- NumberFormatException 数字转换异常
- ArithmeticException 算术运算异常
- ParseException 转换异常
- 异常处理方式二
- 格式:
-
try{
//多行代码,可能会产生多种异常
}catch(异常类型1 变量名){
}catch(异常类型2 变量名){
}catch(异常类型n 变量名){
}
- 注意:
- 多catch中的异常类型不能是相同的类型。
- 多catch中的异常类型”可以是子父关系”,但父类的异常必须写在多catch的末尾。
-
例:
try{
}catch(ArithmeticException e){
}catch(NullPointerException e){
}catch(Exception e){
}
- 多catch中的异常类型如果是平级的关系,没有顺序。
- 异常处理方式三
- 示例Demo
- 注意:
- throws用于在”方法声明”处,声明抛出异常;
- throws后面可以写多个异常”异常类型”名,用”,”号隔开;
- 如果方法内产生了声明对的异常类型之一,JVM会立即终止方法的执行,并将异常对象返回给”方法的调用处”;
- 如果声明抛出的是”运行时异常(RuntimeException)”,调用是可以不处理。
- 如果声明抛出的是”编译期异常(除RuntimeException外的异常)”,调用处必须将这个异常捕获(try...catch)或者继续抛出(Throws);
-
- 异常处理方式三
- Demo
-
- 注意:
- Throw表示:后面必须跟一个异常对象
-
-
- 如果是运行时异常,可不抛
- 如果是非运行时异常,则必须跑
-
-
- Throw表示:后面必须跟一个异常对象
-
b) Throw表示结束方法的执行,立即返回一个异常,后续代码不会被执行。