基础类库学习(上)

基础类库的学习方法

  • 习惯使用API
  • 通过练习 记忆常用类的作用和其常用方法
API(Application Programming Interface,应用程序接口)是一些预先定义的接口(如函数、HTTP接口),或指软件系统不同组成部分衔接的约定。
[1]  用来提供应用程序与开发人员基于某软件或硬件得以访问的一组例程,而又无需访问源码,或理解内部工作机制的细节。
API:一组相关功能的类和接口的集合:类和接口功能、及其成员的使用说明

api的结构

  • 1 类结构
    image

2 类的简介

image-20210830112342808

3 类成员变量:一般都是静态的

image-20210830112420232

4 类构造方法

image-20210830112446182

5 类的实例方法:重写/特有的

image-20210830112520853

6类的实例方法:继承父类

image-20210830112552844

7 成员的详细说明

image-20210830112623050

image-20210830112645186

1、Object

概念

类 Object 是类层次结构的根类。每个类都使用 Object 作为超类。所有对象(包括数组)都实现这个类的方法。
一个类没有继承其他类  默认继承Object

常用方法

image-20210830113134156

package com.zhiyou100.day06;

public class Test04Object {
	public static void main(String[] args) {
		
		//1  String toString(): 获取当前对象的字符串表示形式
		//特点1:toString方法获取的是当前对象的字符串表示形式:类型@16进制内存地址
		 Student s1=new Student();
		 System.out.println("s1="+s1.toString());//s1=com.zhiyou100.day06.Student@15db9742
		 
		 //特点2: 打印对象或者字符串拼接  默认调用对象的toString方法
		 System.out.println("s1="+s1);//s1=com.zhiyou100.day06.Student@15db9742
		 System.out.println(s1);//com.zhiyou100.day06.Student@15db9742
		 
		 //2 int hashCode(); 获取对象的内存地址
		 System.out.println("s1.hashCode()="+s1.hashCode());//2110121908
		 System.out.println(s1+":"+s1.hashCode()+":"+chang16(s1.hashCode()));//com.zhiyou100.day06.Student@15db9742:366712642:15db9742
		 
//		 for(int i=0;i<20;i++){
//			 System.out.println(chang2(i));
//		 }
//		 for(int i=0;i<100;i++){
//			 System.out.println(chang16(i));
//		 }
		 
		 //3 Class getClass();获取对象的类的字节码文件对象
		 System.out.println(s1.getClass());
		 //Class类中的方法:1 String getName() 获取类的全程
		 //                2 String getSimpleName() 获取类的简称
		 System.out.println("getName="+s1.getClass().getName());//getName=com.zhiyou100.day06.Student
		 System.out.println("getSimpleName="+s1.getClass().getSimpleName());//getSimpleName=Student
		 
		 
		 //4 boolean equals(obj):判断当前对象和参数引用是否指向同一个对象
		 Student s11=new Student("韩梅梅",'女',11);
		 Student s12=new Student("韩梅梅",'女',11);
		 Student s13=s11;
		 System.out.println(s11.equals(s12));
		 System.out.println(s11.equals(s13));
		 //在电脑内存中:s11和s12不是同一个对象
		 //但在现实生活中:s11和s12的数据完全相同  可以理解为都在描述同一个现实实物 需要其euqals比较时返回true
		 //需要重写equals方法
		 // 重写要求:如果所有参数相同 返回true
		 
		 
		 
		 
		 

	}
	//写一个方法把10进制转换为2进制
		public static String chang16(int n){
			char[] arr={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};//定义一个数组 记录所有的16进制字符
			//10进制:每个位数上有10个选择0-9  逢10进1
			//16进制:每个位数上有12个选择0-9 a-f  逢16进1
			
			//获取n的m的进制的字符串结构:1 拿n余m 2然后n除m 除数循环进行1和2 操作 直到除数为0
			//把所有余数倒着拼成字符串即可
			 String result="";
			 int k=n;
			 while(true){
				 int yuShu=k%16;//获取余数
				 result=arr[yuShu]+result;
				 k=k/16;//获取除数
				 if(k==0){
					 break;
				 }
			 }
			 return result;
			
		}
	//写一个方法把10进制转换为2进制
	public static String chang2(int n){
		//10进制:每个位数上有10个选择0-9  逢10进1
		//16进制:每个位数上有12个选择0-9 a-f  逢16进1
		
		//获取n的m的进制的字符串结构:1 拿n余m 2然后n除m 除数循环进行1和2 操作 直到除数为0
		//把所有余数倒着拼成字符串即可
		/*0  0
		 *1  1
		 *2  10
		 *3  11
		 *4  100
		 *5  101
		 *6  110
		 *7  111
		 *8  1000
		 *9  1001
		 *10 1010 
		 * */
		 String result="";
		 int k=n;
		 while(true){
			 int yuShu=k%2;//获取余数
			 result=yuShu+result;
			 k=k/2;//获取除数
			 if(k==0){
				 break;
			 }
		 }
		 return result;
		
	}
}
class Student extends Object{
	String name;
	char sex;
	int age;
	public Student(String name, char sex, int age) {
		super();
		this.name = name;
		this.sex = sex;
		this.age = age;
	}
	public Student() {
		super();
	}
	public boolean equals(Object obj){
		//判断当前对象this和参数对象obj的属性是否完全相同
		//通过instanceof判断参数对象的类型
		if(!(obj instanceof Student)){
			return false;
		}
		//向下转型
		Student s=(Student)obj;
		//判断属性是否完全相同
		//注意:name是String类型的:字符串做比较通过equals方法
		return s.age==this.age&&s.sex==this.sex&&s.name.equals(this.name);
	}
}

重点

1 Object类是所有类的直接或者间接父类
2 Object类中所有的方法  及其方法作用
3 equals方法的重写

2、System

概念

与系统相关的所有功能和属性
没有提供构造方法 不能实例化,所有方法和属性都是static  所以通过类名即可调用

属性

static PrintStream err;系统错误输出流
static PrintStream out;系统标准输出流
static InputStream in;系统标准输入流

方法

static void exit(int status)  :虚拟机退出:参数为0正常退出 非0异常退出
static void gc()              :启动垃圾回收期
static long currentTimeMillis() :获取当前时间的毫秒值:参照历元(1970/1/1 0:0:0)
  • 代码
package com.zhiyou100.day06;

import java.util.Scanner;

