javaSE(五)

1.package

作用是将字节码文件.class分类存放

多级.分开,一个java文件只能有一句package语句

此时需要使用import进行导包

package,import,class是否有先后顺序?

先package,再import,最后是class

 

2.权限修饰符

private  仅可本类

默认       本类   同一包下

protected  本类   同一包下  不同包下的子类

public         本类   同一包下    不同包下的子类   不同包下的无关类

 

3.内部类

内部类就是在类内部创建的类

内部类访问的特点:

           内部类随便访问外部类的成员

           外部类访问内部类需要创建内部类对象

格式:外部类名.内部类名  对象名 = 外部类对象.内部类对象(也就是new 外部类().new 内部类())

 

私有内部类的使用:

class Outer {
	private int num = 60;

	private class Inner {
		public void method() {
			System.out.println(num);
		}
	}

	public void Rao() {
		Inner inn = new Inner();
		inn.method();
	}
}

在外部类的内部提供一个创建私有内部类并调用对应方法的方法,直接新建外部类对象调用该方法即可。

 

静态内部类使用:

public class Practice {
	public static void main(String[] args) {
		Inner1 inner1 = new Outer.Inner1();
		inner1.print1();
		new Outer.Inner2().print2();
	}
}
class Outer{
	static class Inner1{
		public void print1(){
			System.out.println(666);
		}
	}
	static class Inner2{
		public static void print2(){
			System.out.println(777);
		}
	}
}

静态可以直接使用,非静态必须创建对象。

成员内部类面试题:

public class Practice {
	public static void main(String[] args) {
		Inner inner = new Outer().new Inner();
		inner.method();
	}
}

class Outer {
	public int num = 10;

	class Inner {
		public int num = 20;

		public void method(){
			int num =30;
			System.out.println(?);
			System.out.println(??);
			System.out.println(???);
		}
	}
}

?,??,???位置分别填上对应代码,使之依次输出10,20,30.

	System.out.println(Outer.this.num);
			System.out.println(this.num);
			System.out.println(num);

就近是30,this调用本类也就是内部类的是20,Outer.this调用外部类的变量。

 

局部内部类在访问它所在方法的局部变量一定要加final,为什么?

因为在调用这个方法的时候,如果局部变量没有用final修饰,那么局部变量的生命周期和方法的生命周期是一样的,当方法发生弹栈,它就随之消失。如果局部内部类还没有马上消失想要使用这个局部变量,也无法使用。如果使用final修饰,局部变量就会进入内存中方法区的常量池中,延长了局部变量的生命周期。

JDK1.8取消了该限制。

 

4. 匿名内部类

前提条件:存在一个接口或者一个类

格式:new 类名或者接口名(){

                      重写方法;

}.方法名;

本质:继承了该类或者实现了该接口的子类匿名对象。

 

匿名内部类重写多个方法调用:

public class Practice {
	public static void main(String[] args) {
		new Outer().method();
	}
}

interface Inter {
	public abstract void print1();
	public abstract void print2();
}

class Outer {
	public void method(){
		new Inter(){

			@Override
			public void print1() {
			System.out.println("1");	
			}

			@Override
			public void print2() {
				System.out.println("2");	
			}
			
		}.print1();
		new Inter(){
			
			@Override
			public void print1() {
				System.out.println("1");	
			}
			
			@Override
			public void print2() {
				System.out.println("2");	
			}
			
		}.print2();
	}
}

调用多个方法每次都需要重新创建并且需要全部重写,明显很麻烦。改进方法如下:

class Outer {
	public void method(){
		Inter inter = new Inter(){

			@Override
			public void print1() {
			System.out.println("1");	
			}

			@Override
			public void print2() {
				System.out.println("2");	
			}
			
			public void print3(){
				System.out.println("3");
			}
		};
		inter.print1();
		inter.print2();
		
	}
}

父类引用指向子类对象。但是该引用不能调用匿名内部类特有的方法,但是因为本身没有子类,只有子类对象,无法向下转型。所以,不建议使用!一般匿名内部类只在调用一次方法的时候使用。

 

