========基本类型(byte char short int long float double boolean)如何转换成字符串=========
//1.任何的数据类型和字符串进行连加,就会变成字符串
int num=50;
String str = "ab"+num;//ab50
System.out.println(str);
System.out.println("我是:"+num+50);//输出结果: 1.我是:50 2.我是:5050 ===>我是:5050
System.out.println(num+50+"我是");//输出结果: 1. 50+50=100 2.100+"我是"===> 100我是
//2.通过 String.valueOf(基本类型数据)方法将基本类型转换成 String 类型
double d1=45.67;
String str2 = String.valueOf(d1); //"45.67"
System.out.println(str2);
//=============字符串如何转换成基本数据类型=======================
//在java中每一个基本数据类型都对应了一个引用数据类型的包装类
//包装类 byte=>Byte short=>Short int=>Integer
//long=>Long float=>Float double=>Double boolean=>Boolean char=>Charactor
String str1="false";
boolean bl = Boolean.parseBoolean(str1);
String str3="50";
byte by=Byte.parseByte(str3);
String str4 ="45456";
short st = Short.parseShort(str4);
String str5="45645646";
int num5 = Integer.parseInt(str5);
String str6="457657657657";
long l1= Long.parseLong(str6);
String str7="4545.67";
float fl= Float.parseFloat(str7);
String str8="4564576657.3";
double dl2= Double.parseDouble(str8);
//char
char ch=str7.charAt(1);
二维数组的动态初始化数组
int[][] number = new int[4][]; for (int i = 0; i常见算法
进制
二进制以0B/b开头
八进制以0开头
十六进制以0X开头
十进制转其他数用除其他剩余法(转16就除以16,转8就除以8,转二就除以二)
其他转十进制就用乘法,(用二转就二进制每个数乘以2的次方,用8、16就乘以他的次方相加)
二转8或16就每(三个)或每(四个)看成一个数对应各自的进制。
位运算原码、反码、补码 对于有符号的而言; 1、二进制的最高位是符号位:0表示正数,1表示负数 2、正数的原码反码补码都是一样的,三码合一 3、负数的反码 = 它的原码符号位不变,其他位取反 4、负数的补码 = 它的反码+1,负数的反码 = 负数的补码 - 1; 5、0 的反码、补码都是0; 6、java中没有无无符号位 7、计算机在运行的时候,都是通过补码的方式 8、当看运算结果的时候,要看他的原码 位运算符 java中有7个位运算 &、|、^、~、>>、<<、和>>> 按位与 & 两个为一,结果为一,否则为0 按位或 | 两个只要有一个为1,结果为1,否则为0 按位异或^ 两个一个为1一个为0则为1,否则为0 按位取反 ~ 取反就是取反 }常量、枚举表示具体的值用常量,只是用信息分类就用枚举
二、包、工具类 JDK中主要的包java.lang:包含一些Java语言的核心类,如String、Math、Integer、System和Thread,提供常用功能。java.awt:包含了构成抽象窗口工具集(abstract window toolkits)的多个类,这些类被用来构建和管理应用程序的图形用户界面(GUI)。java.applet:包含applet运行所需的一些类。java.net:包含执行与网络相关的操作的类。java.io:包含能提供多种输入/输出功能的类。java.util:包含一些实用工具类,如定义系统特性、使用与日期日历相关的函数。**java.sql *包含了java进行JDBC数据库编程的相关类、接口。
注:java.lang这个包会自动被导入,对于其中的类,不需要使用import语句来做导入。
Object常用方法***判断两个对象是否是同一类型o1 . instanceof. student 如果是同一类型,可以强转
toString
默认返回打印当前对象在堆内存中的地址,输出内容的话得重写
很多类都已经重写了toString,只有自己写的类需要自己重写
equals
默认比较两个对象的地址,比较内容的话得重写
hashCode,返回对象的哈希值。
String字符串进行比较得话已经内部重写了Object的equals方法,应该用Objects.equals 更安全
Objects可以进行一个非空校验,更安全
StringAPI几种创建字符串对象的格式:直接创建的在堆内存常量池中(相同内容只会存储一个),new出来的在堆内存中和常量池中同时创建对象,常量池中有就不创建了
和长度有关的方法 返回类型 方法名 作用 int length() 得到一个字符串的字符个数(一个中文是一个字符,一个英文是一个字符,一个转义字符是一个字符) 和数组有关的方法 返回类型 方法名 作用 byte[] getBytes() 将一个字符串转换成字节数组 char[] toCharArray() 将一个字符串转换成字符数组 String[] split(String) 将一个字符串按照指定内容劈开 和判断有关的方法 返回类型 方法名 作用 boolean equals(String) 判断两个字符串的内容是否一模一样 boolean equalsIgnoreCase(String) 忽略大小写的比较两个字符串的内容是否一模一样 boolean contains(String) 判断一个字符串里面是否包含指定的内容 boolean startsWith(String) 判断一个字符串是否以指定的内容开头 boolean endsWith(String) 判断一个字符串是否以指定的内容结尾 和改变内容有关的方法 和改变内容有关的方法,都不会直接操作原本的字符串 而是将符合条件的字符串返回给我们,所以注意接收 返回类型 方法名 作用 String toUpperCase() 将一个字符串全部转换成大写 String toLowerCase() 将一个字符串全部转换成小写 String replace(String,String) 将某个内容全部替换成指定内容 String replaceAll(String,String) 将某个内容全部替换成指定内容,支持正则 String repalceFirst(String,String) 将第一次出现的某个内容替换成指定的内容 String substring(int) 从指定下标开始一直截取到字符串的最后 String substring(int,int) 从下标x截取到下标y-1对应的元素 String trim() 去除一个字符串的前后空格 和位置有关的方法 返回类型 方法名 作用 char charAt(int) 得到指定下标位置对应的字符 int indexOf(String) 得到指定内容第一次出现的下标 int lastIndexOf(String) 得到指定内容最后一次出现的下标
Stringbuilderpublic class TestStringBuilder { public static void main(String[] args) { StringBuilder sb = new StringBuilder("hello"); //字符串的容量和长度 System.out.println("容量是:"+sb.capacity());//16+5=21 System.out.println("长度是:"+sb.length());//5 //通过toString 就可以实现把StringBuilder转化为String 用完Stringbuilder就得切回来 //StringBuilder insert(int offset,String str) // — 将str插入到当前字符串中offset指向的位置上; System.out.println("插入后新字符串:"+sb.insert(3,"yes")); // StringBuilder append(String str) // — 将str插入到当前字符串的末尾位置; System.out.println("插入末尾后的新字符串:"+sb.append("world").append(",,,,,")); // StringBuilder delete(int start ,int end) // — 将当前字符串中从start(包含)开始到end(不包含)之间的内容移除; System.out.println("删除后的新字符串:"+sb.delete(2, 4)); // StringBuilder replace(int start , int end , String str) // — 将当前字符串中start到end之间的内容全部用str的内容替换; System.out.println("替换内容后的新字符串:"+sb.replace(2, 4, "XXOO")); // StringBuilder reverse() // — 实现字符串的反转; System.out.println("反转后的新字符串:"+sb.reverse()); // StringBuilder substring() System.out.println("下标2的新字符:"+sb.substring(2)); // StringBuilder indexOf() // — 从指定的索引处开始,返回第一次出现的指定子字符串在该字符串中的索引。 System.out.println("从下标2开始查找的字符“l”出现的位置:"+sb.indexOf("l",2)); } }Arrays 数组操作工具类1、boolean equals(array1,array2):比较两个数组是否相等。 package com.jredu.ch06; import java.util.Arrays; public class Ch03 { public static void main(String[] args) { // TODO Auto-generated method stub String[] str1={"1","2","3"}; String[] str2={"1","2",new String("3")}; System.out.println(Arrays.equals(str1, str2));//结果是:true } } 2、 void sort(array):对数组array的元素进行升序排列 //给一个数组进行排序 int[] score ={79,65,93,64,88}; Arrays.sort(score);//给数组排序 //sort:作用是把一个数组按照有小到大进行排序 //str代表的也是一个引用地址 String str = Arrays.toString(score); //print方法可以直接打印字符串的值 System.out.println(str); //Arrays.toString(score):把数组转变成字符串 3、 String toString(array):把数组array转换成一个字符串。 package com.jredu.ch06; import java.util.Arrays; public class Ch05 { public static void main(String[] args) { // TODO Auto-generated method stub //toString:把一个数组转换成一个字符串 //定义 一个数组 int[] a={1,2,3}; System.out.println(a);//打印出的是hashcode码 System.out.println(Arrays.toString(a));//打印出的是数组 } }4、 void fill(array,val):把数组array所有元素都赋值为val。 //fill方法:把数组中的所有元素替换成一个值 int[] num={1,2,3}; //参数1:数组对象 //参数2:替换的值 Arrays.fill(num, 6); System.out.println(Arrays.toString(num));//打印结果:[6, 6, 6] 5、int binarySearch(array,val):查询元素值val在数组array中的下标 //binarySearch:通过二分法的方式找对应元素的下标 / System.out.println(Math.sqrt(16)); //4.0 System.out.println(Math.cbrt(8)); //2.0 System.out.println(Math.pow(3,2)); //9.0 System.out.println(Math.max(2.3,4.5));//4.5 System.out.println(Math.min(2.3,4.5));//2.3 System.out.println(Math.abs(-10.4)); //10.4 System.out.println(Math.abs(10.1)); //10.1 System.out.println(Math.ceil(-10.1)); //-10.0 System.out.println(Math.ceil(10.7)); //11.0 System.out.println(Math.ceil(-0.7)); //-0.0 System.out.println(Math.ceil(0.0)); //0.0 System.out.println(Math.ceil(-0.0)); //-0.0 System.out.println(Math.ceil(-1.7)); //-1.0 System.out.println(Math.floor(-10.1)); //-11.0 System.out.println(Math.floor(10.7)); //10.0 System.out.println(Math.floor(-0.7)); //-1.0 System.out.println(Math.floor(0.0)); //0.0 System.out.println(Math.floor(-0.0)); //-0.0 System.out.println(Math.random()); //大于或者等于0小于1的double类型的数 System.out.println(Math.random()*2);//大于或者等于0小于2的double类型的数 System.out.println(Math.random()*2+1);//大于或者等于1小于3的double类型的数 System.out.println(Math.rint(10.1)); //10.0 System.out.println(Math.rint(10.7)); //11.0 System.out.println(Math.rint(11.5)); //12.0 System.out.println(Math.rint(10.5)); //10.0 System.out.println(Math.rint(10.51)); //11.0 System.out.println(Math.rint(-10.5)); //-10.0 System.out.println(Math.rint(-11.5)); //-12.0 System.out.println(Math.rint(-10.51)); //-11.0 System.out.println(Math.rint(-10.6)); //-11.0 System.out.println(Math.rint(-10.2)); //-10.0 System.out.println(Math.round(10.1)); //10 System.out.println(Math.round(10.7)); //11 System.out.println(Math.round(10.5)); //11 System.out.println(Math.round(10.51)); //11 System.out.println(Math.round(-10.5)); //-10 System.out.println(Math.round(-10.51)); //-11 System.out.println(Math.round(-10.6)); //-11 System.out.println(Math.round(-10.2)); //-10 }BIgDecimal 解决精度失真的问题add 和
subtract 差
multiply 积
divide 商
System//系统打印输出 out输出 System.out.println("helloWord"); //系统输入 in 输入 Scanner input = new Scanner(System.in); //系统日志打印 System.err.println("hello word"); //系统退出 System.exit(0); // GC 表示虚拟机垃圾回收机制.需要等待JVM空闲时,才会进行垃圾回收(不再启用的内存空间).并不是运行GC()方法,就一定进行垃圾回收. System.gc();日期类APIpublic class TestDate { public static void main(String[] args) throws Exception{ // 每个地区的标准时间是不一样的,因为存在时区的差异新,中国属于东八区, //因此标准时间是1970年1月1日8时0分0秒 // 1.使用各种不同的版本构造对象 Date d1 = new Date(); System.out.println("d1=" + d1);// 打印系统时间 Date d2 = new Date(1000); System.out.println("d2=" + d2);// 1000毫秒 //2、两种方法计算毫秒值 Date d1 = new Date(); System.out.println("d1=" + d1);// 打印系统时间 long time = d1.getTime(); System.out.println(time); // 打印时间毫秒值 long time1 = System.currentTimeMillis(); System.out.println(time1); //3、把当前日期换个格式输出 Date r = new Date (); SimpleDateFormat r1 = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss EEE a"); System.out.println(r1.format(r)); //星期 上下午 案例1,当前时间往后走一小时121秒的时间是多少 long r = System.currentTimeMillis() +(60*60+121)*1000; ; //获取现在的毫秒值 (1) Date r1 = new Date(r); System.out.println(r1); (2) Date r2 = new Date(); r2.setTime(r); System.out.println(r2); 案列2 // 请计算出2021年08月06日11点11分11秒,往后走2天14小时49分06秒后的时间是多少 String r = "2021年08月06日11:11:11"; //格式一定要正确,不然会报错 SimpleDateFormat s = new SimpleDateFormat("yyyy年MM月dd日HH:mm:ss"); Date d = s.parse(r); //解析时间 long time = d.getTime()+(2L*24*60*60+14*60*60+49*60+6)*1000; System.out.println(s.format(time)); //案例3、秒杀活动 //1、开始和结束时问 string startTime = "2021-11-11 00:00:00"; string endTime = "2021-11-11 00:10:00"; //2、小贾小皮 string xiaoJia ="2021-11-11 00:03:47"; string xiaoPi = “2021-11-11 00:10:11"; //3,解析他们的时问 simpleDateFormat sdf = new simpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date d1 = sdf.parse(startTime); Date d2 = sdf.parse(endTime); Date d3 = sdf.parse(xiaoJia); Date d4 = sdf.parse(xiaoPi); if(d3.after(d1)&& d3.before(d2)){ System.out.println("小贡秒杀成功,可以发货了!“); }else { System.out.println("小贡秒杀夫败!―〕;) if(d4.after(d1) && d4.before(d2)){ systen.out.println("小皮杪杀成功,可以发货了!"); }else { System.out.println("小皮秒杀夫败!“〕; } Calendar代表了系统此刻日期对应的日历对象。 Calendar是一个抽象类,不能直接创建对象。 public static Calendar getInstance() 获取当前日历对象 | public int get(int field) | 取日期中的某个字段信息。 | | :------------------------------------ | --------------------------- | | public void set(int field,int value) | 修改日历的某个字段信息。 | | public void add(int field,int amount) | 为某个字段增加/减少指定的值 | | public final Date getTime() | 拿到此刻日期对象。 | | public long getTimeInMillis() | 拿到此刻时间毫秒值 | 注意:calendar是可变日期对象,一旦修改后其对象本身表示的时间将产生变化 LocalDate:不包含具体时间的日期。 LocalTime:不含日期的时间。 LocalDateTime:包含了日期及时间。 Instant:代表的是时间戳。 DateTimeFormatter 用于做时间的格式化和解析的 Duration:用于计算两个“时间”间隔 Period:用于计算两个“日期”间隔LocalDate:不包含具体时间的日期。
LocalTime:不含日期的时间。
LocalDateTime:包含了日期及时间。
Instant:代表的是时间戳。
DateTimeFormatter 用于做时间的格式化和解析的
Duration:用于计算两个“时间”间隔
Period:用于计算两个“日期”间隔
正则表达式
matches 方法来匹配字符串
public class TestStringReg { public static void main(String[] args) { // 1.准备一个描述正则表达式的字符串 // 描述银行卡密码的规则,要求由六位数字组成 // String reg = "^[0-9]{6}$"; // 在编码中需要两个组成一个识别 // String reg = "\d{6}"; // 描述手机号码的规则,要求由11位数字组成,其中1开头,第二位必须是345789 // String reg = "[1]{1}[345789]{1}\d{9}"; // 描述座机号码的规则,要求3-4位区号,中间使用-连接,后面7-8位号码 // String reg = "\d{3,4}[-]{1}\d{7,8}"; // 描述身份证号码的规则,要求由17位数字与最后一位是X或者数字组成,前6位要求表示地区,4位表示年份,4位表示月日,3位校验码,最后一位可能是数字可能是X // String reg = "\d{6}\d{8}\d{3}[0-9X]{1}"; // 描述用户名规则,要求6-8位数字、字母以及下划线组成 // String reg = "\w{6,8}"; // 描述邮箱的规则,要求字母、数字以及下划线组成名称,中间@符号,后面2-5位的字母或者数字组成.最后加上后缀.com.org.cn.edu.com.cn String reg = "\w{1,}[@]{1}[0-9a-zA-Z]{2-5}(.com|.org|.cn|.edu|.com.cn)"; // 2.不断的提示用户输入一个字符串,若匹配上诉规则则结束输入,否则继续输入 Scanner sc = new Scanner(System.in); while (true) { System.out.println("请输入邮箱号码:"); String str = sc.next(); if (str.matches(reg)) { System.out.println("格式正确!"); break; } else { System.out.println("格式不正确!"); continue; } } sc.close(); }爬取信息 Stream流1、Stream流的作用
简化集合、数组操作的API,结合了Lambda表达式,一种手段
2、使用步骤
先得到集合或者数组的Stream流
把元素放上去
然后用这个Stream流简化的API来方便的操作元素
** Collection集合获取流 CollectionList = new ArrayList<>(); Stream s = List.stream(); ** Map集合获取流 Map maps = new HashMap<>(); //键流 maps.keySet().stream(); //值流 maps.values().stream(); //键值对流(拿整体) maps.entrySet().stream(); ** 数组获取流 String name= {" "," "," "}; Arrays.stream(name); Streeam.of(name); 常用Api
1、forEach
// forEach接收消费类型的函数式接口,为Stream流的最终方法,调用后不能再调用Stream流的其它方法了
// 若只有一个参数则可以省略()
// 参数的类型也可省略,java编译器会自动推断参数类型
// 若方法体只有一行代码则可以省略{}
@Test public void test1() { Streamst = Stream.of("张三","李四","王五","赵六","田七"); st.forEach((String name) -> { System.out.println(name); }); } @Test public void test2() { Stream st = Stream.of("张三","李四","王五","赵六","田七"); st.forEach(name -> System.out.println(name)); } 2、filter
// 过滤,延迟方法,接收判断类型的函数式接口,产生新的子集流,调用后还可以继续调用其它的Stream流方法
// 若写了{}则必须用return返回结果
// 若省略了{}则不需要return返回结果
@Test public void test1() { // 原始Stream流 Streamst1 = Stream.of("张三","张无忌","赵敏","张三丰","周芷若"); // 过滤后会产生一个新的子集流 Stream st2 = st1.filter((String name) -> { return name.startsWith("张") && name.length() == 3; }); st2.forEach(name -> System.out.println(name)); } @Test public void test2() { // 原始Stream流 Stream st1 = Stream.of("张三","张无忌","赵敏","张三丰","周芷若"); // 过滤后会产生一个新的子集流 Stream st2 = st1.filter(name -> name.startsWith("张") && name.length() == 3); st2.forEach(name -> System.out.println(name)); } 3、map
// 延迟方法,操作Stream流数据中的每个元素,将Stream流映射到一个新的Stream流上
// 操作数据中的每个元素,改变该元素的值或者类型等等
@Test public void test1() { Streamst1 = Stream.of("a","b","c","d","e"); // 操作数据中的每个元素,返回新的元素 // 方法体只有一行时,可省略{}和return st1.map(str -> str += str.toUpperCase()) .forEach(str -> System.out.println(str)); } @Test public void test2() { Stream st1 = Stream.of("a","b","c","d","e"); // 操作数据中的每个元素,返回新的元素 // 方法体有{}时必须加上return st1.map(str -> { return str += str.toUpperCase(); }).forEach(str -> System.out.println(str)); } @Test public void test3() { Stream st1 = Stream.of("1","2","3","4","5"); // 操作数据中的每个元素,将每个元素转为Integer类型 Stream st2 = st1.map(str -> Integer.parseInt(str)); st2.forEach(num -> System.out.println(num.getClass())); } 4、count
// 最终方法,没有参数,没有方法体,属于Stream流的最终方法,用于统计Stream流中的数据长度,返回long类型
@Test public void test4() { // count方法属于Stream流的最终方法,统计数据的长度,返回long类型 Streamst1 = Stream.of("1","2","3","4","5"); long ct = st1.map(str -> Integer.parseInt(str)) .filter(num -> num > 3) .count(); System.out.println(ct); } 5、limit
// 延迟方法,截取Stream流中的前几个元素返回新的Stream流,入参为long类型,没有方法体
// 若入参的值大于Stream流中的数据的长度则返回由原数据组成的新Stream流
@Test public void test1() { Streamst1 = Stream.of("aa","bb","cc","dd","ee"); st1.limit(3).forEach(str -> System.out.println(str)); } 6、skip
// 延迟方法,入参为long类型,没有方法体,跳过前一个Stream流的前几个元素,得到由后面的元素组成的新Stream流
@Test public void test2() { Streamst1 = Stream.of("aa","bb","cc","dd","ee"); st1.skip(2).forEach(str -> System.out.println(str)); } // 若跳过的元素个数>=Stream流数据的长度则会得到一个元素个数为0的空流
@Test public void test2() { Streamst1 = Stream.of("aa","bb","cc","dd","ee"); long ct = st1.skip(6).count(); System.out.println(ct); } 7、concat
// Stream的静态方法,将多个Stream流的数据按入参顺序合并为一个新的Stream流
@Test public void test3() { Streamst1 = Stream.of("aa","bb","cc","dd","ee"); Stream st2 = Stream.of("AA","BB","CC","DD","EE"); Stream st3 = Stream.concat(st1,st2); st3.forEach(s -> System.out.println(s)); } 8、Stream流的收集方法,还原成集合或数组
Collector tolist
Collector toSet
Collector Map
数组 .toArray
三、集合/不可变集合(of) 集合Collection1.如果希望元素可以重复,又有索引,索引查询要快
用Arraylist集合,基于数组。(用的最多)
2.如果希望元素可以重复,又有索引,增删首尾操作快
用linkedList集合,基于链表的
3.如果希望增删改查都快,但是元素不重复、无序、无索引
用HashSet集合,基于哈希表的
4.如果希望增删改查都快,但是元素不重复、有序、无索引
用linkedHashSet集合,基于哈希表和双链表
5.如果要对对象进行排序
用TreeSet集合,基于红黑树,后续也可以用List集合实现排序
Collection集合常用Api Collection是单列集合的祖宗接口,它的功能是全部单列集合都可以继承使用的 方法名 说明 boolean add(Ee) 把指定的对象添加到当前集合中 void clear() 清空集合中所有元素 boolean remove(E e) 把指定的对象在当前对象中删除 boolean contains(Objcct obj) 判断当前集合中是否包含给定的对象 boolean isEmpty() 判断当前集合是否为空 int size() 返回集合中元素的个数 Object[] toArray() 把集合中的元素,存储到数组中遍历集合 Collectionaqq = new ArrayList<>(); aqq.add(11); Iterator axx = aqq.iterator(); 1用迭代器 while(axx.hasNext()){ 用while循环 System.out.println(axx.next()); for (int axx :aqq) { 2foreach System.out.println(axx); aqq.forEach(System.out::println); 3、 lambda表达式 4、 for循环 //问题引出 **当我们从集合中找出某个元素并删除的时候可能出现一种并发修改异常问题 哪些遍历存在问题 1 迭代器遍历集合且直接用集合删除元素的时候可能出现 2 Foreach遍历集合且直接用集合删除元素的时候可能出现 解决方案 1 、迭代器遍历集合但是用迭代器自己的删除方法操作 2、 使用For循环遍历并删除元素不会存在这个问题( 倒着删,或者用删完一次后就i-- )拓展:泛型类 List接口 ArrayList常用方法1、add(Object element) 向列表的尾部添加指定的元素,且每次只能添加一个元素 2、size() 返回列表中的元素个数 3、get(int index) 返回列表中指定位置的元素,index从0开始,即第一个元素是从0开始调用 4、add(int index, Object element) 在列表的指定位置插入指定元素 5、set(int i, Object element) 将索引位置元素替换为元素element并返回被替换的元素。 6、clear() 从列表中移除所有元素 7、isEmpty() 判断列表是否包含元素,不包含元素则返回 true,否则返回false 8、contains(Object o) 如果列表包含指定的元素,则返回 true。 9、remove(int index)删除指定索引(从0开始)位置的元素,并将被删元素返回,将后面元素前移 10、remove(Object o) 移除集合中第一次出现的指定元素,移除成功返回true,否则返回false。返回boolean型(有才能删除),并后面元素前移 11、iterator() 返回按适当顺序在列表的元素上进行迭代的迭代器(按照地址顺序)1、add(Object element) 向列表的尾部添加指定的元素,且每次只能添加一个元素 import java.util.ArrayList; public class Test { public static void main(String[] args) { ArrayList list=new ArrayList<>(); list.add("Tom");//用于向List集合容器中尾部添加一个元素 } 2、size() 返回列表中的元素个数 package list; import java.util.ArrayList; public class Test { public static void main(String[] args) { ArrayList list=new ArrayList<>(); int length =list.size();//用于获取集合中有多少元素 System.out.println(length); } 3、get(int index) 返回列表中指定位置的元素,index从0开始,即第一个元素是从0开始调用 package list; import java.util.ArrayList; public class Test { public static void main(String[] args) { ArrayList list=new ArrayList<>(); list.add("Tom");//用于向List集合容器中尾部添加一个元素 System.out.println(list.get(0));//获取指定索引(从0开始)位置的元素 }//输出结果为Tom 4、add(int index, Object element) 在列表的指定位置插入指定元素 package list; import java.util.ArrayList; public class Test { public static void main(String[] args) { ArrayList list=new ArrayList<>(); list.add("Tom"); list.add(0, "Kate");//在指定位置添加元素,原来位置的元素后移 System.out.println(list.get(1)); }//此时输出为Tom,第一个元素为Kate,Tom顺势后移,所以为“1”的位置 5、set(int i, Object element) 将索引位置元素替换为元素element并返回被替换的元素。 package list; import java.util.ArrayList; import java.util.Iterator; public class Test { public static void main(String[] args) { ArrayList list=new ArrayList<>(); list.add("Tom"); list.add("Jim"); list.set(1, "Lucy"); System.out.println(list.get(1)); }//输出结果为Lucy 6、clear() 从列表中移除所有元素 package list; import java.util.ArrayList; public class Test { public static void main(String[] args) { ArrayList list=new ArrayList<>(); list.add("Tom"); list.add("Jim"); list.clear(); int length =list.size(); System.out.println(length); }//输出结果为0,证明集合中的元素已经被清空 7、isEmpty() 判断列表是否包含元素,不包含元素则返回 true,否则返回false package list; import java.util.ArrayList; public class Test { public static void main(String[] args) { ArrayList list=new ArrayList<>(); list.add("Tom"); boolean flag =list.isEmpty();//集合中没有元素,则true System.out.println(flag); }//结果为false,因为集合中存在元素 8、contains(Object o) 如果列表包含指定的元素,则返回 true。 public class Test { public static void main(String[] args) { ArrayListlinked Listlist=new ArrayList (); int flag=list.contains("Jim");//用来判断集合容器中是否含所有参考元素 System.out.println(flag); } 此时我们要考虑contains方法的底层代码包含的含义 public boolean contains(Object o) { return indexOf(o) >= 0; } public int indexOf(Object o) { if (o == null) { for (int i = 0; i < size; i++) if (elementData[i]==null) return i; } else { for (int i = 0; i < size; i++) if (o.equals(elementData[i])) return i; } return -1; } Object o是上转型对象,存储的是String类中对象的地址,看似调用的是Object类,但是因为JVM运行的时候是根据地址确定对象,所以为String类。其中elementData是一个数组,equals判断现有元素是否与数组元素的内容保持一致。 9、remove(int index)删除指定索引(从0开始)位置的元素,并将被删元素返回,将后面元素前移 package list; import java.util.ArrayList; public class Test { public static void main(String[] args) { list.add("Tom"); list.add("Jim"); String str=list.remove(0);//删除指定索引(从0开始)位置的元素,并将元素返回,并就后面元素前移 System.out.println(list.get(0)); } 10、remove(Object o) 移除集合中第一次出现的指定元素,移除成功返回true,否则返回false。返回boolean型(有才能删除),并后面元素前移 package list; import java.util.ArrayList; public class Test { public static void main(String[] args) { list.add("Tom"); list.add("Jim"); list.remove("Tom");//删除List集合元素,并返回boolean(有才能删除),并后面元素前移 System.out.println(list.get(0)); } 11、iterator() 返回按适当顺序在列表的元素上进行迭代的迭代器(按照地址顺序) package list; import java.util.ArrayList; import java.util.Iterator; public class Test { public static void main(String[] args) { ArrayList list=new ArrayList (); list.add("Tom"); list.add("Jim"); 1、 for(int i=0;i iterator=list.iterator();//将list集合中的元素转到iterator中,现在有两份,list和iterator while (iterator.hasNext()) {//判断当前“指针”下面是否还有元素 System.out.println(iterator.next());//如果指针下面还有元素,则移动指针并获取相应元素 } } 可以完成队列结构和栈结构以完成队列结构和栈结构 linkedListSet接口acc = new linkedList<>(); acc.push("第一颗子弹"); acc.push("第二颗子弹"); acc.push("第三颗子弹"); acc.push("第四颗子弹"); acc.push("第五颗子弹"); System.out.println(acc); System.out.println(acc.pop()); System.out.println(acc.pop()); System.out.println(acc.pop()); System.out.println(acc.pop()); linkedList arr = new linkedList<>(); arr.addLast("第一颗子弹"); arr.addLast("第er颗子弹"); arr.addLast("第san颗子弹"); arr.addLast("第si颗子弹"); arr.addLast("第wu颗子弹"); System.out.println(arr.removeFirst()); (无序不重复无索引)HashSet集合(无序不重复无索引) 底层:哈希表 JDK1.7 之前是数组加链表 JDK1.7 之后是数组链表加红黑树 哈希值 1、是JDK根据对象的地址,按照某种规则算出来的int类型的数值 2、public int hashCode();返回对象的哈希值 3、同一个对象多次调用方法返回的哈希值是相同的 **结论:如果希望Set集合认为2个内容一样的对象是重复的,必须重写对象的hashCode()和equals()方法 去重复的原理 重写hashCode后对象内容一样的生成的哈希值是一样的,linkedhashSet集合(有序不重复无索引)
TreeSet(不重复无索引可排序)
treeSet集合默认的规则
1、对于数值类型:Integer。Double,官方默认按照大小进行升序排序 2、对于字符串类型:默认按照首字符的编号升序 3、对于自定义类型:无法直接排序,需要制定排序规则 TreeSet集合自定义排序规则有几种方式 1、实现Comparable接口,重写比较规则 2、集合自定义Comparator比较器对象,重写比较规则 两种方式中,关于返回值的规则: 1、返回正整数就是升序 2、负数就是降序 3、0就是重复就会去除集合自带的比较器
集合MapMap集合和Collection集合的区别
Map集合是有Key和Value的,Collection集合是只有Value。
Collection集合底层也是有Key和Value,只是隐藏起来。
遍历方式一:键找值
Mapbox = new HashMap(); box.put("玩具",100); box.put("手机",10); box.put("手枪",50); System.out.println(box); Setjian = box.keySet(); for (String s : jian) { int zhi = box.get(s); System.out.println(s+zhi); 遍历方式二:键值对
Set> entries = box.entrySet(); for (Map.Entry entry : entries) { String key = entry.getKey(); Integer value = entry.getValue(); System.out.println(key+value); 遍历方式三:Lambda表达式
box.forEach((k,v)->{ System.out.println(k+v); });常用Api 1、V **put**(K key, V value) 向map集合中添加Key为key,Value为value的元素,当添加成功时返回null,否则返回value。 就是说Map集合中的Key是不能重复的,这就类似于Set集合中元素不能重复,但是Map集合中的Value是可以重复。 2、void **putAll**(Map extends K,? extends V> m) 向map集合中添加指定集合的所有元素 3、void **clear**() 把map集合中所有的键值删除 4、boolean **containsKey**(Object key) 检出map集合中有没有包含Key为key的元素,如果有则返回true,否则返回false。 5、boolean **containsValue**(Object value) 检出map集合中有没有包含Value为value的元素,如果有则返回true,否则返回false。 6、SetHashMap linkedHashMap TreeMap 四、异常> **entrySet**() 返回map到一个Set集合中,以map集合中的Key=Value的形式返回到set中。 补充:一般我们遍历HashMap的时候,推荐是用这种方式。不用再通过map的get(key)方法拿值,性能会提升。参考sonar代码规范 7、boolean **equals**(Object o) 判断两个map集合的元素是否相同 8、V **get**(Object key) 根据map集合中元素的Key来获取相应元素的Value 9、int **hashCode**() 返回map集合的哈希码值 10、boolean **isEmpty**() 检出map集合中是否有元素,如果没有则返回true,如果有元素则返回false 11、Set **keySet**() 返回map集合中所有Key 12、V **remove**(Object key) 删除Key为key值的元素 13、int **size**() 返回map集合中元素个数 14、Collection **values**() 返回map集合中所有的Value到一个Collection集合 异常分为两大类:
Error:描述了Java运行系统中的内部错误以及资源耗尽错误
唯一的解决方法:尽力使程序安全地终止Exception:编译期异常,写代码时java程序出现的问题(如日期格式列子)
运行时错误(RuntimeException):运行期异常,由程序错误导致。(如索引值溢出)
解决方法——异常处理
对于异常Java中提供了两种常见的方式:
–捕获异常
–抛出异常自定义异常
继承Exception或RuntimeException , 重写有参和无参构造方法
五、Logback日志框架public static final Logger LOGGER = LoggerFactory.getLogger("Test.class");六、File类1、File的作用
创建对象定位文件,可以删除、获取文件信息等。但是不能读写文件内容
2、构建对象的方式
File file = new File(“文件/文件/绝对路径/相对路径”) ;
3、绝对路径和相对路径是什么样的
绝对路径是带盘符的,依赖当前系统
相对路径是不带盘符的,默认相对到工程下开始寻找文件
File类的判断文件类型、获取文件信息功能 public boolean isDirectory() 测试此抽象路径名表示的File是否为文件夹 public boolean isFile() 测试此抽象路径名表示的File是否为文件 public boolean exists() 测试此抽象路径名表示的File是否存在 public String getAbsolutePath() 返回此抽象路径名的绝对路径名字符串 public String getPath() 将此抽象路径名转换为路径名字符串 public String getName() 返回由此抽象路径名表示的文件或文件夹的名称 public long lastModified() 返回文件最后修改的时间毫秒值File类创建文件的功能 public boolean createNewFile() 创建一个新的空的文件 public boolean mkdir() 只能创建一级文件夹 public boolean mkdirs() 可以创建多级文件夹 File类删除文件的功能 public boolean delete() 删除由此抽象路径名表示的文件或空文件夹 delete方法直接删除不走回收站;如果删除的是一个文件,且文件没有被占用则直接删除。 delete方法默认只能删除空文件夹。File类的遍历功能 public String[] list() 获取当前目录下所有的"一级文件名称"到一个字符串数组中去返回。 public File[] listFiles()(常用) 获取当前目录下所有的"一级文件对象"到一个文件对象数组中去返回(重点) listFiles方法注意事项: *当调用者不存在时,返回null *当调用者是一个文件时,返回null *当调用者是一个空文件夹时,返回一个长度为0的数组 *当调用者是一个有内容的文件夹时,将里面所有文件和文件夹的路径放在File数组中返回 *当调用者是一个有隐藏文件的文件夹时,将里面所有文件和文件夹的路径放在File数组中返回,包含隐藏内容 public static void main(String[] args) { searchFile(new File("D:/软件"),"QMDriverHelper.exe"); } private static void searchFile(File file,String name) { if (file != null){ File[] acc = file.listFiles(); if (acc.length>0 && acc!= null){ for (File file1 : acc) { if (file1.isFile()){ if (file1.getName().contains(name)){ System.out.println("找到了"+file1.getAbsolutePath()); } }else{ searchFile(file1,name); } } }七、IO流 字节流适合做数据的拷贝,不适合做读取中文内容的输出
字节转换文字 字节输入流FileInputStreamInputStream a = new FileInputStream("D:\Picture\2e69ee5de998c7120e9c627ca4152955.jpeg"); byte[] sum = new byte[1024]; int length ; while ((length=a.read(sum))!=-1){ System.out.println(new String(sum,0,length)); 读多少写倒多少readAllbytes读取全部的数据
字节输出流FileOutputStreamOutputStream s = new FileOutputStream("IO/src/date.txt");//创建文件**只要一创建就会清空之前的数据 s.write('Q'); 可以追加,在创建的时候后面加个true s.write(97); s.write("nr".getBytes()); //换行 byte[] c = "我是帅哥".getBytes(); s.write(c); s.write(c,0,6); // 可以规定写一个数组的开始位置和长度 s.flush(); //刷新流 s.close();//关闭流文件拷贝InputStream a = new FileInputStream("D:\Picture\2e69ee5de998c7120e9c627ca4152955.jpeg"); OutputStream b = new FileOutputStream("D:\Picture\hello\helloWord.jpeg"); byte[] sum = new byte[1024]; int length ; while ((length=a.read(sum))!=-1){ b.write(sum,0,length); } a.close(); b.close();释放资源 字符流适合做文本文件的操作
字符输入流FileRead 字符输出流FileWriter 缓冲流(高级流) 字节缓冲流(自带8KB的缓冲区)快~~~~ 字符缓冲流public BufferedReader(Reader r)
性能提升了,多了一个readLine()按照行读取的功能,无行可读就返回null
public BufferedWriter(Writer W)
性能提升了,多了newline()换行的功能
转换流 字符输入转换流 字符输出转换流 对象序列化、反序列化序列化
反序列化
打印流PrintStream和PrintWriter的区别
重定向
打印数据功能上是一模一样的,
都是使用方便,性能高效(核心优势)
PrintStream继承自字节输出流OutputStream,
支持写字节数据的方法。
PrintWriter继承自字符输出流Writer,支持写字符数据出去。System.out是一个静态常量
public static final printstream out = …;
set out是一个原生方法,不是在java语言中实现的,原生方法可以绕过java语言的访问控制机制
System.out.printLn("锦瑟无端五十弦"); System.out.println("一弦一柱思华年"); // 改变输出语句的位置(重定向) PrintStream ps = new PrintStream( "io-app2/src/Log.txt"); System.setout(ps);// 把系统打印流改成我们自己的打印流 System.out.printLn("庄生晓梦迷蝴蝶"); System.out.printun("望帝春心托杜鹃");Properties1.Properties的作用?
IO框架
可以存储Properties属性集的键值对数据到属性文件中去:
void store(Writer writer, String comments)
可以加载属性文件中的数据到Properties对象中来:
void load(Reader reader)第三方API commons-io
commons-io commons-io 2.11.0 八、多线程多线程是什么?
多线程的创建 方式一:继承Thread类
多线程是指从软硬件上实现多条执行流程的技术。继承Thread类
① 定义一个子类MyThread继承线程java.lang.Thread,重写run()方法
②创建MyThread类的对象
调用线程对象的start()方法启动线程(启动后还是执行run方法的)优缺点:
代码简单
线程类已经继承Thread类,无法继承其他类,不利于扩展
**为什么不直接调用了run方法,而是调用start启动线程。
直接调用run方法会当成普通方法执行,此时相当于还是单线程执行。**不要把主线程任务放在子线程之前
方式二:实现Runnable接口1、定义一个线程任务类MyRunnable实现Runnable接口,重写run()方法
2、创建MyRunnable任务对象
3、把myRnnable任务对象交给Thread处理
4、调用线程对象的start()方法启动线程
优缺点:可以继续继承类和实现接口,扩展性强
编程多一层对象包装,如果线程有执行结果是不可以直接返回的
函数式接口可以用lambda表达式
方式三:利用Callable、FutureTask接口实现(前两种方式没有返回结果)
1、得到任务对象
定义类实现Callable接口,重写call方法,封装要做的事情
用FutureTask把Callable对象封装成线程任务对象
2、把线程任务对象交给Thread处理
3、调用Thread的start方法启动线程,执行任务
4、线程执行完毕后,通过FutureTask的get方法去获取任务执行的结果
public static void main(String[] args) throws ExecutionException, InterruptedException { CallableThread常用方法call = new Threaddemo5(100); FutureTask task = new FutureTask<>(call); Thread test = new Thread(task); test.start(); String rs =task.get(); System.out.println(rs); } } class Threaddemo5 implements Callable { public Threaddemo5(int n) { this.n = n; } private int n; @Override public String call() throws Exception { int sum = 0; for (int i = 1; i <= n; i++) { sum+=i; } return "子线程执行的结果是"+sum; } 获取线程名称getName();
设置名称 setName();
获取当前线程对象currentThread();
让当前线程休眠指定的时间后再执行,单位为毫秒sleep();静态方法
其他后续学习
线程同步 1、同步代码块锁对象的规范要求
2、同步方法 3、lock锁 线程通信
。规范上:建议使用共享资源作为锁对象。
。对于实例方法建议使用ths作为锁对象。
。对于静态方法建议使用字节码(类名.class)对象作为锁对象。
1.同步代码块是如何实现线程安全的?
●对出现问题的核心代码使用synchronized进行加锁
●每次只能一个线程占锁进入访问
2.同步代码块的同步锁对象有什么要求?
·对于实例方法建议使用this作为锁对象。
●对于静态方法建议使用字节码(类名.class)对象作为锁对象。什么是线程通信、如何实现?
线程池
·所谓线程通信就是线程间相互发送数据。
线程通信常见形式
。通过共享一个数据的方式实现。
根据共享数据的情况决定自己该怎么做,以及通知其他线程怎么做。
线程通信实际应用模型
·生产者与消费者模型:生产者线程负责生产数据,消费者线程负责消费生产者产生的数据。
·一般要求:生产者线程生产完数据后唤醒消费者,然后等待自己,消费者消费完该数据后唤醒生产者,然后等待自己。方式一
方式二
定时器
定时器
线程状态 九、网络通信 1、IP地址
●定时器是一种控制任务延时调用,或者周期调用的技术。
●作用:闹钟、定时邮件发送。
定时器的实现方式
●方式一:Timer
●方式二:ScheduledExecutorService
IP地址:设备在网络中的地址,是唯一的标识。
端☐:应用程序在设备中唯一的标识。
协议: 数据在网络中传输的规则,常见的协议有UDP协议和TCP协议。说说网络通信至少需要几个要素
2、端口
IP、端☐、协议。IP地址是做什么的,具体有几种
定位网络上的设备的,有IPv4,IPv6.如何查看本机IP地址,如何看是否与对方互通
ipcofig
ping 192.168.10.23本机IP是谁?
127.0.0.1或者是localhost端口号的作用是什么?
唯一标识正在计算机设备上运行的进程(程序)一个设备中,能否出现2个应用程序的端口号一样,为什么?
3、协议
不可以,如果一样会出现端口冲突错误。传输层的2个常见协议
UDP(User Datagram Protocol):用户数据报协议
UDP协议:
UDP是一种无连接、不可靠传输的协议。
将数据源IP、目的地IP和端口封装成数据包,不需要建立连接
每个数据包的大小限制在64KB内
发送不管对方是否准备好,接收方收到也不确认,故是不可靠的
可以广播发送,发送数据结束时无需释放资源,开销小,速度快。
UDP协议通信场景
语音通话,视频会话等。UDP协议的特点是什么
用户数据报协议(User Datagram Protocol)
UDP是面向无连接,不可靠传输的通信协议。
速度快,有大小限制一次最多发送64K,数据不安全,易丢失数据。TCP
(Transmission Control Protocol)):传输控制协议
1、通信协议是什么?
。计算机网络中,连接和通信数据的规则被称为网络通信协议。
2、TCP通信协议的特点是什么样的?
●它是一种面向连接的可靠通信协议。
。传输前,采用“三次握手”方式建立连接,点对点的通信,所以可靠。
●
在连接中可进行大数据量的传输。
●通信效率较低。
TCP协议特点
使用TCP协议,必须双方先建立连接,它是一种面向连接的可靠通信协议。
传输前,采用“三次握手”方式建立连接,所以是可靠的 。
在连接中可进行大数据量的传输。
连接、发送数据都需要确认,
且传输完毕后,还需释放已建立的连接,通信效率较低。TCP协议通信场景
对信息安全要求较高的场景,例如:文件下载、金融等数据通信。
十、Junit单元测试框架 十一、反射
反射的作用?
获取class对象的三种方式 获取构造器创建对象 获取成员变量赋值取值 获取方法并使用
可以在运行时得到一个类的全部成分然后操作。
可以破坏封装性。(很突出)
也可以破坏泛型的约束性。(很突出)
更重要的用途是适合:做Java高级框架十二、注解
可以通过反射拿对象并解析注解
自定义注解 元注解元注解
注解的解析
元注解:就是注解注解的注解。
元注解有两个:
@Target:约束自定义注解只能在哪些地方使用,
@Retention:申明注解的生命周期解析注解的技巧
注解在哪个成分上,我们就先拿哪个成分对象。
比如注解作用成员方法,则要获得该成员方法对应的Method对象,再来拿上面的注解
比如注解作用在类上,则要该类的Class对象,再来拿上面的注解
比如注解作用在成员变量上,则要获得该成员变量对应的Fild对象,再来拿上面的注解public static void main(String[] args) throws InvocationTargetException, IllegalAccessException { Class十三、XML文件解析a = Test.class;//拿到类对象 Method[] declaredMethods = a.getDeclaredMethods();//拿类对象里所有方法 for (Method declaredMethod : declaredMethods) { if (declaredMethod.isAnnotationPresent(myTest.class)){ //过滤是否有注解的方法 declaredMethod.invoke(new Test()); //执行有注解的方法 } 使用Dom4解析出XML文件
需求:使用Dom4把一个XML文件的数据进行解析
分析:
1下载Dom4j框架,官网下载。
2在项目中创建一个文件夹:lib
3将dom4j-2.1.1.jar文件复制到lib文件夹
4在jar文件上点右键,选择Add as Library->点击OK
5在类中导包使用数据检索技术Xpath
四个方案