public class Test05System {
	public static void main(String[] args) {
		//System的属性
		//		static PrintStream err;系统错误输出流
		//		static PrintStream out;系统标准输出流
		//      static InputStream in;系统标准输入流:键盘输入的内容
		//      注意1:当out和err同时打印输出时  顺序无法预期
		//            out和err是两个不同的线程  同时竞争console
		//      注意2:err输出的是红色:一般用于异常处理
				System.out.println("out11");
				System.err.println("err011");
				System.out.println("out12");
				System.err.println("err012");
				System.out.println("out13");
				System.err.println("err013");
				System.out.println("out14");
				System.err.println("err014");
				//Student06.t.show(1);
		//		static InputStream in;系统标准输入流
				//System.out.println(1/0);//ArithmeticException: / by zero
				
				//static InputStream in;系统标准输入流:键盘输入的内容
				//获取系统输入流的监控器器对象
				Scanner  sr=new Scanner(System.in);
				//Scanner类中的方法:
				//in nextInt();获取系统输入的一个int数据
				//String next();获取系统输入的一个字符串数据
				//注意:这两个方法都是阻塞方法::: 如果某个操作不执行 程序就一直等待,只有执行某个操作 程序才继续向下执行
//				System.out.println("请输入一个int数据:");
//				int n=sr.nextInt();//java.util.InputMismatchException
//				System.out.println("n="+n);
				System.out.println("请输入一个字符串:");
				String str1=sr.next();
				System.out.println("str1="+str1);
				System.out.println("请输入一行数据:");
				String str2=sr.nextLine();
				//建议不要把next()、nextInt()与nextLine方法混合使用
				//输入完字符串后:点击enter键 ;字符串输入完毕 提交数据+换行
				//          abab +enter
				System.out.println("str2="+str2);
				
		//System类的方法:
				//static void exit(int status)  :虚拟机退出:参数为0正常退出 非0异常退出
				//static void gc()              :启动垃圾回收期
				//static long currentTimeMillis() :获取当前时间的毫秒值:参照历元(1970/1/1 0:0:0)
				
				//System.exit(0);//虚拟机停止:下面的代码不再执行
				long time=System.currentTimeMillis();
				System.out.println(time/1000/3600/24/365);//51 
				
				
	}
}
class Teacher06{
	void show(int n){
		System.out.println("老师的show方法!!!n="+n);
	}
}
class Student06{
	private Student06(){}
	//static Teacher06  t=new Teacher06();
	static Teacher06  t;
	static{//静态代码块::给静态成员变量赋值::类加载时执行一次
		t=new Teacher06();
	}
}

重点

1 Scanner  sr=new Scanner(System.in);的使用
2 static long currentTimeMillis()
3 static void gc()              :启动垃圾回收期

3、Math

概念

和数学运算相关的方法和属性
没有构造方法 不能实例化  所有成员都是静态的

属性

static double E 
          比任何其他值都更接近 e(即自然对数的底数)的 double 值。 
static double PI 
          比任何其他值都更接近 pi(即圆的周长与直径之比)的 double 值。 

方法

//1 求绝对值:static int abs(int a)  
		   
//2 求次方:static double cbrt(double a)  :对a开三次方
//         static double sqrt(double a)  :对a开平方 
//         static double pow(double a, double b) :求a的b次方

//3 求近似值:static double ceil(double a)    :获取大于等于参数的最小整数
//           static double floor(double a)  :获取小于等于参数的最大整数
//           static double rint(double a)   :四舍六入五取偶数
//           static long round(double a)    :正宗的四舍五入

//4 随机:[0,1)  static double random()  
package com.zhiyou100.day06;


public class Test06Math {
	public static void main(String[] args) {
		   System.out.println(Math.E);//2.718281828459045
		   System.out.println(Math.PI);//3.141592653589793
		   
		   
		   //Math类相关方法
		   //1 求绝对值:static int abs(int a)  
		   
		   //2 求次方:static double cbrt(double a)  :对a开三次方
		   //         static double sqrt(double a)  :对a开平方 
		   //         static double pow(double a, double b) :求a的b次方
		   for (int i = 1; i <=10; i++) {
			    System.out.println("对"+i+"开三次方:"+Math.cbrt(i));
			    System.out.println("对"+i+"开平方:"+Math.sqrt(i));
			    System.out.println("求"+i+"的2次方="+Math.pow(i, 2));
		   }
		   
		   //3 求近似值:static double ceil(double a)    :获取大于等于参数的最小整数
		   //           static double floor(double a)  :获取小于等于参数的最大整数
		   //           static double rint(double a)   :四舍六入五取偶数
		   //           static long round(double a)    :正宗的四舍五入
		   
		   for (int i = 1,n=10; i <=30; i++) {
			    double m=n+i*1.0/10;
			    System.out.println("m="+m);
			    //System.out.println("Math.ceil("+m+")="+Math.ceil(m));
			    //System.out.println("Math.floor("+m+")="+Math.floor(m));
			    //System.out.println("Math.rint("+m+")="+Math.rint(m));
			    //System.out.println("Math.round("+m+")="+Math.round(m));
		   }
		   
		   //4 随机:[0,1)  static double random()  
		   for (int i = 0; i < 10; i++) {
			   //System.out.println(i+":::"+Math.random());
		   }
		  //随机1到10整数[1,10]
		   for (int i = 0; i < 100; i++) {
			   System.out.println(i+"::::"+Math.random());//[0,1)
			   System.out.println(i+"::::"+Math.random()*10);//[0,10)
			   System.out.println(i+"::::"+(int)(Math.random()*10));//[0,9]
			   System.out.println(i+"::::"+(int)(Math.random()*10+1));//[1,10]
		   }
		   //随机a到b的整数[a,b]
		   //乘以范围[b-a+1], 加上起始值a,强制转换为int
		   //[0,1)---乘以范围---[0,b-a+1)
		   //[0,b-a+1)---加上起始值a---[a,b+1)
		   //[a,b+1)---强制转换为int---[a,b]
		   
	}
}

练习

  • 1 Object
定义一个Student类有属性 名字 年龄 性别 成绩
1:所有属性私有化封装
2:提供各种需求的构造方法
3:重写toString方法:打印所有属性的值
4:重写equals方法: 如果名字相同 性别相同 年龄相差2岁以内 分数相差10分以内 返回true
  • 2 System
1 获取今天的年月日时分秒:需要判断闰年(可以被4整除 但不能被100整除  + 可以被400整除)
  • 3 Math
1 写一个方法 随机一个4位数的字符串:字符可以由数字 大小写字母
  • 4 游戏
随机一个1-20的一个数字n
通过系统出入流 来猜测n的具体值: 猜对结束  猜错告诉他 输入的数大 还是小了
打印猜对的次数

4、String字符串(重点)

概念

字符序列

特点

//特点1: 创建字符串对象的两种方式
//通过双引号+通过构造方法
String s1="114";//通过双引号来创建字符串对象
String s2=new String("114");//通过构造方法创建对象
//String已经重写了equals方法:用于判断两个引用指向的对象的字符序列是否相同
System.out.println(s1==s2);//false


//特点2:字符串对象是常量:字符串对象一旦创建 字符序列不能更改 如果更改就是又创建了一个新的对象
s1="abc";s2=s1;
s1=s1+"1";
System.out.println(s1==s2);//false
s1="a"+"b"+"c"+"e"+"d";//一共有9个对象
//为了节省内存空间:尽量避免出现大量的字符串拼接


//特点3:字符串常量池:通过双引号创建的字符串对象 存放在字符串常量池中
//                  如果要通过双引号创建字符串对象前  先判断常量池中是否有相同序列 有则直接获取其地址使用即可
//                                                 如果常量池中没用相同相同 才创建
String s11="abc",s12="abc";//通过双引号创建的字符串对象
String s21=new String("abc");
String s22=new String("abc");//通过构造方法创建的字符串对象
//equals判断s11 s12 s21 s22返回都是true: 四个字符序列完全相同
//== 是判断是否同一个对象
System.out.println("s11==s12   "+(s11==s12));//true
System.out.println("s21==s22   "+(s21==s22));//false
System.out.println("s11==s21   "+(s11==s21));//false

equals和==的区别

//equals和==的区别
//equals是Object类的方法
//== 是比较运算符
//相同之处 都可以用于对象之间做比较
//不同之处1:==可以比较引用数据类型和基本数据类型
//          equals只能比较引用数据类型
//不同之处2:==比较引用数据类型时:只能判断两边的引用是否指向同一个对象
//          Object类的equals方法是判断当前引用和参数引用是否指向同一个对象
//          但可以被子类重写