匿名内部类在开发中的使用

当做参数传递,类似于匿名对象,不同的是他是作为类或者接口的子类传入,并且需要重写方法。

多线程和监视器的时候常用。

实际代码如下:

public class Practice {
	public static void main(String[] args) {
		PersonDemo pd = new PersonDemo();
		pd.method(new Person(){

			@Override
			public void show() {
				// TODO Auto-generated method stub
				System.out.println("匿名内部类的实际开发");
			}
			
		});
	}
}

abstract class Person{
	public abstract void show();
}

class PersonDemo{
	public void method(Person p){
		p.show();
	}
}

 

匿名内部类的面试题:

//在*位置填入适当代码,使程序顺利运行且最后的显示结果为HelloWorld
public class Practice {
	public static void main(String[] args) {
		Outer.method().show();
	}
}

interface Inter {
	void show();
}

class Outer{
	*
}

分析:

因为method直接调用,所以该方法为static的,并且方法名为method。

因为可以调用show,所以该方法返回值一定是Inter对象或者Inter的子类。因为接口不能被实例化,所以是Inter子类,因为没有自雷,所以一定是匿名内部类,在类的内部重写show方法,使之为HelloWorld的输出语句。

所以在*中的代码为:

public static Inter method(){
		return new Inter(){

			@Override
			public void show() {
				// TODO Auto-generated method stub
				System.out.println("HelloWorld");
			}
			
		};
	}

 

5.eclipse的使用

不同项目交互:打jar包,jar包放进lib文件夹,方便管理,添加进classpath(build path)。

 

删除勾选从磁盘删除,不勾选只删除项目。

 

所有和视图有关的都在window里面,视图混乱可以使用

 

6.Object类

hashcode,getClass,toString,equals

hashcode查看不同对象是否一样

getclass同时了解返回类型的其他方法

toString源码源码组成及重写(直接打印对象的引用,默认调用toString方法)

equals源码组成及重写(默认比较地址没实际意义,自己写的注重属性的比较)

 

==和equals方法的区别

共同点:返回值都是boolean类型,都可以用于比较

不同点:==是运算符,既可以比较基本数据类型,也可以比较引用数据类型。基本数据类型比较的是值,引用数据类型比较的是地址。

equals只能比较引用数据类型,因为它是方法,只有对象可以调用,但是因为它比较的是引用对象的地址值,没有实际意义,所以我们一般重写该方法。

 

7.Scanner类

public static final InputStream in; 标准的输入流,对应着键盘录入。

 intnextInt() 
          将输入信息的下一个标记扫描为一个 int。

构造成功后调用上述方法,如果输入的不是对应类型的值,报错如下:

Exception in thread "main" java.util.InputMismatchException

查询对应API,发现是类型不匹配导致的问题。解决方法就是调用这个方法:

 booleanhasNextInt() 
          如果通过使用 nextInt() 方法,此扫描器输入信息中的下一个标记可以解释为默认基数中的一个 int 值,则返回 true。

通过加入判断,如果是该类型再调用nextInt方法,不是输出提示语句。

 

nextInt和nextLine方法分别获取两次可以正常运行,但是先获取int再获取line就会出错,为什么呢?

int后自带/r /n,而nextLine就是一次为界限的,通过读取nextInt的/r /n,他就认为已经完成了输入,所以nextLine获取不到对应的值。

 

8.String类

String 类代表字符串。Java 程序中的所有字符串字面值(如 "abc" )都作为此类的实例实现。

需要注意的是字符串是常量,一旦被赋值就无法改变

String类的构造方法

String() 
          初始化一个新创建的 String 对象,使其表示一个空字符序列。
String(byte[] bytes) 
          通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String

String(byte[] bytes, int offset, int length) 
          通过使用平台的默认字符集解码指定的 byte 子数组,构造一个新的 String

无参构造的String类中是空的。

有参可以使用byte,char等数组进行构造,offset是偏移量,表示开始的索引,length表示要构造的长度。

 

