前篇链接
18.接口
package cn.cast.demo8;
//接口
public interface Smoking {
//成员方法
//接口中的成员方法都有默认的修饰符public abstract
public abstract void smoke();
}
package cn.cast.demo8;
//接口Smoking的实现类(子类
public class Teacher implements Smoking{
@Override
public void smoke() {
System.out.println("吸烟有害身体健康");
}
}
package cn.cast.demo8;
public class Test {
public static void main(String[] args) {
//Smoking s=new Smoking();
//这样写会报错,因为接口是比抽象类更抽象的存在,不能实例化
//若想实例化可通过创建其子类对象完成
//多态
Smoking s=new Teacher();
s.smoke();
}
}
java中的类最多只能继承一个类,可以实现多个接口;
所有变量都有修饰符 public static final 你没写系统会默认添加;
package cn.cast.demo8;
public interface USB {
//成员常量
int NUM=10;
//成员方法
//jdk7及以前的方法;
public abstract void open();
void close();
//jdk8多了两种写法,即方法有了方法体
public static void method1(){
System.out.println("我是jdk8的新特性");
}
public default void method2(){
System.out.println("我是jdk8的新特性");
}
//jdk9多了一种写法
private void method3(){
System.out.println("我是jdk8的新特性");
}
//接口中没有构造方法
//public USB(){}
}
package cn.cast.demo8;
public class Test {
public static void main(String[] args) {
//USB.num=20;会报错,常量不能被修改
System.out.println(USB.NUM);
}
}
19.java的常用工具_API
如果有些类没有构造方法,说明类里面的成员大多都是静态的,可以通过类名.方式直接调用;
API文档——类的使用说明书
API文档
Object类:
java.lang下的类可以直接使用不需要导包;
package cn.cast.demo;
public class Test {
public static void main(String[] args) {
//非静态的方法的调用方式:通过 对象名.的形式调用
//1.创建object类型对象
Object obj1 = new Object();
Object obj2 = new Object();
//2.测试object类中的成员方法
int code1 = obj1.hashCode();
int code2 = obj2.hashCode();
System.out.print(code1+" "+code2);
System.out.println();
//int hashCode();返回对象的哈希码值,不同对象的哈希码值一般不同
//284720968 189568618
//Class<?> getClass():返回该调用者的字节码文件,一个类只有一个字节码文件对象(一个类可以创建多个对象)
Class claz1=obj1.getClass();
Class claz2=obj2.getClass();
System.out.println(claz1);//class java.lang.Object
System.out.println(claz2);//class java.lang.Object
System.out.println();
//String toString():返回该对象的字符串表示形式,默认打印的地址值,但不同对象的地址值肯定不同
//地址值组成:全类名(包名加类名java.lang.Object)+@+该对象的哈希码的无符号十六进制
//哈希码:根据地址值计算出来的一个结果
String s1=obj1.toString();
String s2=obj2.toString();
System.out.println(s1);//java.lang.Object@10f87f48
System.out.println(s2);//java.lang.Object@10f87f48
System.out.println();
//boolean equals():比较两个对象是否相等,默认比较地址值,无意义(因为不同对象的地址值肯定不同),子类一般都会重写这个方法
boolean b1=obj1.equals(obj2);
System.out.println("b1 = " + b1);
//b1 = false
}
}
注意:实际开发中,我们把两个对象的各个属性值都相同的情况下,才会认为这两个对象是同一个对象
实际开发中Javabean类一般都会去重写Object类中的toString和equals方法
package cn.cast.demo2;
import java.util.Objects;
public class Student {
private int id;
private String name;
private int Score;
public Student() {
}
public Student(int id, String name, int score) {
this.id = id;
this.name = name;
Score = score;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getScore() {
return Score;
}
public void setScore(int score) {
Score = score;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", Score=" + Score +
'}';
}
//自定义的重写equals方法
//假设id属性值相同,两个对象就是同一对象
/* @Override
public boolean equals(Object obj) {
//不能把参数类型改掉,否则就不是重写了
//s1.equals(s2)
*//*
this:谁调用就表示谁 s1
obj:s2
*//*
//向下转型,因为obj没有id这个student特有的成员变量
Student s2=(Student) obj;
return this.id==s2.id;
}*/
@Override
public boolean equals(Object o) {
//this s1 o s2
//比较两个对象的地址值是否相同
if (this == o) return true;
//判断两个对象是否属于同一个类型的对象,提高程序的健壮性
if (o == null || getClass() != o.getClass()) return false;
//向下转型,正常的逻辑代码
Student student = (Student) o;
return id == student.id &&
Score == student.Score &&
name.equals(student.name);
}
/*@Override
public int hashCode() {
return Objects.hash(id, name, Score);
}*/
}
package cn.cast.demo2;
public class Test {
public static void main(String[] args) {
//测试toString方法
// 创建学生类的对象
Student s1=new Student(1,"roxxane",99);
System.out.println(s1);
//输出语句打印对象默认调用了该对象的toString方法
//cn.cast.demo2.Student@b4c966a
System.out.println(s1.toString());
//cn.cast.demo2.Student@b4c966a
//重写toString后的结果
//Student{id=1, name='roxxane', Score=99}
//Student{id=1, name='roxxane', Score=99}
Student s2=new Student(1,"roxxane",99);
boolean b1=s1.equals(s2);
System.out.println(b1);//true
}
}
Scanner
注意:在实际开发中,应用最多的方法是nextInt()用来接收整数,nextLine()用来接收字符串
package cn.cast.demo3;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
//创建Scanner类型的对象(注意导包)
//System.in标准输入流。默认指向键盘
Scanner sc=new Scanner(System.in);
/*//接受一个整数
System.out.println("请录入一个整数:");
//为了解决/避免InputMismatchException异常,可以加入一个判断
if(sc.hasNextInt()){
//判断录入的是否是整数,是结果true;
int num=sc.nextInt();
System.out.println("num = " + num);
}*/
//接受字符串类型的数据
System.out.println("请录入一个字符串:");
/* String s1=sc.nextLine();
System.out.println("s1 = " + s1);*/
String s2=sc.next();
System.out.println("s2 = " + s2);
}
}
String类:
string类的判断功能
package cn.cast.demo4;
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
//测试 构造方法
//1.将指定的字节数组转成字符串
//'a'=97
byte[] bys={97,98,99};
String s1=new String(bys);
System.out.println("s1 = " + s1);//s1 = abc
//2.将指定的字符数组转成字符串
char[] chs={'h','e','l','l','o'};
String s2=new String(chs);
System.out.println("s2 = " + s2);//s2 = hello
/*s2="sdsdsd";
System.out.println(s2);//sdsdsd*/
//在实际开发中,String类非常常用,每次new很麻烦,于是针对string的语法做了优化,省去了new的动作
String s3="sdada";//免new
//测试成员方法
String str1="abc";
String str2="ABC";
boolean b1=str1.equals(str2);
System.out.println("b1 = " + b1);//b1 = false
boolean b2=str1.equalsIgnoreCase(str2);
System.out.println("b2 = " + b2);//b2 = true
//判断str1是否以字符串"a"开头
boolean b3=str1.startsWith("a");
System.out.println("b3 = " + b3);//b3 = true
boolean b4=str1.isEmpty();
System.out.println("b4 = " + b4);//b4 = false
}
}
string类的获取功能:
package cn.cast.demo4;
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
String str = "java roxxane.java";
int length = str.length();
System.out.println("length = " + length);//length = 17
char ch= str.charAt(2);
System.out.println("ch = " + ch);//ch = v
int index=str.indexOf('a');//字符a第一次出现的位置
System.out.println("index = " + index);//index = 1
int indexl=str.lastIndexOf('a');//字符最后一次出现的位置
System.out.println("indexl = " + indexl);//indexl = 16
//截取从索引5开始的所有元素
String s1=str.substring(5);
System.out.println("s1 = " + s1);//s1 = roxxane.java
//截取从索引5-10的所有元素
String s2=str.substring(5,12);//左闭右开
System.out.println("s2 = " + s2);//s2 = roxxane
}
}
String类的转换功能
package cn.cast.demo4;
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
String str = "abc";
byte[] bytes=str.getBytes();
for (int i = 0; i <bytes.length; i++) {//返回字符对应的数字形式 97 98 99
System.out.println(bytes[i]);
}
char[] ch=str.toCharArray();
for (int i = 0; i <ch.length ; i++) {
System.out.print(ch[i]+" ");//a b c
}
System.out.println();
String s2=String.valueOf(123);//静态方法,可以直接用类名调用
System.out.println("s2= " + s2 + 4);//s2= 1234
//在实际开发中,上述的方法都会用下面的方法所替代
String s3=""+123;
System.out.println(s3+4);//1234
String s4="abc abc abc";
//用 d替换b
String s5=s4.replace('b','d');
System.out.println("s5 = " + s5);//s5 = adc adc adc
//将s4按空格切割
String[] stra=s4.split(" ");
for (int i = 0; i <stra.length ; i++) {
//abc
//abc
//abc
System.out.println(stra[i]);
}
String s6=" a b c ";
String s7=s6.trim();//不会修改本身值,需要赋给别的变量
System.out.println(s6);// a b c
System.out.println(s7);//a b c
//实际开发中,当用户录入完密码或账号时,一般会调用trim方法执行,防止有人写完后习惯性的敲空格
}
}
StringBuilder和StringBuffer类(使用相同的API,前者运行效率比后者高,在实际开发中,常用StringBuilder)
若在使用StringBuilder中,你只想使用里面的成员方法,没有其他的需求,就可以通过空参构造,来实现
package cn.cast.demo4;
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
StringBuilder sb=new StringBuilder();
StringBuilder sb2=sb.append("abc");
//append将任意数据添加到StringBuilder容器中,返回自身
//一般直接这么写sb.append("abc");
System.out.println("sb:"+sb);
System.out.println("sb2:"+sb2);
//sb:abc
//sb2:abc
//将string类型的abc转成stringbuilder类型的对象
StringBuilder sb3=new StringBuilder("abc");
System.out.println("sb3 = " + sb3);//sb3 = abc
//将三个字符串拼接成一个新的字符串 该怎么去形容你最贴切 拿什么跟你做比较才算特别 对你的感觉强烈
StringBuilder sb4=new StringBuilder();
sb4.append("该怎么去形容你最贴切 ");
sb4.append("拿什么跟你做比较才算特别 ");
sb4.append("对你的感觉强烈");
System.out.println("sb4 = " + sb4);//sb4 = 该怎么去形容你最贴切 拿什么跟你做比较才算特别 对你的感觉强烈
String s=sb4.toString();
System.out.println("s = " + s);//s = 该怎么去形容你最贴切 拿什么跟你做比较才算特别 对你的感觉强烈
Class cz1=s.getClass();
System.out.println("cz1 = " + cz1);//cz1 = class java.lang.String
Class cz2=sb4.getClass();
System.out.println("cz2 = " + cz2);//cz2 = class java.lang.StringBuilder
}
}
Date和Calendar类:
java.util使用前需要导包;
1min=60s,1s=1000ms
package cn.cast.demo4;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
public class Test {
public static void main(String[] args) {
//测试Date
//测试空参构造,采用当前操作系统的默认时间;
Date date1 = new Date();
System.out.println("date1 = " + date1);//date1 = Thu Sep 24 16:49:54 CST 2020
//获取当前操作系统的毫秒值
long time=date1.getTime();
System.out.println("time = " + time);
//Thu Sep 24 16:49:54 CST 2020 --->1600937475492
//创建一个指定的时间
Date date2=new Date(1600937475492l);
System.out.println("date2 = " + date2);
//date2 = Thu Sep 24 16:51:15 CST 2020
//Calendar c=new Calendar(); 抽象类不能实例化;
//创建Calendar类型的对象
Calendar c=Calendar.getInstance();
System.out.println("c = " + c);
/*
c = java.util.GregorianCalendar[time=1600937747577,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",
offset=28800000,dstSavings=0,useDaylight=false,transitions=29,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,
YEAR=2020,MONTH=8,WEEK_OF_YEAR=39,WEEK_OF_MONTH=4,DAY_OF_MONTH=24,DAY_OF_YEAR=268,DAY_OF_WEEK=5,
DAY_OF_WEEK_IN_MONTH=4,AM_PM=1,HOUR=4,HOUR_OF_DAY=16,MINUTE=55,SECOND=47,MILLISECOND=577,ZONE_OFFSET=28800000,DST_OFFSET=0]
*/
//获取年月日的信息
int year=c.get(Calendar.YEAR);
int mouth=c.get(Calendar.MONTH);//也可以利用c.MONTH;JAVA中使用0-11表示月份的对应1-12月
int day=c.get(Calendar.DATE);
System.out.println(year+"年"+(mouth+1)+"月"+day+"日");//2020年9月24日
//设置指定时间2022.2.22
/* 只设置了年份
c.set(Calendar.YEAR,2022);
int year2=c.get(Calendar.YEAR);
System.out.println(year2+"年"+(mouth+1)+"月"+day+"日");//2022年9月24日*/
c.set(2022,1,22);
int year2=c.get(Calendar.YEAR);
int mouth2=c.get(Calendar.MONTH);//也可以利用c.MONTH;JAVA中使用0-11表示月份的对应1-12月
int day2=c.get(Calendar.DATE);
System.out.println(year2+"年"+(mouth2+1)+"月"+day2+"日");//2022年2月22日
}
}
基本类型的包装类:
parseXxx是静态方法,可直接通过类名调用;
package cn.cast.demo4;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
public class Test {
public static void main(String[] args) {
//因为变量a属于基本类型,不能通过对象名.的形式调用方法。
int a = 10;
//a.
//解决方案,将其转换成对应的包装类(引用类型)即可
//基本类型转换成引用类型,装箱
Integer i1=new Integer(a);//有划线说明已过时
int b=i1.intValue();//拆箱
System.out.println(i1);//10
System.out.println(b);//10
//JDK5的新特性,自动拆装箱
Integer i2=30;//装箱
int c=i2;//拆箱
//将字符串类型的”10“转换成int类型的10
String s="10";
int num=Integer.parseInt(s);
System.out.println("num = " + num);
System.out.println("num +100= " + (num+100));
//num = 10
//num +100= 110
}
}
20.集合
数组是强类型:数组在声明和实例化时就明确了它里面能装什么类型的数据,编译器会检查存放到数组中数据和数组的类型是否匹配或者兼容
集合(暂不考虑泛型集合)是弱类型:集合在声明和实例化时,并未限制它里面能装什么类型。但正是这样,在集合中存取元素时,可能发生与object类型的之间的引用类型转型或者装箱拆箱操作,导致性能问题。
所以,后来又有了泛型集合。
java中的集合分为单列集合(顶层是collection接口)和双列集合(顶层是map接口),单列集合又分为list体系和set体系(list和set仍然是接口,必须通过创建他们的子类对象才能使用)List最常用的子类是ArrayList,set最常用的是HashSet,map最常用的是HashMap
package cn.cast.demo4;
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
package cn.cast.demo4;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Test {
public static void main(String[] args) {
//需求,往list集合中,添加三个学生对象,遍历
List list = new ArrayList();
//注意使用的List是util包下的,不是awt下的
Student s1 = new Student("ronxxane", 18);
Student s2 = new Student("ronxxane", 18);
Student s3 = new Student("charlesyzk", 19);
Student s4 = new Student("nevertheless", 22);
/* boolean b1=list.add(s1);
System.out.println("b1 = " + b1);
boolean b2=list.add(s1);
System.out.println("b2 = " + b2);
返回了True但没有实际意义*/
list.add(s1);
list.add(s2);
list.add(s3);
list.add(s4);
//直接打印集合
System.out.println(list);
//这样显示的结果因为你重写了tostring方法
//[Student{name='ronxxane', age=18}, Student{name='ronxxane', age=18}, Student{name='charlesyzk', age=19}, Student{name='nevertheless', age=22}]
//获取索引为2的元素
Object obj=list.get(2);
System.out.println("索引元素为2的元素 = " + obj);
//获取集合的元素个数
System.out.println(list.size());
for (int i = 0; i <list.size() ; i++) {
Object objs=list.get(i);
System.out.println("索引为"+i+"的元素是"+objs);
//索引为0的元素是Student{name='ronxxane', age=18}
//索引为1的元素是Student{name='ronxxane', age=18}
//索引为2的元素是Student{name='charlesyzk', age=19}
//索引为3的元素是Student{name='nevertheless', age=22}
}
}
}
增强for快捷方式:iter–>回车
注意:增强for的底层依赖的是迭代器Iterator,(增强for就是迭代器的简写形式 )
obj是集合中的元素,其本身应该是Integer类型的数据,只不过你在添加进去的时候,想上转型变成了object类型,
我们利用强制类型转换,把obj转换成Integer类型的,虽然输出的结果相同,但是你可以使用Integer类的方法了
迭代器的用法
总结:普通的迭代器在遍历集合同时不能添加或者删除元素,否则会报:并发修改异常
列表迭代器在遍历集合同时可以修改集合中的元素(添加,删除等),必须使用列表迭代器中的方法;
package cn.cast.demo4;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
public class Test {
public static void main(String[] args) {
//通过增强for遍历list集合
List list=new ArrayList();
list.add("a");
list.add("b");
list.add("c");
/*//1.根据集合对象获取其对象的迭代器对象;
Iterator it=list.iterator();
//2.判断迭代器中是否有元素
while(it.hasNext()){
//如果迭代器有元素,就一直迭代
//3.如果有就获取元素
//Object obj= it.next();
//因为集合中添加的都是字符串,可以进行向下转型
String s=(String)it.next();
System.out.println(s);
}*/
//需求 判断集合中如果有字符串"b",就在其后边添加一个新的字符串:“java”
Iterator it= list.iterator();
while(it.hasNext()){
String s=(String)it.next();
if("b".equals(s)){//一般常量和变量进行比较时会把常量写在前面,变量写在括号里,因为b永远是常量,常量调用方法,即使里面是一个null,也能规避空指针异常
//如果变量写在前面,变量是null,null调用方法会导致空指针异常
//能走到这里说明集合中有元素b
list.add("java");//这样写,会导致ConcurrentModificationException(并发修改异常)
//指的是你在遍历集合时,又往集合中添加或删除元素了
//可以通过列表迭代器实现
}
System.out.println(s);
}
}
}
package cn.cast.demo4;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class Test1 {
public static void main(String[] args) {
//需求 测试列表迭代器
List list=new ArrayList();
list.add("a");
list.add("b");
list.add("c");
//需求 判断集合中如果有字符串"b",就在其后边添加一个新的字符串:“java”
//1.根据集合对象获取其对象的迭代器对象;
ListIterator lit=list.listIterator();
//2.判断迭代器中是否有元素
while(lit.hasNext()){
//3.如果有就获取元素
String s=(String)lit.next();
if("b".equals(s)){
//list.add("java");这样写不行,必须调用列表迭代器的方法来实现
lit.add("java");
}
System.out.println(s);
}
//打印新的集合中的值
System.out.println(list);//[a, b, java, c]
}
}
总结:
泛型一般只和集合类相结合使用。
泛型是jdk5的新特性,但是从jdk7开始,后面的泛型可以不用写具体的数据类型了(菱形泛型)
java.util使用前需要导入
package cn.cast.demo4;
import java.util.*;
public class Test {
public static void main(String[] args) {
//创建集合对象
List<Integer> list=new ArrayList<>();
//往集合中添加数据
list.add(1);
list.add(3);
list.add(3);
list.add(5);
list.add(2);
list.add(2);
list.add(4);
System.out.println("没有操作以前,集合中的数据");
System.out.println(list);//[1, 3, 3, 5, 2, 2, 4]
Integer Max=Collections.max(list);
System.out.println("Max = " + Max);
/*Collections.sort(list);
System.out.println("升序排列后的结果为:"+list);//[1, 2, 2, 3, 3, 4, 5]*/
/* Collections.reverse(list);
System.out.println("翻转后集合中的数据: " +list);//[4, 2, 2, 5, 3, 3, 1]*/
//对集合中的数据降序排列
//先升序,再反转
/* Collections.sort(list);
Collections.reverse(list);
System.out.println("降序后的结果为"+list);//[5, 4, 3, 3, 2, 2, 1]*/
//随机置换,相当于洗牌
Collections.shuffle(list);
System.out.println(list);//每次执行得到结果不同
}
}
Set集合
结论:set集合保证元素的唯一性依赖两个方法:equals hashcode
package cn.cast.demo4;
import java.util.*;
public class Test {
public static void main(String[] args) {
Set<Student> set=new HashSet<>();
Student s1=new Student("sdsd",12);
Student s2=new Student("sdsda",15);
Student s3=new Student("qwer",18);
Student s4=new Student("sdsd",12);
Student s5=new Student("qwer",18);
set.add(s1);
set.add(s2);
set.add(s3);
set.add(s4);
set.add(s5);
System.out.println(set);
/*[Student{name='sdsd', age=12}, Student{name='sdsda', age=15}, Student{name='sdsd', age=12}, Student{name='qwer', age=18}, Student{name='qwer', age=18}]
为什么set集合没有”去重“:因为set集合保证元素的唯一性依赖:equals()和hashcode()两个方法
你没有在student类中重写这两个方法,默认调用的是object类中的两个方法
而object类中的equals()方法默认比较的是地址值是否相同
解决方案:在Student类中重写这两个方法*/
//重写后 [Student{name='qwer', age=18}, Student{name='sdsda', age=15}, Student{name='sdsd', age=12}]
//通过迭代器遍历set集合
//a.通过集合对象获取其对应的迭代器对象
//b.判断迭代器中是否有元素
//c.如果有就获取元素
Iterator<Student> it=set.iterator();
while(it.hasNext()){
Student S=it.next();
System.out.println(S);
//Student{name='qwer', age=18}
//Student{name='sdsda', age=15}
//Student{name='sdsd', age=12}
}
//通过增强for遍历
for (Student student : set) {
System.out.println("student = " + student);
//student = Student{name='qwer', age=18}
//student = Student{name='sdsda', age=15}
//student = Student{name='sdsd', age=12}
}
}
}
map:
map双列集合,泛型要写两个。
package cn.cast.demo4;
import java.util.*;
public class Test {
public static void main(String[] args) {
//需求:往map集合汇总添加三个学生对象,然后打印
//1.创建集合对象
//键:学生的编号,值:具体的学生对象
Map<Integer,Student> map=new HashMap<>();
//2.创建元素对象
Student s1=new Student("zhangsan",23);
Student s2=new Student("lisi",24);
Student s3=new Student("zhangsan",23);
//3.将元素对象添加到集合中
/* Student stu1=map.put(1,s1);
System.out.println("stu1 = " + stu1);//stu1 = null,因为是第一次添加所以会返回null
Student stu2=map.put(1,s2);//因为key=1已存在,所以新值会覆盖旧值并返回旧值
System.out.println("stu2 = " + stu2);//stu2 = Student{name='zhangsan', age=23},所以stu2记录旧值s1,map里存的是新值*/
//实际开发中的写法
map.put(1,s1);
map.put(2,s2);
map.put(3,s3);
//根据键获取值
Student stu3=map.get(2);
System.out.println("key:"+2+" value:"+stu3);//key:2 value:Student{name='lisi', age=24}
//打印集合
System.out.println(map);
//{1=Student{name='zhangsan', age=23}, 2=Student{name='lisi', age=24}, 3=Student{name='zhangsan', age=23}}
//4.遍历集合 双列集合不能直接遍历,需要先转换成单列集合在遍历
/* //4.1获取到所有键的集合 keyset()
Set<Integer> keys=map.keySet();//返回值是一个set集合,因为键具有唯一性,所以要用具有唯一性的set集合存储
//4.2遍历所有的键,获取到每一个键 迭代器,增强for
Iterator<Integer> it=keys.iterator();//获取迭代器对象
while(it.hasNext()){
Integer key=it.next();
//4.3根据键获取指定的值 get()
//根据键获取值
Student value=map.get(key);
System.out.println("key:"+key+" value:"+value);
//key:1 value:Student{name='zhangsan', age=23}
//key:2 value:Student{name='lisi', age=24}
//key:3 value:Student{name='zhangsan', age=23}
}*/
Set<Integer>keys=map.keySet();
for (Integer key : keys) {
//key就是双列集合中的每一个键
Student value=map.get(key);
System.out.println("key:"+key+" value:"+value);
//key:1 value:Student{name='zhangsan', age=23}
//key:2 value:Student{name='lisi', age=24}
//key:3 value:Student{name='zhangsan', age=23}
}
}
}
package cn.cast.demo5;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Test {
public static void main(String[] args) {
//1.买牌;
//1.1定义一个双列集合,键表示牌的编号,值表示具体的牌,规则:编号越小,牌越小
Map<Integer,String> pokers=new HashMap<>();
//1.2定义一个单列集合,用来存储所有牌的编号
List<Integer> list=new ArrayList<>();
//1.3具体的买牌动作
//普通牌 52 大小王 2
String[] colors={"♠","♥","♣","♦"};
String[] numbers={"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
int num=0;//牌的编号
//通过循环遍历造普通牌
for (String number : numbers) {//外循环获取所有的点数
for (String color : colors) {//内循环获取所有的花色
String poker=color+number ;
System.out.println(poker);
//将牌的编号,具体的牌放到双列集合中
pokers.put(num,poker);
//将牌的编号放到单列集合中
list.add(num);
//每填加一张牌,编号要自增1
num++;
}
}
//添加大小王;
pokers.put(num,"小王");
list.add(num++);
pokers.put(num,"大王");
list.add(num);
//打印牌
System.out.println("所有的牌:"+pokers);
System.out.println("牌的编号:"+list);
//编号越小,牌越小
/*所有的牌:{0=♠3, 1=♥3, 2=♣3, 3=♦3, 4=♠4, 5=♥4, 6=♣4, 7=♦4, 8=♠5, 9=♥5, 10=♣5, 11=♦5, 12=♠6, 13=♥6, 14=♣6, 15=♦6, 16=♠7, 17=♥7, 18=♣7, 19=♦7, 20=♠8, 21=♥8, 22=♣8, 23=♦8, 24=♠9, 25=♥9, 26=♣9, 27=♦9, 28=♠10, 29=♥10, 30=♣10, 31=♦10, 32=♠J, 33=♥J, 34=♣J, 35=♦J, 36=♠Q, 37=♥Q, 38=♣Q, 39=♦Q, 40=♠K, 41=♥K, 42=♣K, 43=♦K, 44=♠A, 45=♥A, 46=♣A, 47=♦A, 48=♠2, 49=♥2, 50=♣2, 51=♦2, 52=小王, 53=大王}
牌的编号:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53]
*/
}
}
package cn.cast.demo5;
import java.util.*;
public class Test {
public static void main(String[] args) {
//1.买牌;
//1.1定义一个双列集合,键表示牌的编号,值表示具体的牌,规则:编号越小,牌越小
Map<Integer,String> pokers=new HashMap<>();
//1.2定义一个单列集合,用来存储所有牌的编号
List<Integer> list=new ArrayList<>();
//1.3具体的买牌动作
//普通牌 52 大小王 2
String[] colors={"♠","♥","♣","♦"};
String[] numbers={"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
int num=0;//牌的编号
//通过循环遍历造普通牌
for (String number : numbers) {//外循环获取所有的点数
for (String color : colors) {//内循环获取所有的花色
String poker=color+number ;
System.out.println(poker);
//将牌的编号,具体的牌放到双列集合中
pokers.put(num,poker);
//将牌的编号放到单列集合中
list.add(num);
//每填加一张牌,编号要自增1
num++;
}
}
//添加大小王;
pokers.put(num,"小王");
list.add(num++);
pokers.put(num,"大王");
list.add(num);
//打印牌
System.out.println("所有的牌:"+pokers);
System.out.println("牌的编号:"+list);
//编号越小,牌越小
//2.洗牌
Collections.shuffle(list);
System.out.println("洗好牌后,编号为:"+list);
//3.发牌:
//3.1定义四个集合,分别表示3个玩家,底牌
List<Integer> player1=new ArrayList<>();
List<Integer> player2=new ArrayList<>();
List<Integer> player3=new ArrayList<>();
List<Integer> dipai=new ArrayList<>();
//3.2定义具体的发牌动作,将索引对3取模,决定发给谁
for (int i = 0; i <list.size() ; i++) {
//获取编号
Integer pokerNum=list.get(i);
//System.out.println("pokerNum = " + pokerNum);
if(i>= list.size()-3){
dipai.add(pokerNum);
}
else if(i%3==0){
player1.add(pokerNum);
}
else if(i%3==1){
player2.add(pokerNum);
}
else if(i%3==2){
player3.add(pokerNum);
}
}
//3.3查看玩家,底牌的编号
System.out.println("dipai = " + dipai);
System.out.println("player1 = " + player1);
System.out.println("player2 = " + player2);
System.out.println("player3 = " + player3);
}
}
package cn.cast.demo5;
import java.util.*;
public class Test {
public static void main(String[] args) {
//1.买牌;
//1.1定义一个双列集合,键表示牌的编号,值表示具体的牌,规则:编号越小,牌越小
Map<Integer,String> pokers=new HashMap<>();
//1.2定义一个单列集合,用来存储所有牌的编号
List<Integer> list=new ArrayList<>();
//1.3具体的买牌动作
//普通牌 52 大小王 2
String[] colors={"♠","♥","♣","♦"};
String[] numbers={"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
int num=0;//牌的编号
//通过循环遍历造普通牌
for (String number : numbers) {//外循环获取所有的点数
for (String color : colors) {//内循环获取所有的花色
String poker=color+number ;
System.out.println(poker);
//将牌的编号,具体的牌放到双列集合中
pokers.put(num,poker);
//将牌的编号放到单列集合中
list.add(num);
//每填加一张牌,编号要自增1
num++;
}
}
//添加大小王;
pokers.put(num,"小王");
list.add(num++);
pokers.put(num,"大王");
list.add(num);
//打印牌
System.out.println("所有的牌:"+pokers);
System.out.println("牌的编号:"+list);
//编号越小,牌越小
//2.洗牌
Collections.shuffle(list);
System.out.println("洗好牌后,编号为:"+list);
//3.发牌:
//3.1定义四个集合,分别表示3个玩家,底牌
List<Integer> player1=new ArrayList<>();
List<Integer> player2=new ArrayList<>();
List<Integer> player3=new ArrayList<>();
List<Integer> dipai=new ArrayList<>();
//3.2定义具体的发牌动作,将索引对3取模,决定发给谁
for (int i = 0; i <list.size() ; i++) {
//获取编号
Integer pokerNum=list.get(i);
//System.out.println("pokerNum = " + pokerNum);
if(i>= list.size()-3){
dipai.add(pokerNum);
}
else if(i%3==0){
player1.add(pokerNum);
}
else if(i%3==1){
player2.add(pokerNum);
}
else if(i%3==2){
player3.add(pokerNum);
}
}
//3.3查看玩家,底牌的编号
/*System.out.println("dipai = " + dipai);
System.out.println("player1 = " + player1);
System.out.println("player2 = " + player2);
System.out.println("player3 = " + player3);*/
//4.查看具体的牌
/* String str=printPoker(player1,pokers);
System.out.println("player1 = " + str);*/
System.out.println("dipai = " + printPoker(dipai,pokers));
System.out.println("player1 = " + printPoker(player1,pokers));
System.out.println("player2 = " +printPoker(player2,pokers));
System.out.println("player3 = " + printPoker(player3,pokers));
}
/*4.定义一个方法,用来看牌
方法名 printPoker
参数列表 List<Integer>,Map<Integer,String>
返回值:String
*/
public static String printPoker(List<Integer> nums,Map<Integer,String> pokers){
//1.对牌的编号升序排列
Collections.sort(nums);
StringBuilder sb=new StringBuilder();
//2.遍历牌的编号集合,获取到每一个编号
for (Integer num : nums) {
//num就是要查找的具体牌的编号
//3.根据编号去双列集合中查找该编号对应的具体牌
String poker= pokers.get(num);
//4.将获取到的牌进行拼接
sb.append(poker+" ");
}
//5.将最后的拼接结果返回即可
String str=sb.toString();
//去掉最后一张牌的空格
return str.trim();
}
}
21.IO流
异常处理方式:
方式一特点:处理完异常后,程序会继续执行
执行流程:先执行try{}中的内容,看是否有问题(异常)
没有:直接执行finally语句中的内容
有:跳转到catch(){}开始执行,在执行finally{}语句中的内容。(当try里面的语句出现问题时,不管该语句后是否还有几行代码,立刻跳转到catch中执行)
package cn.cast.demo6;
public class Test {
public static void main(String[] args) {
//int a=10/0;//java.lang.ArithmeticException: / by zero
//System.out.println("a = " + a);由于没有设置处理方式,会采用默认的jvm处理,将异常信息打印在控制台上并终止程序执行,所以此句不会执行
//使用try.catch.finally来处理异常
try{
//尝试要执行的代码
int a=10/10;
System.out.println("a = " + a);
return;
}catch(Exception e){
//出现问题后的代码(解决方案)
System.out.println("被除数不能为0");
return;
}finally{
//即使try.catch中有return,finally里面的语句也会执行,而外面的语句不会执行
System.out.println("看看是否执行到此处");
}
//System.out.println("看看是否执行到此处");
}
}
特点:执行结束后,程序不再继续执行(如果交由jvm处理)
package cn.cast.demo6;
public class Test {
public static void main(String[] args)throws Exception {
//需求 main函数中调用show()
//show()有红标并不能用,因为show方法已经抛出一个异常,作为调用者(main函数)必须处理这个异常
//方案一:接着抛(main函数抛给了jvm,因为main函数的执行是由jvm自动调用的)
//show();
//System.out.println("康康我执行了吗");//并没有执行,因为main函数把异常交给jvm处理,jvm会将异常的信息打在处理台上并终止程序执行
//方案二:采用try catch处理
//作为调用者,我只需把异常处理了就可以,但我处理的方式使用try catch还是接着抛跟show方法就没有关系了
try{
show();
}catch(Exception e){
System.out.println("代码出问题了");
}
System.out.println("康康我执行了吗");
}
//定义一个方法
public static void show()throws Exception{
int a=10/0;
System.out.println("a = " + a);
}
}
IO流:
Reader Writer抽象类 要使用他们的子类
FileReader FileWriter普通的字符输入输出流
BufferWriter BufferReader高效的字符输入输出流
InputStream OutputStream抽象类 要使用他们的子类
FileInputStream FileOutputStream普通的字节输入输出流
BufferInputStream BufferOutputStream高效的字节输入输出流(运行效率比普通的高很多)
File类:
其中创建功能:如果不存在就创建,返回true,否则就不创建,返回false
package cn.cast.demo7;
import java.io.File;
import java.io.IOException;
public class Test {
public static void main(String[] args) throws IOException {
//需求将D:\abc\1.txt封装成File对象
//方式一:根据字符串的形式获取file对象
//File file1=new File("D:\\abc\\1.txt");
File file1=new File("D:/abc/1.txt");//两种路径的写法
System.out.println("file1 = " + file1);
//file1 = D:\abc\1.txt
//方式二根据字符串形式的父目录以及子目录创建file对象
File file2=new File("D:/abc/","1.txt");
System.out.println("file2 = " + file2);
//file2 = D:\abc\1.txt
//方式三根据父目录对象,以及字符串形式的子目录来获取file对象
File file3=new File("D:/abc/");
File file4=new File(file3,"1.txt");
System.out.println("file4 = " + file4);
//file4 = D:\abc\1.txt
//需求,在d盘下创建一个2.txt文件
File file5=new File("D:/2.txt");//注意盘符不区分大小写d也可
boolean flag1=file5.createNewFile();
System.out.println("flag1 = " + flag1);
//需求,在d盘下创建一个a文件夹
File file6=new File("D:/a");
boolean flag2=file6.mkdir();//make directory,创建单级目录
System.out.println("flag2 = " + flag2);
//需求,在d盘下创建一个a/b/c文件夹
File file7=new File("d:/a/b/c");
boolean flag3=file7.mkdirs();
System.out.println("flag3 = " + flag3);//flag3 = false,因为mkdir此方法,只能创建单级路径,创建多个不存在的文件用mkdirs
//mkdirs可以创建多级目录,也可以创建单级目录,实际使用最为广泛
File file8=new File("d:/a/b");
System.out.println("file8是否是文件夹:"+file8.isDirectory());
System.out.println("file8是否是文件:"+file8.isFile());
System.out.println("file8是否存在:"+file8.exists());
//file8是否是文件夹:true
//file8是否是文件:false
//file8是否存在:true
}
}
package cn.cast.demo8;
import java.io.File;
import java.util.Date;
public class Test {
public static void main(String[] args) {
File file1 = new File("lib/1.txt");
//获取file1的绝对路径
String path1 = file1.getAbsolutePath();
System.out.println("absolute path: " + path1);//absolute path: D:\software\storage\lib\1.txt
//获取file1的相对路径
String path2=file1.getPath();
System.out.println("相对路径: "+path2);//相对路径: lib\1.txt
//获取文件名
String filename= file1.getName();
System.out.println("filename = " + filename);//filename = 1.txt
//获取lib文件夹下所有文件(夹)的:名称数组String[]
//lib下有a abc 1.txt a和abc里还有内容,但你只能拿到lib里面的一级的内容
File file2=new File("lib");
String[] names=file2.list();
for (String name : names) {
System.out.println("name = " + name);
//name = 1.txt
//name = a
//name = abc
}
//获取lib文件夹下所有文件(夹)的:File对象数组 File[]
File[] files=file2.listFiles();
for (File file : files) {
System.out.println("file = " + file);
//file = lib\1.txt
//file = lib\a
//file = lib\abc
}
//与上一个方法的区别在意他只是拿的名字,而此处拿的是file对象,可调用方法
}
}