构造方法

//String类的构造方法
//1 无参数的构造方法:String() 
String s1;
s1=new String();//字符串对象:字符串序列为空
s1=new String("");//字符串对象:字符串序列为空
s1="";//常量池中创建的字符串对象:字符串序列为空
s1=null;//null为常量 此引用地址栏值为null 说明此引用没用指向任何对象

//2 参数是数组的构造方法:
//String(byte[] bytes) :通过默认平台的默认编码集吧字节数组转换为字符
//String(byte[] bytes, int offset, int length) :字节数组的一部分
//String(byte[] bytes, int offset, int length, Charset charset) :指定编码集
//String(byte[] bytes, int offset, int length, String charsetName) 
//String(byte[] bytes, String charsetName) 
//String(char[] value) 
//String(char[] value, int offset, int count) 
//String(int[] codePoints, int offset, int count)  
//常见编码集:中文:UTF-8    (GBK  GB2312  GB18030)(GB系列)
//           无中文:ASCII   ISO-8859-1 
//注意1:所有的编码集兼容ascii码表
//注意2:UTF-8中文占3个字节  GB中文占2个字节  // 65536

//3 参数是字符串对象:String(String original) 
//创建一个与参数字符串对象相同序列的副本对象
String s2=new String("123");//共创建了两个字符串对象
//先通过双引号在常量值中创建一个字符序列为123的字符串对象
//再通过new 调用构造方法创建一个相同序列的副本对象

普通方法

public static void change(){
    //3 转换
    //  3.1 字符串拼接
    //       String concat(String str)   
    //  3.2 替换
    //      String replace(char oldChar, char newChar) 
    //      String replace(CharSequence target, CharSequence replacement)  
    //  3.3 大小写转换
    //      String toLowerCase() 
    //      String toUpperCase() 
    //  3.4 去除两边的空格
    //      String trim()  
    //  3.5 把参数数据/对象转换为字符串
    //      static String valueOf(Object b)
    String s="1231231251271ab";
    String ss=s.replace('1', '0');
    System.out.println(s+"::"+ss);//1231231251271ab::0230230250270ab

    ss=s.replace("1", "");//删除所有的1字符
    System.out.println(s+"::"+ss);//1231231251271ab::23232527ab

    s="   123   456   ";
    ss=s.trim();
    System.out.println("---"+s+"---::::---"+ss+"----");

}

public static void panDuan(){
    //1 判断
    //  1.1 逐个字符做比较
    //       int compareTo(String anotherString) 
    //       int compareToIgnoreCase(String str) :不区分大小写
    //  1.2 判断是否包含指定的子串
    //       boolean contains(CharSequence s)    
    //  1.3 判断是否以参数开头/结尾
    //       boolean endsWith(String suffix)  
    //       boolean startWith(String prefix)
    //  1.4  字符序列判断是否相同
    //       boolean equals(Object anObject)  
    //       boolean equalsIgnoreCase(String anotherString)  :不区分大小写
    //  1.5 判断是否为空
    //        boolean isEmpty()  :length==0
    //  1.6 正则判断
    //        boolean matches(String regex)  

    //compareTo:拿当前字符串和参数字符串按字典顺序逐个字符做比较
    // 返回正数 当前字符串大 返回负数 当前字符串小  返回0 字符序列完全相同
    System.out.println("123".compareTo("102"));//2
    System.out.println("123".compareTo("123"));//0
    System.out.println("123".compareTo("ab"));//-48

    System.out.println("123456".contains("134"));//false
    System.out.println("123456".endsWith("56"));//true
    System.out.println("123456".endsWith("456"));//true

    System.out.println("123".equals(new String("123")));//true
}
public static void huoQu() throws UnsupportedEncodingException{
    //2 获取
    //  2.1 获取指定下标出的字符
    //       char charAt(int index)  
    //  2.2 获取当前字符串对应的字节数组
    //       byte[] getBytes() :使用平台默认编码集
    //       byte[] getBytes(String charsetName)    :使用指定编码集
    //  2.3 获取参数字符/子串 第一次出现的下标:如果没用找到返回-1
    //        int indexOf(int ch)  
    //		  int indexOf(int ch, int fromIndex) 
    //		  int indexOf(String str) 
    //		  int indexOf(String str, int fromIndex) 
    //        int lastIndexOf(int ch) 
    //        int lastIndexOf(int ch, int fromIndex) 
    //        int lastIndexOf(String str) 
    //        int lastIndexOf(String str, int fromIndex)  
    //  2.4 获取字符长度
    //        int length()  
    //  2.5 切割
    //        String[] split(String regex)  
    //  2.6 截取子串
    //        CharSequence subSequence(int beginIndex, int endIndex) :截取beginIndex到endIndex-1位置处的子串
    //        String substring(int beginIndex) 
    //        String substring(int beginIndex, int endIndex)  
    //  2.7 获取字符数组
    //        char[] toCharArray()  

    //遍历字符串
    String s="abcdef12345";
    for(int i=0;i<s.length();i++){
        System.out.println(s+":的第"+(i+1)+"个字符是:"+s.charAt(i));
    }
    //获取字符串对应的字节数组
    s="123abc苗天保";
    byte[] arr=s.getBytes();//使用平台默认编码集:GBK
    for(int i=0;i<arr.length;i++){
        System.out.print(arr[i]+(i==arr.length-1?"\n":" "));
    }
    arr=s.getBytes("utf-8");//使用指定编码集:UTF-8 :
    //使用字符串utf-8表示编码集  编译器无法判断此字符串表示的编码集是否存在
    //只有虚拟机运行后才知道是否错误:需要再方法声明上添加 throws 异常类型
    for(int i=0;i<arr.length;i++){
        System.out.print(arr[i]+(i==arr.length-1?"\n":" "));
    }

    s="123123123412112";
    System.out.println("字符1第1次出现的位置:"+s.indexOf('1'));//0
    System.out.println("字符1第2次出现的位置:"+s.indexOf('1',1));//3
    System.out.println("字符1第3次出现的位置:"+s.indexOf('1',4));//6
    showIndex(s,'1');

    //字符串切割: 如果开头或者中间是连续多个"刀" 会形成多个空字符串
    //           但如果以多个"刀"结尾  不会形成空字符串
    s="111231241111251781ab1111";
    String[] arrs=s.split("1");
    for (int i = 0; i < arrs.length; i++) {
        System.out.println("arrs["+i+"]="+arrs[i]);
    }


    //截取子串
    s="abcdefghijklmn";
    System.out.println(s.subSequence(1, 5));//bcde
    System.out.println(s.substring(1, 5));//bcde
    System.out.println(s.substring(1));//bcdefghijklmn

    char[] arrChar=s.toCharArray();
    System.out.println(arrChar);//abcdefghijklmn
}
//获取字符串中指定字符出现的所有位置
public static void showIndex(String s,char c){
    int index=-1;
    int ciShu=0;
    while(true){
        ciShu++;
        index=s.indexOf(c,index+1);//每次都从上一次+1位置出找字符c
        if(index==-1){
            break;
        }
        System.out.println(s+"中字符"+c+"第"+ciShu+"次出现的位置:"+index);//6
    }
}

4.1、String作业

package com.zhiyou100.day08;

import java.util.Arrays;

public class ZuoYe01 {