面试题五则:

	public static void main(String[] args) {
		//demo1();
		//demo2();
		//demo3();
		//demo4();
		String s1 = "ab";
		String s2 = "abc";
		String s3 = s1 + "c";
		System.out.println(s3 == s2);           //false
		System.out.println(s3.equals(s2)); 		//true
	}

	private static void demo4() {
		//byte b = 3 + 4;						//在编译时就变成7,把7赋值给b,常量优化机制
		String s1 = "a" + "b" + "c";
		String s2 = "abc";
		System.out.println(s1 == s2); 			//true,java中有常量优化机制	
		System.out.println(s1.equals(s2)); 		//true
	}

	private static void demo3() {
		String s1 = new String("abc");			//记录的是堆内存对象的地址值		
		String s2 = "abc";						//记录的是常量池中的地址值
		System.out.println(s1 == s2); 			//false
		System.out.println(s1.equals(s2)); 		//true
	}

	private static void demo2() {
		//创建几个对象
		//创建两个对象,一个在常量池中,一个在堆内存中
		String s1 = new String("abc");		
		System.out.println(s1);
	}

	private static void demo1() {				//常量池中没有这个字符串对象,就创建一个,如果有直接用即可
		String s1 = "abc";
		String s2 = "abc";
		System.out.println(s1 == s2); 			//true	
		System.out.println(s1.equals(s2)); 		//true
	}

最后一个面试题参考资料JDK的api中String描述:

Java 语言提供对字符串串联符号("+")以及将其他对象转换为字符串的特殊支持。字符串串联是通过 StringBuilder(或 StringBuffer)类及其 append 方法实现的。字符串转换是通过 toString 方法实现的,该方法由 Object 类定义,并可被 Java 中的所有类继承。(相当于创建了一个StringBuffer接收数值,再调用toString方法转化为String)下面是上述案例的内存图:

 

9.String类的判断功能

        * boolean equals(Object obj):比较字符串的内容是否相同,区分大小写
        * boolean equalsIgnoreCase(String str):比较字符串的内容是否相同,忽略大小写
        * boolean contains(String str):判断大字符串中是否包含小字符串
        * boolean startsWith(String str):判断字符串是否以某个指定的字符串开头
        * boolean endsWith(String str):判断字符串是否以某个指定的字符串结尾
        * boolean isEmpty():判断字符串是否为空。

值得注意的是isEmpty方法。如果String = ""为空字符串,如果String =null则会报错:

Exception in thread "main" java.lang.NullPointerException

null和""的区别:

""是字符串常量,也就是String类的对象,所以可以调用方法。

null是空常量,不能调用任何方法,否则会报空指针异常。

 

模拟登陆小程序

public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		for (int i = 0; i < 3; i++) {
			System.out.println("请输入用户名:");
			String username = sc.nextLine();
			System.out.println("请输入密码:");
			String password = sc.nextLine();
			if("shuaige".equals(username) && "shiwo".equals(password)){
				System.out.println("登陆成功");
				break;
			}else{
				if(i==2){
					System.out.println("今天次数用完了,请明天再来哦~");
				}else{
					System.out.println("用户名或密码错误,请重新输入。你今天还有"+(2-i)+"次机会!");
				}
			}
		}
	}

很简单,需要注意的是,在应用中,涉及到判断的时候,尽量用常量字符串调用变量字符串,这样可以防止出现空指针的错误。

 

10.String的获取功能

     int length():获取字符串的长度。不同于数组,数组的length是属性,String的length是方法,数组的length后面没有()。
     char charAt(int index):获取指定索引位置的字符
     int indexOf(int ch):返回指定字符在此字符串中第一次出现处的索引。
     int indexOf(String str):返回指定字符串在此字符串中第一次出现处的索引。
     int indexOf(int ch,int fromIndex):返回指定字符在此字符串中从指定位置后第一次出现处的索引。
     int indexOf(String str,int fromIndex):返回指定字符串在此字符串中从指定位置后第一次出现处的索引。
     lastIndexOf:从后向前查,但是索引不变。
     String substring(int start):从指定位置开始截取字符串,默认到末尾。(左闭右开,含头不含尾)
     String substring(int start,int end):从指定位置开始到指定位置结束截取字符串。