	public static void main(String[] args) {
//		get1("ancabcavcbcbbccaaa23",'a');
//		change1("ancABDBD123&*^&&呵呵呵");
//		get2("ancabcavcbcbbccaaa23");
//		getInt("123");
//		get3("abc123sjshd09as3");
//		change2("我...我...我....叫...叫....叫....苗...苗.....苗...天保");
//		change3(123456789);
//		change3(6009);//零后面的单位 删除
//		change3(10006009);//1千万零6千零9元  1千万6千零9元
		
		heDong();

	}
//	 *1: 写一个方法static void get1(String s,char c);打印s中c出现的次数
	  public static void get1(String s,char c){
		  //1 charAt
		  //2 indexOf
		  //3 replace
		  String ss=s.replace(c+"", "");
		  System.out.println(s+" 的"+c+"字符共有"+(s.length()-ss.length())+"个!");
	  }
	
//	 *2: 写一个方法static void change1(String s);把s中大写转换为小写 小写转换为大写 删除数字
	  public static void change1(String s){
		  //定义一个空字符串 记录结果
		  String ss="";
		  //遍历s
		  for(int i=0;i<s.length();i++){
			  //获取当前字符
			  char c=s.charAt(i);
			  //判断当前字符的类型
			  //字符也可以做比较  通过编码表
			  if(c>='A'&&c<='Z'){
				  //c=(char)(c+('a'-'A'));//字符和数字完全等价
				  ss+=(c+"").toLowerCase().charAt(0);
			  }else if(c>='a'&&c<='z'){
				  ss+=(c+"").toUpperCase().charAt(0); 
			  }else if(c<'0'||c>'9'){
				  ss+=c;
			  }
		  }
		  System.out.println(s+"::::"+ss);
	  }
//	 *3: 写一个方法static void get2(String s);打印参数字符串中所有的字符 但不能重复:123abc123aaa--123abc
	  public static void get2(String s){
		  //定义一个空字符串 记录结果
		  String ss="";
		  //遍历s
		  char[] arr=s.toCharArray();
		  for (char c : arr) {
			   //判断当前字符c是否再ss中 如果已有 不加  如果没有 加
//			  if(!(ss.contains(c+""))){
//				  ss+=c;
//			  }
			  if(ss.indexOf(c)==-1){
				  ss+=c;
			  }
		  }
		  System.out.println(s+"::::"+ss);
	  }
//   *8:写一个方法  static int change4(String s);  获取所有数字字符s对应的整数:"123"--123
	  public static int getInt(String s){
		  //"123"--123
		  //"1"-1  减去字符0即可
		  int n=0;
		  for(int i=s.length()-1,j=1;i>=0;i--,j*=10){//变量i记录的是下标 变量j每次*10
			   n+=(s.charAt(i)-'0')*j;
		  }
		  System.out.println(s+"::::"+n);
		  return n;
		  
		  
	  }
//	 *4: 写一个方法static int get3(String s);打印参数字符串中所有数字字符组成的最大整数:123abc08uy--83210
	  public static void  get3(String s){
		  //定义一个空字符串 记录结果
		  String ss="";
		  //遍历s
		  for(int i=0;i<s.length();i++){
			  char c=s.charAt(i);
			  if(c>='0'&&c<='9'){
				  ss+=c;
			  }
		  }
		  //ss中就是纯数字字符
		  //学过数组排序
		  char[] arr=ss.toCharArray();
		  for(int i=0;i<arr.length-1;i++){
			   for(int j=i+1;j<arr.length;j++){
				   if(arr[i]<arr[j]){
					   char c=arr[i];
					   arr[i]=arr[j];
					   arr[j]=c;
				   }
			   }
		  }
		  //把数组再转换为字符串
		  ss=new String(arr);
		  //把字符串转换为整数
		  int max=getInt(ss);
		  System.out.println(s+"::::"+max);
		  
	  }
	  
	  
//	 *5: 写一个方法static void change2(String s);去除叠词和.:  我...我...我....叫...叫....叫....苗...苗.....苗...天保
      public static void change2(String s){
    	  String ss;
    	  //去除期中的点
    	  ss=s.replace(".", "");
    	  System.out.println(s+":::"+ss);
    	  String ssNew="";
    	  //去除叠词:我我我叫叫叫苗苗苗天保
    	  //遍历ss
    	  for(int i=0;i<ss.length();i++){
    		  char c=ss.charAt(i);
    		  if(i==0){//第一个字符直接加
    			   ssNew+=c;
    		  }else{
    			  //判断当前字符是否和前面的字符一样 一样不加 不一样加
    			  char cc=ss.charAt(i-1);
    			  if(cc!=c){
    				  ssNew+=c;
    			  }
    		  }
    	  }
    	  System.out.println(s+"::::"+ssNew);
      }
//	 *6: 判断注册的账号和密码是否符合规则:
//	 *    账号规则:可以由数字字母、_、$组成  但必须有大写、小写  不能以数字开头  长度6-8位
//	 *    密码规则:只能是数字  长度6位
      public static boolean regist(String name,String pwd){
    	  if(name.length()<6||name.length()>8){
    		  return false;
    	  }
    	  //遍历name
    	  boolean bDX=false,bXX=false;//定义遍历记录是否包含大写 和小写
    	  for(int i=0;i<name.length();i++){
    		  //获取当前字符
    		  char c=name.charAt(i);
    		  if(i==0&&(c>='0'&&c<='9')){
    			  return false;
    		  }
    		  //判断是否为大小写
    		  if(c>='A'&&c<='Z'){//判断是不是大写
    			  bDX=true;
    		  }else if(c>='a'&&c<='z'){//判断是不是小写
    			  bXX=true;
    		  }
    		  //判断字符类型
    		  if(!((c>='A'&&c<='Z')||(c>='a'&&c<='z')||c>='0'&&c<='9')||(c=='_'||c=='$')){
    			  return false;
    		  } 
    	  }
    	  return bXX&&bDX;
      }
//	 *7:写一个方法static void change3(int n);
//	 *    打印整数n对应的大写人民币的写法:12345---壹万两千三百四十五元
      public static void change3(int n){//12345
    	  //未解决问题:多个零 需要出去
    	  String hanZi="零壹贰叁肆伍陆柒捌玖";
    	  String danWei="元十百千万十百千亿";
    	  //定义字符串记录结果
    	  String ss="";
    	  String s=n+"";
    	  for(int i=0;i<s.length();i++){
    		  //倒着获取字符
    		  char c=s.charAt(s.length()-1-i);//'6'
    		  //获取字符对应的汉字
    		  char cHanZi=hanZi.charAt(c-'0');
    		  //获取单位
    		  ss=cHanZi+""+(danWei.charAt(i))+ss;
    	  }
    	  System.out.println(ss);
      }
 
//	 *9: 数学黑洞:证明所有4位数除了完全重复的 其他所有数 最多7次按指定运算将进入数学黑洞
//	 *   (1)1354 ---- 获取其每个字符排列后的最大数5431
//	 *   (2)1354 ---- 获取其每个字符排列后的最小数1345
//	 *    (3) 最大数减去最小数:5431-1345= x
//	 *    (4) 如果x的值为6174 就打印其计算的次数
//	 *        如果x的值不是6174 就继续循环1 2 3 4步 直到为6174 
      public static void heDong(){
    	  for(int n=1000;n<=9999;n++){
    		  //排除完全重复的:1111 2222
    		  if(n%1111==0){ continue; }
    		  //定义变量记录次数
    		  int ciShu=0;
    		  int k=n;
    		  while(true){
    			 if(k==6174){
    				 System.out.println(n+":::计算到6174::需要的次数是"+ciShu);
    				 break;
    			 } 
    			 //获取各个位数的值
    			 int a=k%10,b=k/10%10,c=k/100%10,d=k/1000%10;
    			 //对abcd进行排序
    			 int[] arr={a,b,c,d};
    			 for(int i=0;i<arr.length-1;i++){
    				 for(int j=i+1;j<arr.length;j++){
    					 if(arr[i]<arr[j]){
    						 int t=arr[i];arr[i]=arr[j];arr[j]=t;
    					 }
    				 }
    			 }
    			 //获取最大值和最小值
    			 int min=arr[0]*1+arr[1]*10+arr[2]*100+arr[3]*1000;
    			 int max=arr[0]*1000+arr[1]*100+arr[2]*10+arr[3]*1;
    			 //获取差
    			 k=max-min;
    			 ciShu++;
    		  }
    	  }
      }
}