String s = "zheshixianjing";
		String s1 = s.substring(6, 10);
		System.out.println(s);
		System.out.println(s1);

这段代码可以发映出substring的两个特点,一个是substring包含头不包含尾,另一个就是substring是产生了一个新的字符串,不会对原字符串造成影响。

面试题:统计不同类型的字符出现的次数:

public static void main(String[] args) {
		String s = "dsuafhqfeAGYBHJBHGF12349>";
		int small = 0;
		int big = 0;
		int number = 0;
		int other = 0;
		for (int i = 0; i < s.length(); i++) {
			if (s.charAt(i) >= 'a' && s.charAt(i) <= 'z') {
				small++;
			} else if (s.charAt(i) >= 'A' && s.charAt(i) <= 'Z') {
				big++;
			} else if (s.charAt(i) >= '1' && s.charAt(i) <= '9') {
				number++;
			} else {
				other++;
			}
		}
		System.out.println("小写字母有" + small + "个,大写字母有" + big + "个,数字有" + number + "个,其他字符有" + other + "个。");
	}

 

11.String类的转换功能


       byte[] getBytes():把字符串转换为字节数组。
       char[] toCharArray():把字符串转换为字符数组。
       static String valueOf(char[] chs):把字符数组转成字符串。
       static String valueOf(int i):把int类型的数据转成字符串。
       注意:String类的valueOf方法可以把任意类型的数据转成字符串。
    
    
        String toLowerCase():把字符串转成小写。(了解)
        String toUpperCase():把字符串转成大写。
        String concat(String str):把字符串拼接。
   

到这里,统计字符串中不同字符就有了两种方法,一种是先遍历,在对应位置进行charAt获取当前索引位置的值,另一种是直接调用getBytes先把字符串转化为字符数组,然后再遍历。

concat的拼接和String+String效果一样,但是实际上+功能更为强大。

两个小Demo。分别是按标准格式转换成首字母大写的字符串,使用了链式编程。和把数组按照字符串的格式输出。

	public static void demo2() {
		int[] arr = {1,2,3,4};
		String f = "[";
		System.out.print(f);
		for (int i = 0; i < arr.length; i++) {
			if(i==arr.length-1){
				System.out.print(arr[i]+"]");
			}else{
				System.out.print(arr[i]+",");
			}
		}
	}

	public static void demo1() {
		String s = "BiaozzGGnsugwuHD";
		String substring = s.substring(0, 1).toUpperCase().concat(s.substring(1).toLowerCase());
		System.out.println(substring);
	}

 

12.String类的其他功能

         A: String的替换功能及案例演示
              String replace(char old,char new)
              String replace(String old,String new)
         B:  String的去除字符串两空格及案例演示
              String trim()
         C: String的按字典顺序比较两个字符串及案例演示
              int compareTo(String str)(暂时不用掌握)
              int compareToIgnoreCase(String str)(了解)
             

trim方法只去两边的空格。

 

13.String类API的综合使用案例

public class Practice1 {
	/*
	 * 键盘录入字符串,然后反转
	 */
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入你想要转换的字符串:");
		String nextLine = sc.nextLine();
		char[] array = nextLine.toCharArray();
		String s = "";
		for (int i = array.length - 1; i >= 0; i--) {
			s = s + array[i];
		}
		System.out.println(s);
	}

}
public class Practice2 {
	/*
	 * 在大串中查找小串出现的次数
	 */
	public static void main(String[] args) {
		String da = "woaishenghuo,shenghuohenmeihao,shenghuohenyouqu";
		String xiao = "shenghuo";
		//设定索引值
		int index = 0;
		//设定计数器
		int count = 0;
		while ((index = da.indexOf(xiao)) != -1) {
			count++;
			//设定继续查找的长字符串
			da = da.substring(index + xiao.length());
		}
		System.out.println(count);
	}

}

思路:找到就去掉前面部分,在剩余的里面继续找。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值