5、包装类

概念

java为了完全面向对象:为8种基本数据类型 提供了对应的8种包装类
1----把一个事物封装为对象-----提取事物的数据作为变量 提取事物的功能作为方法

对应关系

基本数据类型    包装类
byte          Byte
short         Short
char          Character
int           Integer
long          Long
float         Float
double        Double
boolean       Boolean

特点

1 八种包装类:包装类、字符串、基本数据类型之间的转换
2 八种包装类种的方法基本一致:只用学习一个即可Integer
3 八种有一个比较特殊的:Character

Integer中通用的方法

        int n;
		Integer in;
		String s;
		//包装类解决的问题:包装类对象、字符串、基本数据类型常量之间的相互转换
  //1  基本数据类型常量--->包装类对象
		//1.1  构造方法:Integer(int value) 
		in=new Integer(1);
		System.out.println(in);//1
		//1.2 静态方法:static Integer valueOf(int i) 
		in=Integer.valueOf(1);
		System.out.println(in);//1
		//1.3 自动装箱:包装类引用=基本数据类型数据;
		in=1;//编译器会自动把基本数据类型的数据 转换为包装类对象
		

   //2 包装类对象--->基本数据类型常量
		//2.1 普通方法:int intValue()  
		n=in.intValue();
		System.out.println(n);//1
		//2.2 自动拆箱:基本数据类型变量=包装类对象;
		n=in;//自动拆箱:编译器子自动由包装类对象获取其对应的基本数据类型值
		
   //3 字符串对象--->包装类对象
		 //3.1 构造方法:Integer(String s) 
		 in=new Integer("123");
		 //in=new Integer("123aab");//NumberFormatException
		 System.out.println(in);
		 //3.2 静态方法
		 //static Integer valueOf(String s) 
         //static Integer valueOf(String s, int radix) //使用指定的进制radix解析字符串s 
		 in=Integer.valueOf("1234");
		 System.out.println(in);
		 in=Integer.valueOf("1111",2);
		 System.out.println(in);//15

   //4 包装类对象--->字符串对象
         //4.1 字符串拼接:连接一个空字符串
		 s=in+"";
		 System.out.println(s);//15
		 //4.2 普通方法:String toString()  
		 s=in.toString();
		 System.out.println(s);
		 
   //5 字符串对象--->基本数据类型常量
		  //5.1 静态方法:static int parseInt(String s)  
		  //             int parseInt(String s, int radix)  :指定进制
		  n=Integer.parseInt("123");
		  System.out.println(n);
		  //n=Integer.parseInt("123abc");//NumberFormatException
		  System.out.println(n);
		  n=Integer.parseInt("111",2);
		  System.out.println(n);//7
		  
	//6 基本数据类型常量--->字符串对象
		   //6.1 字符串拼接
		   s=n+"";
		   System.out.println(s);
		   //6.2 静态方法
		   // static String toBinaryString(int i) :获取参数i对应的2进制字符串
		   // static String toHexString(int i)    :获取参数i对应的16进制字符串
		   // static String toOctalString(int i)  :获取参数i对应的8进制字符串
		   s=Integer.toBinaryString(18); 
		   System.out.println(s);//10010
		   s=Integer.toOctalString(18);
		   System.out.println(s);//22
		   s=Integer.toHexString(18);
		   System.out.println(s);//12
		   //6.3 静态方法:static String toString(int i) 
		   //            static String toString(int i, int radix)  指定进制
		   s=Integer.toString(100);
		   System.out.println(s);
		   s=Integer.toString(18, 5);
		   System.out.println(s);//33

Character 特有方法

//Character中的特有方法
//1 static boolean isDigit(char ch)  :判断参数字符是不是数字字符
//2 static boolean isLetter(char ch) :判断参数字符是不是单词字符(字母/汉字)
//3 static boolean isLetterOrDigit(char ch) :判断是不是单词字符或者数字 
//4 static boolean isLowerCase(char ch) :判断是不是小写字母
//5 static boolean isUpperCase(char ch) :判断是不是大写字母
//6 static char toLowerCase(char ch)  :获取参数字符对应的小写
//7 static char toUpperCase(char ch)  :获取参数字符对应的大写
String s="abcABC123&^%$_)(*&#@!明天吧";
for (int i = 0; i <s.length(); i++) {
    char c=s.charAt(i);
    System.out.println(c+":::isDigit::::"+Character.isDigit(c));
    System.out.println(c+":::isLetter::::"+Character.isLetter(c));
    System.out.println(c+":::isLetterOrDigit::::"+Character.isLetterOrDigit(c));
    System.out.println(c+":::isLowerCase::::"+Character.isLowerCase(c));
    System.out.println(c+":::isUpperCase::::"+Character.isUpperCase(c));
}

Character 练习

//转换字符串:大写转小写 小写转大写 删除数字
public static void change(String s){
    String ss="";
    for(int i=0;i<s.length();i++){
        //获取当前字符
        char c=s.charAt(i);
        //判断当前字符的类型
        if(Character.isUpperCase(c)){
            ss+=Character.toLowerCase(c);
        }else if(Character.isLowerCase(c)){
            ss+=Character.toUpperCase(c);
        }else if(!Character.isDigit(c)){
            ss+=c;
        }
    }
    System.out.println(s+"::::"+ss);
}

6、Date

概念

描述时间的类:时间参数:年月日时分秒

注意事项

//注意1:jre中有两个Date:学习的是java.util.Date
//       另外一个Date:java.sql.Date是java.util.Date的子类
java.util.Date date=new Date();

//注意2:java.util.Date的大量方法都是已过时的
//      过时:此方法或者类有更好的替代者 不建议使用  但使用是没有问题的
//      java.util.Date的替代者是java.util.Calendar

//注意3:基准参照时间为“历元(epoch)”,即 1970 年 1 月 1 日 00:00:00 GMT
//       咱们是东八时:需要+8 1970-1-1 8:0:0

构造方法

//构造方法
//1 Date()  无参数的:获取当前时间
Date date1=new Date();
System.out.println(date1);//Wed Sep 01 16:14:30 CST 2021

//2 Date(int year, int month, int date, int hrs, int min, int sec) 参数是年月日时分秒时间参数
//         注意:year-1900 month-1
Date date2=new Date(2021-1900, 9-1, 1, 16, 17, 29);
System.out.println(date2);//Wed Sep 01 16:17:29 CST 2021

//3 Date(long date) 参数是毫秒值:参照的是距离历元的毫秒值
Date date3=new Date(1000L*3600*25);
System.out.println(date3);//Fri Jan 02 09:00:00 CST 1970

普通方法

//普通方法:
// 1 时间比较:
// boolean after(Date when) 
// boolean before(Date when)  
// int compareTo(Date anotherDate)  
System.out.println(date3.after(date1));//false
System.out.println(date3.compareTo(date1));//-1

//2 获取和设置时间参数
//int getXxx()
//void setXxx(int xxx);
date1=new Date();
date1.setYear(2020-1900);
System.out.println(date1);

date2String(new Date());

//3 日期与毫秒值之间的转换
// long getTime() :获取当前时间对象对应的毫秒值 
// void setTime():设置当前时间对象时间与参数毫秒值一致
date=new Date();
long time=date.getTime();
System.out.println(time/1000/3600/24/365);//1630485323022
date.setTime(0);
date2String(date);//1970-11-1 星期四 8:0:0

//4 获取系统时间格式对应的字符串: String toLocaleString() 
System.out.println(date.toLocaleString());//1970-1-1 8:00:00

练习题

1 假设从2000-1-1开始:三天打鱼两天晒网 问 今天是在干啥
2 写一个方法:获取参数字符串表示的时间距离当前时间有多少天:参数字符串格式:xxxx-xx-xx
3 字符串练习题 再写一次

7、SimpleDateFormat

概念

日期格式化类:用于Date对象和指定格式的字符串之间的相互转换
java.text.SimpleDateFormat
格式化:把对象(Date)转换为指定格式的字符串
解析:由指定格式的字符串获取一个对象(Date)

字符串模式

日期和字符串之间相互转换  必须指定字符串的格式:如:xxxx-xx-xx xxxx年xx月xx号 xxxx/xx/xx
需要使用SimpleDateFormat中预定义好的一些字母来表示模式中的时间参数
年  y
月  M
号  d
星期 E
时  H
分  m
秒  s

方法

  • 构造方法
SimpleDateFormat(String pattern) :参数是通过预定义的字母拼凑的字符串模式
  • 格式化方法
String format(Date date): 把参数date对象格式化为指定格式的字符串
  • 解析方法
Date parse(String source) throws ParseException:
      把参数字符串解析为Date对象  但参数字符串的格式必须和模式匹配 才能解析 需要抛出异常

练习

public static void main(String[] args)throws ParseException {
    //System.out.println(new Date());
    //System.out.println(new Date().toLocaleString());
    Date date1=new Date();

    //由date1获取一个字符串:xxxx年xx月xx号 星期x xx时xx分xx秒
    //创建模式:使用预定义的字母表示时间参数
    String pattern="yyyy年MM月dd号 E HH时mm分ss秒";//注意空格
    //创建simpledateformat对象 关联模式
    SimpleDateFormat sdf=new SimpleDateFormat(pattern);
    //使用格式化方法:format方法
    String str1=sdf.format(date1);
    System.out.println(str1);//2021年09月02号 星期四 10时49分56秒

    String str2="2021年10月11号 星期四 12时30分11秒";
    //使用解析方法:parse方法:把指定格式的字符串转换为date对象
    Date date2=sdf.parse(str2);//Unhandled exception type ParseException
    System.out.println(date2.toLocaleString());

}

注意

1 创建SimpleDateFormat 必须关联一个字符串模式:期中用预定义的字母来表示时间参数
2 调用SimpleDateFormat的parse方法时  调用者必须在方法声明上添加:throws ParseException 

8、Calendar

概念

日历类:java.util.Calendar用于弥补java.util.Date类而创建的用于实现国际化的描述时间的类
java.util.Date是完全按照美国人对时间的描述而创建的类:与地球上其他很多民族描述时间的算法都不一致
java.util.Calendar类的设计思想:为了满足国际化  把所有与时间相关的参数都罗列出来 使用者可以各取所需

方法

package com.zhiyou100.day09;

import java.util.Calendar;
import java.util.Date;

public class Test02Calendar {

	public static void main(String[] args) {
		//注意1:Calendar类是抽象类  通过其静态方法static Calendar getInstance()  获取其子类对象
		Calendar c1=Calendar.getInstance();//多态
		System.out.println(c1);
		//java.util.GregorianCalendar[time=1630552360049,areFieldsSet=true,areAllFieldsSet=true,
		//lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,
		//useDaylight=false,transitions=19,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,
		//ERA=1,YEAR=2021,MONTH=8,WEEK_OF_YEAR=36,WEEK_OF_MONTH=1,DAY_OF_MONTH=2,DAY_OF_YEAR=245,
		//DAY_OF_WEEK=5,DAY_OF_WEEK_IN_MONTH=1,AM_PM=0,HOUR=11,HOUR_OF_DAY=11,MINUTE=12,SECOND=40,
		//MILLISECOND=49,ZONE_OFFSET=28800000,DST_OFFSET=0]
		
		//普通方法
		//1 static Calendar getInstance()  :获取子类对象
		//2 比较方法
		//   boolean after(Object when)  
		//   boolean before(Object when) 
		//   int compareTo(Calendar anotherCalendar)  
         
		//3 设置和获取指定的时间参数:通过静态的成员变量来表示所有的时间参数
		//   int get(int field)  
		//   void set(int field, int value)  
		printCalendar(c1);
		c1.set(Calendar.YEAR, 2000);//把年设置为2000
		printCalendar(c1);
		
		//4 设置年月日:
		//void set(int year, int month, int date) 
        //void set(int year, int month, int date, int hourOfDay, int minute)  
		c1.set(2000, 12-1,11,10,9,8);//月从0开始
		printCalendar(c1);
		
		//5 指定时间参数添加值
		//void add(int field, int amount)  
		c1.add(Calendar.YEAR, 1);//年加1
		printCalendar(c1);
		
		//6 日历和日期之间的转换
		//void setTime(Date date) 把当前日历对象的时间设置为参数日期对象定义的时间 
		//Date getTime()  获取当前日历对象的相同时间对应的日期对象
		c1=Calendar.getInstance();
		Date date=c1.getTime();
		System.out.println(date.toLocaleString());//2021-9-2 11:34:56
		date.setTime(0);//设置date的毫秒值为0
		c1.setTime(date);//把c1的时间设置为date对应的时间
		printCalendar(c1);
		
		//7 日历与毫秒值之间的转换
		//long getTimeInMillis()  
		//void setTimeInMillis(long millis)  
	
	}
	public static void printCalendar(Calendar c){
		String weeks=" 日一二三四五六";
		//获取时间参数:
		int year=c.get(Calendar.YEAR);
		int month=c.get(Calendar.MONTH)+1;
		int day=c.get(Calendar.DAY_OF_MONTH);
		int week=c.get(Calendar.DAY_OF_WEEK);//sunday 1  monday 2   saturday 7
		int hour=c.get(Calendar.HOUR_OF_DAY);
		int minute=c.get(Calendar.MINUTE);
		int second=c.get(Calendar.SECOND);
		String str=year+"年"+month+"月"+day+"号 星期"+weeks.charAt(week)+" "+hour+"时"+minute+"分"+second+"秒";
		System.out.println(str);
	}
}
abstract class MyCalendar{
	void hehe(){}
	static MyCalendar getInstance(){
		return new MyCalendarZi();
	}
}
class MyCalendarZi extends MyCalendar{
	
}

9、集合(重点)

9.1、 概念

和数组相同 都是容器
装任意个数个引用数据类型数据的容器
  • 集合和数组的区别
数组:装指定个数个 相同类型数据的容器
集合:装任意个数个 引用数据类型数据的容器
相同之处:都是容器:用于装多个数据
不同之处:
   1 : 数组创建后元素个数不能变
       集合元素个数是可变的
   2 : 数组中元素的类型必须一致
        集合中元素的类型可以不同
   3 : 数组元素类型可以是任意类型:基本数据类型/引用数据类型
        集合的元素类型只能是引用数据类型
   4 : 数组中的元素不赋值  有默认值
        集合的元素没有默认值        
  • 集合框架
由多个接口和其实现类组成
集合框架结构
     Collection: 接口  单列集合的顶层接口 --每次增删改查 只涉及一个数据
          -- List: 子接口  有序列表
              -- ArrayList: 实现类: 底层是长度可变数组的实现;查询和更改快 增删效率低
              -- Vector   : 实现类:和ArrayList相同:(线程安全)
              --LinkedList: 实现类:底层是链表:查询和更改慢 增删效率高
          -- Set: 子接口  不重复列表
              -- HashSet :实现类: 无序 不重复列表
              -- TreeSet :实现类: 有序 不重复列表
     Map: 接口  双列集合的顶层接口 --每次增删改查 涉及的是一对数据(键值对)键不能重复
          --  HashMap: 实现类:  键和值都可以为null 不同步
          --  HashTable: 实现类: 键和值都不可以为null  线程同步

9.2、 Collection

注意:Collection是单列集合的顶层接口:其方法是所有单列集合的共同方法

        //1 添加
//		 boolean add(E e) 
//		 boolean addAll(Collection<? extends E> c) 
		 Collection c1=new ArrayList();Collection c2=new ArrayList();
		 c1.add("abc"); c2.add("abc");
		 c1.add(1);//把int的1 自动装箱为Integer类型的1 再向上转型为Object 然后装如集合
		 c1.add(1);
		 c1.add("sdf"); c2.add("sdf");
		 c1.add(2);
		 
		//2 删除
//		 boolean remove(Object o) 
		 //System.out.println(c1.remove(1)); //如果c1中有多个相同元素  只删除一个
//		 boolean removeAll(Collection<?> c) 
		 //System.out.println(c1.removeAll(c2));
//		 void clear() 
		 //c1.clear();
		 
		//3 判断
//		 boolean contains(Object o) 
		 System.out.println(c1.contains(1));
//		 boolean containsAll(Collection<?> c) 
		 System.out.println(c1.containsAll(c2));
//		 boolean isEmpty() 
		 System.out.println(c1.isEmpty());
		 
		//4获取
//		 Iterator<E> iterator() : 获取集合的迭代器(用于装遍历集合方法的对象)		 
//     		  Iterator的方法:boolean hasNext() 判断是否还有元素可以遍历
//            Iterator的方法:Object next()     获取一个元素
//            把集合想象为一个仓库  把迭代器想象为仓库的货物清单
//       		 hasNext()方法用于判断清单是否还有物品可以查看
//         		 next()方法是从清单顶部读取一个物品 然后把此物品从清单上抹去
//            Iterator:遍历集合时 是一次性的
//		 int size() :获取元素的个数
//		 Object[] toArray() :转换为Object数组 
		 
		 
		 //学习集合的重点:1 集合特点 2 遍历方式
		 //遍历方式1:foreach 简洁for循环
		 for(Object obj:c1){
			 System.out.println(obj);
		 }
		 //遍历方式2: 转换为数组 通过遍历数组来遍历集合
		 Object[] arr=c1.toArray();
		 for(int i=0;i<arr.length;i++){
			 System.out.println("arr["+i+"]="+arr[i]);
		 }
		 //遍历方式3:通过迭代器
		 Iterator it=c1.iterator();
		 while(it.hasNext()){//判断迭代器中是否还有元素可以迭代
			 Object obj=it.next();//获取一个元素
			 System.out.println("obj="+obj);
		 }

9.3、 Arraylist

  • 概念
底层是可变长度数组的实现:
单列集合、元素有下标、查询和修改效率高 增加和删除效率低  线程不安全  JDK1.2
  • 特有方法
//ArrayList特有方法:(比Collection多的方法)
// void add(int index, E element) :在指定下标处添加元素 
// E get(int index)  :根据下标获取元素
// int indexOf(Object o)    :获取元素第一次出现的下标:如果没有返回-1
// int lastIndexOf(Object o)  :倒着找 获取元素第一次出现的下标:如果没有返回-1
// E remove(int index)      : 根据下标 删除元素  返回值是删除的元素对象 
// E set(int index, E element)  :修改指定下标处的元素 返回的是旧值
ArrayList list=new ArrayList();
list.add("a");
list.add("b");
list.add("c");
list.add("d");

list.add(1);//在末尾添加元素
list.add(1,"o");//在下标1处添加一个元素
System.out.println(list.indexOf(1));//5
System.out.println(list.indexOf(2));//-1

//System.out.println(list.remove(0));
//System.out.println(list.remove(9));//IndexOutOfBoundsException: Index: 9, Size: 5

System.out.println(list.set(0, "aa"));
//遍历ArrayList有四种方式
//1:简洁for循环
//2:通过toArray方法获取数组 遍历数组
//3:通过迭代器
//4:通过下标获取元素
for(int i=0;i<list.size();i++){
    System.out.println(i+":::"+list.get(i));
}

//System.out.println(args[1]);//ArrayIndexOutOfBoundsException

9.4 、HashSet

  • 概念
Set接口的实现类:不重复
HashSet:不重复 无序 线程不安全 可以有null值
  • 特有方法
全是继承于Collection 无特有方法
  • HashSet保证元素不重复的原理
package com.zhiyou100.day09;

import java.util.HashSet;

public class Test05HashSet {

	public static void main(String[] args) {
		Student05 s11=new Student05();
		Student05 s12=new Student05();
		Student05 s13=new Student05();
		Student05 s14=new Student05();
		Student05 s15=new Student05();
		Student05 s16=new Student05();
//		System.out.println(s11);
//		System.out.println(s12);
//		System.out.println(s13);
//		System.out.println(s14);
		HashSet set=new HashSet();
		System.out.println("添加::"+s11+":::"+set.add(s11));
		System.out.println("添加::"+s12+":::"+set.add(s12));
		System.out.println("添加::"+s13+":::"+set.add(s13));
		System.out.println("添加::"+s14+":::"+set.add(s14));
		System.out.println("添加::"+s15+":::"+set.add(s15));
		System.out.println("添加::"+s16+":::"+set.add(s16));

	}

}
class Student05{
	private static int n=0;
	private final int num;//用于记录当前对象是第几个对象
	Student05(){
		n++;num=n;
	}
	@Override
	public String toString() {
		return "Student05 [num=" + num + "]";
	}
	@Override
	public int hashCode() {
		System.out.println(this+"的hashCode方法被调用了!!! num%2="+num%2);
		//return super.hashCode();//返回的对象的内存地址
		return this.num%2;
	}
	@Override
	public boolean equals(Object obj) {
		System.out.println(this+"的equals方法被调用了!!!比较对象是:::"+obj);
		return super.equals(obj);
	}
}

image

  • 原理分析
调用set.add(obj1)时 怎么保证元素唯一?
1 先调用obj1的hashCode方法 获取其hashCode值
2 如果此hashCode值 与set中其他所有元素比较是唯一的  直接添加成功
3 如果此hashCode值 与set中其他所有元素中的n个元素 hashCode值相同
4 调用obj1的equals方法与这n个相同hashCode值的元素 分别做比较
5 只用当调用的n次equals方法都返回false 才允许添加  只要有一个返回true 则添加失败
  • 练习:
1  创建一个arraylist 装5个int和5个字符串
  1.2 遍历此arraylist
  1.3 获取其中数字元素的平均值
  1.4 删除期中含有a字符的元素
2 创建一个老师类:名字 性别 工资
  创建10个老师对象 装入HashSet中
  怎么设计老师类 可以保证:名字相同 性别相同 工资相差100以内的对象 不能重复添加 

10、 泛型(Generics)

概念

jdk1.5后的新特性
泛型:为容器的元素规范类型
      把容器元素类型也定义为变量 使用时由调用者来指定具体类型
关键字:<>      

案例

public static void main(String[] args) {
		// ArrayList list1 = getList();
		ArrayList list1=new ArrayList();
		 list1.add(1);// boolean add(Object obj)
		 list1.add("1");
		 list1.add('1');
		 list1.add(1L);
		return list1;
		 //获取元素只能用Object引用来接受
		 Object obj0=list1.get(0);//Object get(index)
		 //需要向下转型: 向下转型的前提条件是::必须知道元素的具体类型
		 //如果不知道元素的具体类型  就无法向下转型  这样的集合没有使用价值
		 //向下转型时:容易出现ClassCastException异常
		 Integer int1=(Integer)obj0;
		 Integer int2=(Integer)list1.get(1);//ClassCastException
		 
		 
		 //使用泛型来规范集合的元素类型
		 ArrayList<String> list2 = new ArrayList<String>();
		 list2.add("11");//boolean add(String obj)
		 //list2.add(1); //添加元素时 只能添加指定类型的元素  元素类型和泛型不一致时 编译器报错
		 list2.add("112");
		 list2.add("11a");
		 list2.add("11c");
		 String ss=list2.get(1);//String get(index)
		 //获取元素  直接使用泛型类型的引用接受元素即可  不需要向下转型  避免出现了ClassCastException
		 
		 //泛型优点: 1 添加元素时 编译器会检测添加的元素是否时泛型指定的类型
		 //         2 获取元素时 直接获取的就是泛型指定的类型 不需要向下转型 就不会出现ClassCastException运行时异常
		 
		 //注意:所有的集合 必须加泛型

	}
    //返回的集合元素时String
	private static ArrayList getList() {
		ArrayList list1=new ArrayList();
		 list1.add(1);// void add(Object obj)
		 list1.add("1");
		 list1.add('1');
		 list1.add(1L);
		return list1;
	}

11、 Map

概念

双列集合:每次增删改查 都是一对数据 键值对
特点:要求键不能重复

实现类HashMap

  • 特点
键不能重复
可以有null值和null键
线程不安全
键是无序的
  • 方法
package com.zhiyou100.day10;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;

public class Test02HashMap {
	public static void main(String[] args) {
		//1 添加
//		V put(K key, V value) :返回值 如果key存在 返回值是旧值  如果key不存在 返回null
		
		//2 删除
//		V remove(Object key) :删除键对应的键值对 并返回值
//		void clear()   : 清空map
		
		//3 获取
//		Set<Map.Entry<K,V>> entrySet() :获取所有键值对Entry对象对应的set
//      V get(Object key) :根据键获取值  如果键不存在 返回null
//      Set<K> keySet()   : 获取键对应的集合
		//Collection<V> values() :获取所有的值
		
		//4 判断
//      boolean isEmpty() : 判断是否为kong
//		boolean containsValue(Object value) :判断是否包含指定的值
//		boolean containsKey(Object key) :判断是否包含指定的键
		
		HashMap<Integer, String> map1=new HashMap<Integer, String>();
		map1.put(1001, "韩梅梅");
		map1.put(1002, "韩庚");
		map1.put(1003, "韩雪");
		System.out.println(map1.put(1004, "韩非子"));//null
		System.out.println(map1.put(1004, "韩信"));//韩非子
		System.out.println(map1.get(1004));//韩信
		System.out.println(map1.get(1005));//null
		
		System.out.println(map1.remove(1001));//韩梅梅
		System.out.println(map1.size());//4
		System.out.println(map1.put(1005, "aa"));
		System.out.println(map1.put(1006, "bb"));
		
		//遍历map集合1:获取所有键对应的集合  然后通过键获取值
		Set<Integer>  keys=map1.keySet();//获取所有的键
		for(Integer key:keys){
			//通过键或取值
			String value=map1.get(key);
			System.out.println(key+":::"+value);
		}
		
		//遍历map集合2:获取所有键值对entry对象对应的set集合  遍历set 通过entry的getkey和getvalue方法获取键值
		Set<Entry<Integer, String>>  entrys=map1.entrySet();
		Iterator<Entry<Integer, String>> ite=entrys.iterator();
		while(ite.hasNext()){
			Entry<Integer, String>  entry=ite.next();
			System.out.println(entry.getKey()+":::::::"+entry.getValue());
		}
	}
}

Map 练习

package com.zhiyou100.day10;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
import java.util.Set;

public class Test03LianXi {

	public static void main(String[] args) {
//		 Map<Character,Integer> map1=getMap1();
//		 //遍历map
//		 Set<Character> keys=map1.keySet();
//		 for (Character key : keys) {
//			 System.out.println(key+"::::"+map1.get(key));
//		 }
		 
         Map<Character,Integer> map2=getMap2();
		 //遍历map
		 Set<Entry<Character, Integer>> entrys=map2.entrySet();
		 for(Entry<Character, Integer> entry:entrys){
			 System.out.println(entry.getKey()+"::::"+entry.getValue());
		 }

	}
	//通过键盘输入一行字符串:
	//写一个方法 返回每个字符出现的次数
	public static  Map<Character,Integer> getMap1(){
		 //获取键盘输入的一行数据
		 System.out.println("请输入一行数据:");
		 String line=new Scanner(System.in).next();
		 //定义list装所有字符
		 ArrayList<Character> list=new ArrayList<Character>();
		 //定义一个set装所有字符 但不重复
		 HashSet<Character> set=new HashSet<Character>();
		 //遍历字符串  把每个字符装入list中
		 for (int i = 0; i <line.length(); i++) {
			  char c=line.charAt(i);
			  list.add(c);
			  set.add(c);
		}
		 //定义一个map 装所有字符及其出现的次数
		 Map<Character,Integer> map=new HashMap<Character, Integer>();
		 for(Character c:set){
			 //定义一个int 记录当前字符c在list中出现的次数
			 int ciShu=0;
			 //遍历list
			 for (Character cc : list) {
				  if(cc==c){
					  ciShu++;
				  }
			 }
			 map.put(c, ciShu);
		 }
		 return map;
		 
	}
	
	public static  Map<Character,Integer> getMap2(){
		 //获取键盘输入的一行数据
		 System.out.println("请输入一行数据:");
		 String line=new Scanner(System.in).next();
		 
		 //定义一个map 装所有字符及其出现的次数
		 Map<Character,Integer> map=new HashMap<Character, Integer>();
		 for(int i=0;i<line.length();i++){
			 char c=line.charAt(i);
//			 if(map.containsKey(c)){//map中以存在c这个键
//				 map.put(c, map.get(c)+1);//原来的值+1
//			 }else{//c是第一次出现
//				 map.put(c, 1);//值为1
//			 }
			 map.put(c, map.containsKey(c)?map.get(c)+1:1);
		 }
		 return map;
	}
}
posted @ 2021-09-03 11:29  RenVei  阅读(37)  评论(0编辑  收藏  举报