API–Application Programming Interface应用编程接口,一切可以调用的东西都是API。
Object
–1,概念
类 Object 是类层次结构的根类。每个类都使用 Object 作为超类。
–2,常用方法
String toString()
返回该对象的字符串表示。
int hashCode()
返回该对象的哈希码值。
boolean equals(Object obj)
指示其他某个对象是否与此对象“相等”。
Class<?> getClass()
返回此 Object 的运行时类。
–3,测试
package cn.tedu.api;
//测试 Object类
//总结
//1,什么时候需要重写?--当父类提供的业务发生了改变
//2,为什么需要重写?
//toString()--是因为,默认打印的是地址值.但是我们想要打印的是属性值
//equals()--是因为,默认比较的是两个对象间的地址值,但是我们想要比较的是属性值
//eclipse工具都提供了对应快捷方式,右键-source-generate...
public class Test1_Object {
public static void main(String[] args) {
Student s = new Student("钟南山",85);
// System.out.println(s.getName());//钟南山
// System.out.println(s.getAge());//85
//1,--问题1:如果有很多属性,我们想查看所有属性的值,现在是一个一个get()才能看,能不能简化?
//现在默认打印了s的地址值:cn.tedu.api.Student@15db9742,
//但是我想要的是打印s的属性值!!--继承Object并且重写toString()
//println()底层会帮你自动调用Object的toString(),默认本来就会返回对象的地址值
System.out.println(s);//Student [name=钟南山, age=85]
//366712642,该对象的哈希码值--指给对象分配的存储位置。
System.out.println( s.hashCode() );
System.out.println( s.getClass() );//返回此 Object 的运行时类。
//boolean equals(Object obj) 指示其他某个对象是否与此对象“相等”。
Student s2 = new Student("钟南山",85);
//2,--问题2:使用了Object的equals(),默认就是拿着两个对象进行==比较
//== 比较基本类型的值时,比的是值本身,比如 2==3 得到false
//== 比较引用类型的值时,比的是地址值,比如s和s2比.new了两次,地址值肯定不同得到false
//新的需求:是别比较两个对象间的地址值,而是想要比较对象间的属性值,如果属性值都都一样,
//就说明在描述同一个对象,让对象间比较完是相等的,也就是让equals()返回true--重写equals()
boolean what = s.equals(s2);
//重写前,比的是对象间的地址值是false.重写后,比的是对象间的属性值,完全都一样返true
System.out.println(what);
}
}
//创建Student类,默认就已经继承了Object
class Student extends Object {
//提供丰富的构造方法,方便外界new
public Student() {}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
//给属性赋值的方式? -- 调用set() / 构造方法
private String name ;
private int age ;
//set()/get()-右键-source-generate getters and setters-select all-ok
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;
}
//---问题1,解决方案:重写Object的toString()--因为想看属性值,不想看地址值
//右键-source-generate toString()-ok
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
//--问题2,解决方案:重写Object的equals()--比较对象间的属性值而不是地址值
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
// @Override
// public boolean equals(Object obj) {
// //如果满足了判断条件(比较属性值),就是相等的,返回true
// //1,统一类型
// Student stu = (Student)obj;
// //2,开始比较--如果所有属性值完全相同,那就是同一个对象返回true
// if(this.name==stu.name && this.age==stu.age ) {
// return true;
// }
// return false;//默认是不相等的
// }
}
String
–1,特点
–字符串是常量
–它们的值在创建之后不能更改。
–摘抄源码:
public final class String{
//本质上,字符串里的数据,底层会开辟数组的空间来存放字符串数据.
//数组一旦创建,长度就不能改变!!而且value数组已经被final了,数组里的值也不能改了!!
private final char value[];
}
–2,创建对象
String(char[] value)
分配一个新的 String,使其表示字符数组参数中当前包含的字符序列。
–3,常用方法
char charAt(int index)
返回指定索引处的 char 值。
String concat(String str)
当且仅当此字符串包含指定的 char 值序列时,返回 true
boolean endsWith(String suffix)
测试此字符串是否以指定的后缀结束。
boolean equals(Object anObject)
将此字符串与指定的对象比较。
byte[] getBytes()
int indexOf(String str)
返回指定子字符串在此字符串中第一次出现处的索引。
int lastIndexOf(String str)
返回指定子字符串在此字符串中最右边出现处的索引。
boolean isEmpty()
当且仅当 length() 为 0 时返回 true。
int length()
返回此字符串的长度。
String replace(char oldChar, char newChar)
返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的。
String[] split(String regex)
根据给定正则表达式的匹配拆分此字符串。
boolean startsWith(String prefix)
测试此字符串是否以指定的前缀开始。
String substring(int beginIndex)
返回一个新的字符串,它是此字符串的一个子字符串。
String substring(int beginIndex, int endIndex)
返回一个新字符串,它是此字符串的一个子字符串。
char[] toCharArray()
将此字符串转换为一个新的字符数组。
String toUpperCase()
使用默认语言环境的规则将此 String 中的所有字符都转换为大写。
String trim()
返回字符串的副本,忽略前导空白和尾部空白。
static String valueOf(float f)
返回 float 参数的字符串表示形式。
static String valueOf(int i)
返回 int 参数的字符串表示形式。
static String valueOf(long l)
返回 long 参数的字符串表示形式。
–4,测试
package cn.tedu.api;
import java.util.Arrays;
//测试String类
public class Test2_String {
public static void main(String[] args) {
//1,创建对象
char[] value = new char[]{'a','b','c','a','d'};
//字符串底层维护了一个char数组,会把存入数据.字符串是常量值不能被修改.
String s = new String(value);//触发构造:String(char[] value)
String s2 = "abcdefabca";//简写
//2,常用方法
System.out.println( s2.charAt(2) );//c,获取下标2对应的字符
System.out.println( s2.concat("jack") );//在原有串的后面拼接指定数据
System.out.println( s2.endsWith("bca") );//判断是否以指定数据结尾
System.out.println( s2.equals("abcdefabca") );//判断是否与指定数据相等
System.out.println( s2.indexOf("b") );//获取b第一次出现的索引值
System.out.println( s2.lastIndexOf("a") );//获取a最后一次出现的索引值
System.out.println( s2.isEmpty() );//判断字符串是否为空
System.out.println( s2.length() );//获取字符串的长度
System.out.println( s2.replace('a','x') );//把原有的a字符替换成x字符
System.out.println( s2.startsWith("abc") );//判断字符串是否以abc开始
System.out.println( s2.substring(3) );//从下标为3的位置开始向后截取所有字符串
System.out.println( s2.substring(3,6) );//截取下标3到6的字符串,[3,6).含头不含尾
System.out.println( s2.toUpperCase() );//把字符串全转大写
s2 = " ab cdef " ;
System.out.println( s2.trim() );//去除前导后导多余空格
//字符串转数组
byte[] bs = s2.getBytes() ;//把字符串里的数据存入byte[]里
//[32, 97, 98, 32, 32, 32, 99, 100, 101, 102, 32]
System.out.println( Arrays.toString(bs));
char[] cs = s2.toCharArray() ;//把字符串里的数据存入char[]里
//[ , a, b, , , , c, d, e, f, ]
System.out.println( Arrays.toString(cs));
s2 = "102030405";
String[] ss = s2.split("0") ;//按照规则,切割字符串
//[1, 2, 3, 4, 5]
System.out.println( Arrays.toString(ss));
//把其他类型的数据 转成 字符串类型
System.out.println( String.valueOf(123) + 1);//1231
//TODO 接收键盘输入的字符串,并且打印每个字符
String str = new Scanner(System.in).nextLine() ;
//既然字符串底层维护了char[],就可以按照下标遍历
for(int i = 0 ; i < str.length() ; i++) {
char c = str.charAt(i) ;//根据下标获取对应的字符
System.out.println(c);
}
}
}
StringBuilder/StringBuffer
–1,特点
专门用来优化字符串的 拼接业务.
–源码摘抄:
public final class StringBuilder extends AbstractStringBuilder
implements java.io.Serializable, CharSequence{
/**
* The value is used for character storage.
*/
char[] value;
}
–2,创建对象
StringBuilder()
构造一个不带任何字符的字符串生成器,其初始容量为 16 个字符。
–3,常用方法
StringBuilder append(String str)
将指定的字符串追加到此字符序列。
–4,测试
package cn.tedu.api;
//测试 字符串拼接
public class Test3_StringBuilder {
public static void main(String[] args) {
// method() ;//用+拼接
method2() ;//用工具类 拼接
}
//用工具类 拼接
public static void method2() {
//1,把指定的字符串拼接10000次,并打印拼接结果
String s = "abcdefghijklmnopqrstuvwxyz";
//创建工具类对象
StringBuilder sb = new StringBuilder();
long start = System.currentTimeMillis() ;//计时开始ms
for (int i = 0; i < 10000; i++) {
sb.append(s) ;
}
long end = System.currentTimeMillis() ;//计时结束ms
System.out.println(end-start);//1ms
}
//用+拼接
public static void method() {
//1,把指定的字符串拼接10000次,并打印拼接结果
String s = "abcdefghijklmnopqrstuvwxyz";
String res = "";//定义变量,记录拼接的结果
long start = System.currentTimeMillis() ;//计时开始ms
for (int i = 0; i < 10000; i++) {
res = res + s; //用+拼接
}
long end = System.currentTimeMillis() ;//计时结束ms
System.out.println(end-start);//1278ms
}
}
包装类
–1,专门用来为基本类型提供丰富的功能
–2,基本类型:byte short int long float double char boolean
包装类型:Byte Short Integer Long Float Double Character Boolean
–4,Number
–包装类也有严格的继承结构
–抽象类Number是BigDecimal、BigInteger、Byte、Double、Float、Integer、Long和Short类的超类
–常用方法
byte byteValue()
以 byte 形式返回指定的数值。
abstract double doubleValue()
以 double 形式返回指定的数值。
abstract float floatValue()
以 float 形式返回指定的数值。
abstract int intValue()
以 int 形式返回指定的数值。
abstract long longValue()
以 long 形式返回指定的数值。
short shortValue()
以 short 形式返回指定的数值。
–5,Integer
–Integer 类在对象中包装了一个基本类型 int 的值。
–创建对象
Integer(int value)
构造一个新分配的 Integer 对象,它表示指定的 int 值。
static Integer valueOf(int i)
返回一个表示指定的 int 值的 Integer 实例。
–常用方法
static int parseInt(String s)
int intValue()
以 int 类型返回该 Integer 的值
–测试
package cn.tedu.api;
//测试 包装类
public class Test4_Number {
public static void main(String[] args) {
//1,创建对象 -- 把基本类型 变成 包装类型
//触发构造:Integer(int value)
Integer a = new Integer(5);
//static Integer valueOf(int i)
Integer b = Integer.valueOf(5);
//2,调用方法
int x = a.intValue();//把包装类型包装的值,拆出来,变成基本类型
System.out.println(x);
int y = Integer.parseInt("123");//把字符串类型的数字转成基本类型
System.out.println(y);
//Double -- 把基本类型的小数 包装成 包装类型
Double c = new Double(9.9);
Double d = Double.valueOf(9.9);
//把包装类型包装的值,拆出来,变成基本类型
double m = c.doubleValue() ;
System.out.println(m);
}
}
日期类Date
–1,表示特定的瞬间,精确到毫秒。它允许把日期解释为年、月、日、小时、分钟和秒值。
–2,创建对象
Date()
分配 Date 对象并初始化此对象,以表示分配它的时间(精确到毫秒)。
–3,常用方法
int getDate()
已过时。 从 JDK 1.1 开始,由 Calendar.get(Calendar.DAY_OF_MONTH) 取代。
int getDay()
已过时。 从 JDK 1.1 开始,由 Calendar.get(Calendar.DAY_OF_WEEK) 取代。
int getHours()
已过时。 从 JDK 1.1 开始,由 Calendar.get(Calendar.HOUR_OF_DAY) 取代。
int getMinutes()
已过时。 从 JDK 1.1 开始,由 Calendar.get(Calendar.MINUTE) 取代。
int getMonth()
已过时。 从 JDK 1.1 开始,由 Calendar.get(Calendar.MONTH) 取代。
int getSeconds()
已过时。 从 JDK 1.1 开始,由 Calendar.get(Calendar.SECOND) 取代。
long getTime()
返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。
int getTimezoneOffset()
已过时。 从 JDK 1.1 开始,由 -(Calendar.get(Calendar.ZONE_OFFSET) + Calendar.get(Calendar.DST_OFFSET)) / (60 * 1000) 取代。
int getYear()
已过时。 从 JDK 1.1 开始,由 Calendar.get(Calendar.YEAR) - 1900 取代。
–4,测试
package cn.tedu.api;
import java.util.Date;
//测试 Date类
public class Test1_Date {
public static void main(String[] args) {
//1,创建对象
Date date = new Date();
//2,常用方法
System.out.println( date.getYear() );//获取从1900年到现在有多少年?
System.out.println( date.getDate() );//一个月里的哪天
System.out.println( date.getDay() );//周几
System.out.println( date.getHours() );//现在是几点
System.out.println( date.getMinutes() );//现在是哪一分钟
System.out.println( date.getMonth() );//底层用0-11表示12个月
System.out.println( date.getSeconds() );//现在是具体哪一秒
System.out.println( date.getTime() );//自 1970 年 1 月 1 日 00:00:00到现在的毫秒值
System.out.println( date.toLocaleString() );//2020-7-17 10:35:21
}
}
日期工具SimpleDateFormat
–1,专门用来把日期格式进行转化的工具类.
–2,创建对象
SimpleDateFormat(String pattern)
用给定的模式和默认语言环境的日期格式符号构造 SimpleDateFormat。
–3,常用方法
–可以把Date类型的日期 转成 String类型
String format(Date date) 将给定的 Date 格式化为日期/时间字符串 StringBuffer。
–可以把String类型的日期 转成 Date类型
Date parse(String text) 解析字符串的文本,生成 Date。
–4,测试
package cn.tedu.api;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
//测试 SimpleDateFormat工具类
public class Test2_SimpleDF {
public static void main(String[] args) throws ParseException {
//1,创建对象--需要指定日期格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//2,常用方法
//接收用户输入的出生日期-年月日
String input = new Scanner(System.in).nextLine() ;//2020-10-1
Date birth = sdf.parse(input) ;//把字符串转Date
System.out.println( birth.getMonth() );//9
System.out.println( sdf.format(birth) );//把Date转成字符串
//练习1 :计算存活天数
long birthday = birth.getTime() ;//获取出生时的毫秒值
long now = System.currentTimeMillis() ;//获取现在的毫秒值
System.out.println( (now-birthday)/1000/60/60/24 );//ms->天
}
}
BigDecimal/BigInteger
–1,BigDecimal专门用来解决小数运算不精确的解决方案
–2,BigInteger专门用来处理超大整数运算的解决方案
–3,BigDecimal创建对象
BigDecimal(double val) – 有坑
BigDecimal(String val) – 提倡
–4,常用方法
BigDecimal add(BigDecimal augend) --加法运算
BigDecimal subtract(BigDecimal subtrahend) --减法运算
BigDecimal multiply(BigDecimal multiplicand) --乘法运算
BigDecimal divide(BigDecimal divisor) --除法运算
–5,测试
package cn.tedu.api;
import java.math.BigDecimal;
import java.util.Scanner;
//测试 小数运算精确的解决方案
public class Test3_BigDecimal {
public static void main(String[] args) {
// method() ;//暴露问题
method2() ;//解决浮点数运算不精确
}
private static void method2() {
//接收用户输入的两个小数 ,并做 +-*/ 运算
double a = new Scanner(System.in).nextDouble() ;
double b = new Scanner(System.in).nextDouble() ;
//1,创建BigDecimal对象
// BigDecimal(double val) -- 有坑,更不精确了!!!!
// BigDecimal bd1 = new BigDecimal(a);
// BigDecimal bd2 = new BigDecimal(b);
// BigDecimal(String val) -- 提倡 -- 把a b转成String类型
BigDecimal bd1 = new BigDecimal(a+"");
BigDecimal bd2 = new BigDecimal(b+"");
BigDecimal bd3 = bd1.add(bd2);//加法运算
System.out.println(bd3);
bd3 = bd1.subtract(bd2);//减法运算
System.out.println(bd3);
bd3 = bd1.multiply(bd2);//乘法运算
System.out.println(bd3);
//除法运算时,如果发生了除不尽的现象,直接抛出异常:java.lang.ArithmeticException:
//Non-terminating decimal expansion; no exact representable decimal result.
// bd3 = bd1.divide(bd2);//除法运算
//divide(a,b,c);-a是要做除法运算的对象-b是保留的小数位数-c是舍入方式
bd3 = bd1.divide(bd2,5,BigDecimal.ROUND_HALF_UP);//除法运算
System.out.println(bd3);
}
//暴露问题
public static void method() {
//接收用户输入的两个小数 ,并做 +-*/ 运算
double a = new Scanner(System.in).nextDouble() ;
double b = new Scanner(System.in).nextDouble() ;
System.out.println(a+b);//不精确
System.out.println(a-b);//不精确
System.out.println(a*b);//不精确
System.out.println(a/b);//不精确
}
}
File类
–1,文件和目录路径名的抽象表示形式。
–2,创建对象
File(String pathname)
通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例。
–3,常用方法
略,同网页版笔记
–4,测试
package cn.tedu.io;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
//测试 File类
public class Test4_File {
public static void main(String[] args) throws IOException {
//1,创建对象--封装文件或者文件夹的路径
File file = new File("D:\\iotest\\1.txt");
//2,常用方法
System.out.println( file.length() );//求字节量
System.out.println( file.exists() );//判断文件是否存在
System.out.println( file.isFile() );//判断是否是一个文件
System.out.println( file.isDirectory() );//判断是否是一个文件夹
System.out.println( file.getName() );//获取文件名
System.out.println( file.getParent() );//获取父路径
System.out.println( file.getAbsolutePath() );//获取完整路径
System.out.println( file.createNewFile() );//创建一个不存在的文件
file = new File("D:\\iotest\\abc");
System.out.println( file.mkdir() );//新建一个不存在的文件夹
//
// file = new File("D:\\iotest\\abc\\x\\y\\z");
// System.out.println( file.mkdirs() );//新建多个不存在的文件夹
//
// file = new File("D:\\iotest\\222.txt");
// System.out.println( file.delete() );//删除文件 或者 空的文件夹
//列出文件夹里的资源
file = new File("D:\\iotest");//指定文件夹路径
String[] strs = file.list();//获取文件名 并存入String[]
// [1.txt, abc]
System.out.println(Arrays.toString(strs));
File[] files = file.listFiles();//获取文件 并存入File[]
// [D:\iotest\1.txt, D:\iotest\abc]
System.out.println(Arrays.toString(files));
//TODO 接收用户输入的一串路径
String path = new Scanner(System.in).nextLine();
File f = new File(path);
//判断如果是文件,求文件的字节量
if(f.isFile()) {//如果是文件,返回true
System.out.println( f.length() );
}else if(f.isDirectory()) {//如果是文件夹,返回true
File[] fs = f.listFiles();//判断如果是文件夹,列出所有资源
System.out.println(Arrays.toString(fs));
}
}
}
–5,练习2:递归求目录总大小
package cn.tedu.io;
import java.io.File;
import java.util.Scanner;
//测试 递归求目录总大小
public class Test5_Digui {
public static void main(String[] args) {
//接收用户输入的 文件夹!!!! 路径
String path = new Scanner(System.in).nextLine();
File dir = new File(path);//封装成File对象
long total = size(dir);//调用size求总大小
System.out.println(total);
}
//创建size求总大小
public static long size(File dir) {
//1,列出文件夹下的所有资源
File[] fs = dir.listFiles() ;
long sum = 0 ;//定义变量,记录总和
//遍历数组
//如果你输入的是文件路径,直接抛出异常:java.lang.NullPointerException
//原因是,你调用了为null的对象,身上的功能
for (int i = 0; i < fs.length; i++) {
//获取每个资源fs[i]
//2,判断当前资源是文件吗?是就直接.length()求和
if( fs[i].isFile() ) {
sum = sum + fs[i].length() ;
}else if( fs[i].isDirectory() ) {
//3,判断当前资源是文件夹吗?开始重复1 2 3 ....过程和size()一样
sum = sum + size(fs[i]);//递归调用,在方法内部再调用方法本身
}
}
return sum;//把总大小用return返回给调用位置
}
}
递归删除文件夹
–代码
package cn.tedu.io;
import java.io.File;
import java.util.Scanner;
//测试 递归求目录总大小
public class Test6_Digui2 {
public static void main(String[] args) {
//接收用户输入的 文件夹!!!! 路径
String path = new Scanner(System.in).nextLine();
File dir = new File(path);//封装成File对象
del(dir);//调用方法删除指定文件夹
}
//删除指定文件夹
public static void del(File dir) {
//1,列出文件夹下的所有资源
File[] fs = dir.listFiles() ;
//遍历数组
//如果你输入的是文件路径,直接抛出异常:java.lang.NullPointerException
//原因是,你调用了为null的对象,身上的功能
for (int i = 0; i < fs.length; i++) {
//获取每个资源fs[i]
//2,判断当前资源是文件吗?是就直接删除
if( fs[i].isFile() ) {
fs[i].delete() ;
}else if( fs[i].isDirectory() ) {
//3,判断当前资源是文件夹吗?开始重复1 2 3 ....过程和del()一样
del(fs[i]);//递归调用,在方法内部再调用方法本身
}
}
dir.delete() ;//删除空文件夹
System.out.println("文件夹删除成功!!");
}
}
字节流 – 对所有二进制文件都可以进行读写操作,更加常用!
–读取 : 指把磁盘中的数据 读取 到程序中.in
–写出 : 指把程序中准备好的数据 写出 到磁盘中.out
字节读取流
–InputStream – 字节读取流的 抽象 父类 – 不能new,我们只能学习他的共性方法
–常用方法
void close()
关闭此输入流并释放与该流关联的所有系统资源。
abstract int read()
从输入流中读取数据的下一个字节。
int read(byte[] b)
从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中
int read(byte[] b, int off, int len)
将输入流中最多 len 个数据字节读入 byte 数组。
–FileInputStream – 学习子类创建对象
–FileInputStream 从文件系统中的某个文件中获得输入字节。
–创建对象
FileInputStream(String pathname)
FileInputStream(File file)
–BufferedInputStream – 学习子类创建对象
–BufferedInputStream 为另一个输入流添加一些功能,会创建一个内部缓冲区数组。
–创建对象
BufferedInputStream(InputStream in)
创建一个 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。
BufferedInputStream(InputStream in, int size)
创建具有指定缓冲区大小的 BufferedInputStream 并保存其参数,即输入流 in, 以便将来使用。
–测试
package cn.tedu.io;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
//测试 字节读取流
//FileInputStream BufferedInputStream都可以用来读取
//效率上来讲: BufferedInputStream > FileInputStream
//原因是:FileInputStream 是一个一个字节的读取
//BufferedInputStream是一个数组一个数组的读取/缓冲流/高级流
//本质上,底层就是维护了一个byte[]数组叫 buf,用来缓冲数据,默认大小是8192,8*1024字节=8K数据.
//把数组里的数据一次性的给程序读取进来.减少了程序冲流里获取数据的次数,提高了效率
public class Test1_InputStream {
public static void main(String[] args) throws IOException {
// FIS();//FileInputStream读取流
BIS();//BufferedInputStream读取流
}
//BufferedInputStream读取流
private static void BIS() throws IOException {
//1,创建对象
InputStream in = new BufferedInputStream( new FileInputStream("D:\\iotest\\1.txt") );
//2,开始读取
int b = 0 ;//定义变量,记录read()返回的值
while( ( b = in.read() ) != -1) {
System.out.println(b);
}
//3,释放资源
in.close();
}
//FileInputStream读取流
public static void FIS() throws IOException {
//1,创建多态对象 -- 读取指定位置的文件
//触发了FileInputStream的String类型参数的构造方法
InputStream in = new FileInputStream("D:\\iotest\\1.txt");
//触发了FileInputStream的File类型参数的构造方法
// File file = new File("D:\\iotest\\1.txt");
// InputStream in2 = new FileInputStream(file);
InputStream in2 = new FileInputStream( new File("D:\\iotest\\1.txt") );
//2,开始读取
// int b = in.read() ;//读取方法返回值是整数
// System.out.println( b );//a->97
// System.out.println( in.read() );//98
// System.out.println( in.read() );//99
// //--问题1:如果没数据了,还能读吗?--可以读,永远返回-1!!
// System.out.println( in.read() );//-1
// System.out.println( in.read() );//-1
//---改造,重复执行read()
int b = 0 ;//b记录读取到的数据
while( ( b = in.read() ) != -1) {//-1代表没数据可读了
System.out.println(b);//打印读取到的数据
}
//3,释放资源
in.close();
in2.close();
}
}
字节写出流
–OutputStream–字节写出流的父类,被修饰成立一个抽象类,不能new只能学习共性方法
–常用方法
void close()
关闭此输出流并释放与此流有关的所有系统资源。
void flush()
刷新此输出流并强制写出所有缓冲的输出字节。
void write(byte[] b)
将 b.length 个字节从指定的 byte 数组写入此输出流。
void write(byte[] b, int off, int len)
将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。
abstract void write(int b)
将指定的字节写入此输出流。
–FileOutputStream–方法都是从父类继承来的,那就直接学习子类创建对象
–是用于将数据写出到文件中的输出流
–创建对象
FileOutputStream(String name)
FileOutputStream(File file)
FileOutputStream(File file, boolean append)
FileOutputStream(String name, boolean append)
–BufferedOutputStream–方法都是从父类继承来的,那就直接学习子类创建对象
–该类实现缓冲的输出流
–创建对象
BufferedOutputStream(OutputStream out)
创建一个新的缓冲输出流,以将数据写入指定的底层输出流。
BufferedOutputStream(OutputStream out, int size)
创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的底层输出流。
–测试
package cn.tedu.io;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
//测试 字节写出流
//1,效率上来讲:BufferedOutputStream > FileOutputStream
//2,原因:
//FileOutputStream是一个一个字节向磁盘输出
//BufferedOutputStream是一个数组一个数组向磁盘输出/高级流/缓冲流
//本质上,底层维护了一个byte[] buf,用来缓冲数据.默认大小是8192,相当于8K
public class Test2_OutputStream {
public static void main(String[] args) throws IOException {
// FOS();//FileOutputStream写出流
BOS();//BufferedOutputStream写出流
}
//BufferedOutputStream写出流
private static void BOS() throws IOException {
//1,创建对象--把数据写出到指定文件中
//默认的数据覆盖模式
//OutputStream out = new BufferedOutputStream(
// new FileOutputStream("D:\\iotest\\1.txt"));
//TODO 数据追加模式
OutputStream out = new BufferedOutputStream(
new FileOutputStream("D:\\iotest\\1.txt",true));
//2,开始写出
out.write(49);
out.write(49);
out.write(49);
//3,释放资源
out.close();
}
//FileOutputStream写出流
private static void FOS() throws IOException {
//1,创建对象--指把数据写出到磁盘的哪个文件中去
//OutputStream out = new FileOutputStream("D:\\iotest\\1.txt");//默认就是数据覆盖模式
OutputStream out = new FileOutputStream("D:\\iotest\\1.txt",true);//数据追加模式
//OutputStream out2 = new FileOutputStream(new File("D:\\iotest\\1.txt"));
//2,开始写出
out.write(97);
out.write(98);
out.write(99);
//3,释放资源
out.close();
// out2.close();
}
}
字符流 – 只能对字符文件txt进行读写操作
–读取 : 指把磁盘中的数据 读取 到程序中.in
–写出 : 指把程序中准备好的数据 写出 到磁盘中.out
字符读取流
–Reader–用于读取字符流的抽象类,不能new只能学习共性方法
–常用方法
abstract void close()
关闭该流并释放与之关联的所有资源。
int read()
读取单个字符。
int read(char[] cbuf)
将字符读入数组。
abstract int read(char[] cbuf, int off, int len)
将字符读入数组的某一部分。
–FileReader–方法都是继承来的,我们重点学习创建对象
–用来读取字符文件的便捷类。
–创建对象
FileReader(String fileName)
FileReader(File file)
–BufferedReader–方法都是继承来的,我们重点学习创建对象
–从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。可以 指定缓冲区的大小,或者可使用默认的大小。大多数情况下,默认值就足够大了。
–创建对象
BufferedReader(Reader in)
创建一个使用默认大小输入缓冲区的缓冲字符输入流。
–测试
package cn.tedu.io;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
//测试 字符读取流
//效率上谁快:BufferedReader > FileReader
//原因:
//FileReader 是一个一个字符的读取
//BufferedReader 是一个数组一个数组的读取
//本质上,就是因为底层维护了一个char[] cb,用来缓冲数据,默认大小是8192相当于8K
public class Test3_Reader {
public static void main(String[] args) throws IOException {
// FR();//FileReader读取流
BR();//BufferedReader读取流
}
//BufferedReader读取流
private static void BR() throws IOException {
//1,创建对象
Reader in = new BufferedReader(new FileReader("D:\\iotest\\1.txt"));
//2,开始读取
int b = 0 ;
while( ( b=in.read() ) != -1) {
System.out.println(b);
}
//3,释放资源
in.close();
}
//FileReader读取流
public static void FR() throws IOException {
//1,创建对象
Reader in = new FileReader("D:\\iotest\\1.txt");//触发了String参数的构造
// Reader in = new FileReader( new File("D:\\iotest\\1.txt") );//触发了File参数的构造
//2,开始读取
// System.out.println( in.read() );
// System.out.println( in.read() );
// System.out.println( in.read() );
// System.out.println( in.read() );
// System.out.println( in.read() );
// System.out.println( in.read() );
// //问题1:没数据也可以继续读取,不会抛出异常,只不过永远返回-1
// System.out.println( in.read() );
// System.out.println( in.read() );
//TODO --改造
int b = 0 ;//定义变量,记录读取到的数据
while( ( b=in.read() ) != -1) {//只要有数据就一直读,如果是-1就代表没数据了
System.out.println(b);
}
//3,释放资源
in.close();
}
}
字符写出流
–Writer–字符流写出流的父类,被修饰为了抽象类.不能new,只能学习共性方法
–常用方法
abstract void close()
关闭此流,但要先刷新它。
abstract void flush()
刷新该流的缓冲。
void write(char[] cbuf)
写入字符数组。
abstract void write(char[] cbuf, int off, int len)
写入字符数组的某一部分。
void write(int c)
写入单个字符。
void write(String str)
写入字符串。
void write(String str, int off, int len)
写入字符串的某一部分。
–FileWriter–子类继承了父类的所有方法,重点学习子类创建对象
–用来写入字符文件的便捷类。
–创建对象
FileWriter(File file)
FileWriter(String fileName)
FileWriter(File file, boolean append)
FileWriter(String fileName, boolean append)
–BufferedWriter子类
–将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。可以指定缓冲区 的大小,或者接受默认的大小。在大多数情况下,默认值就足够大了。
–创建对象
BufferedWriter(Writer out)
创建一个使用默认大小输出缓冲区的缓冲字符输出流。
–测试
package cn.tedu.io;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
//测试 字符写出流
public class Test4_Writer {
public static void main(String[] args) throws IOException {
FW();//FileWriter写出流
// BW();//TODO BufferedWriter写出流
}
//FileWriter写出流
private static void FW() throws IOException {
//1,创建对象
// Writer out = new FileWriter("D:\\iotest\\1.txt");//默认就是数据覆盖模式
Writer out = new FileWriter("D:\\iotest\\1.txt",true);//数据追加模式
// Writer out = new FileWriter( new File("D:\\iotest\\1.txt") );
//2,开始写出
out.write(97);
out.write(97);
out.write(97);
out.write("大家好,我叫皮皮霞!!!");
//3,释放资源
out.close();
}
}
字符流写出
–代码:
package cn.tedu.io;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
//测试 字符写出流
public class Test4_Writer {
public static void main(String[] args) throws IOException {
// FW();//FileWriter写出流
BW();//TODO BufferedWriter写出流
}
//BufferedWriter写出流
private static void BW() {
Writer out = null;
try {
//1,创建对象
out = new BufferedWriter( new FileWriter("D:\\iotest\\1.txt") ) ;
//2,开始写出
out.write("今天电影院开业,你准备好了吗?");
} catch (IOException e) {
e.printStackTrace();
} finally{//finally语句块,就是保证无论会不会出现异常,都一定要执行的代码
//3,释放资源--必须保证一定会执行!
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//FileWriter写出流
private static void FW() throws IOException {
//1,创建对象
// Writer out = new FileWriter("D:\\iotest\\1.txt");//默认就是数据覆盖模式
Writer out = new FileWriter("D:\\iotest\\1.txt",true);//数据追加模式
// Writer out = new FileWriter( new File("D:\\iotest\\1.txt") );
//2,开始写出
out.write(97);
out.write(97);
out.write(97);
out.write("大家好,我叫皮皮霞!!!");
//3,释放资源
out.close();
}
}
泛型
–1,概念
作用就类似于项目经理检查学员是这个班的吗?–做出类型检查.泛型的标志 <元素 的类型>,英文是Generics.是JDK1.5 的一个新特性,其实就是一个『语法糖』,本质上 就是编译器为了提供更好的可读性而提供的一种小手段,小技巧,虚拟机层面是不 存在所谓『泛型』的概念的。
–2,作用
–通过泛型的语法定义,约束集合元素的类型,进行安全检查,把错误显示在编译期
–代码通用性更强,后面有案例
–泛型可以提升程序代码的可读性,但它只是一个语法糖(编译后这样的东西就被删除, 不出现在最终的源代码中),对于JVM运行时的性能是没有任何影响的。
–3,泛型使用的位置
–类/接口上 – public class Student{}
–方法上 --public void eat(E e){}
–4,测试
package cn.tedu.collection;
import java.util.ArrayList;
import java.util.List;
// 测试 泛型
public class Test2_Generics {
public static void main(String[] args) {
//泛型来是想要模拟数组--统一数据类型--编译期就报错
// String[] a = {"1","c","av",123,1.1};
//泛型的作用--检查集合中的元素类型 --如果类型不对,编译期报错
List list = new ArrayList();
//集合中可以添加任意类型的数据!!!---太自由!!!
list.add(1.1);
list.add(10);
list.add(true);
list.add("jack");
System.out.println(list);
//想要约束集合中的元素类型?--泛型
List<String> list2 = new ArrayList();
list2.add("jack");
//添加失败,因为元素的类型,没有通过泛型的类型String检查
// list2.add(1.1);
// list2.add(5);
// list2.add(false);
//泛型里约束的元素的类型,必须是引用类型,不能是基本类型
List<Integer> list3 = new ArrayList<>();
list3.add(1);
list3.add(2);
list3.add(3);
}
}
集合
–1,概述
目前程序中,如果出现了多个数据需要存储.解决方案就是数组.但是数组有缺点.
–长度固定,数组一旦创建长度不可改变
–数组里元素的类型太单调,都是统一的
–数组的遍历方式太单一,用下标遍历
–如果有大量的数据需要存储,可以使用集合.
–集合工具类,都在java.util.*包里
–2,继承结构
–Collection是顶级接口
–List接口:
–ArrayList实现类
–LinkedList实现类
–Set接口:
–HashSet实现类
–TreeSet实现类
–Map接口:
Collection接口
–1,概述
Collection 层次结构 中的根接口。Collection 表示一组对象,这些对象也称为 collection 的元素。一些 collection 允许有重复的元素,而另一些则不允许。一些 collection 是有序的,而另一些则是无序的。
–2,常用方法
略,参考字典
–3,测试
package cn.tedu.collection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
//测试 集合
public class Test3_Collection {
public static void main(String[] args) {
//1,创建对象
Collection<Integer> c = new ArrayList<>();
//2,常用方法
c.add(1);
c.add(2);
c.add(3);
c.add(5);
c.add(4);
// c.clear();//清空集合
System.out.println(c.contains(1) );//判断是否包含指定元素
System.out.println(c.equals(1) );//判断集合是否和指定元素相等
System.out.println(c.hashCode() );//获取集合在内存中的哈希码值
System.out.println(c.isEmpty() );//判断集合是否为空
System.out.println(c.remove(2) );//移除指定元素
System.out.println(c.size() );//获取集合的长度
Object[] os = c.toArray() ;//把元素存入数组
//[1, 3, 5, 4]
System.out.println( Arrays.toString(os) );
//----------集合间的操作
Collection<Integer> c2 = new ArrayList<>();
c2.add(1);
c2.add(2);
c2.add(3);
System.out.println( c.addAll(c2) );//把c2添加到c里面
System.out.println( c.containsAll(c2) );//判断c中是否包含c2
//System.out.println( c.removeAll(c2) );//删除交集元素
System.out.println( c.retainAll(c2) );//取差集
System.out.println(c);
//TODO 迭代/循环/遍历 集合
// Iterator<E> iterator() --返回可以迭代集合的迭代器
Iterator<Integer> it = c.iterator() ;
while( it.hasNext() ) {//判断集合中是否有下一个元素,有就返回true
Integer in = it.next() ;//获取下一个元素
System.out.println(in);
}
}
}
List接口
–1,有序的 collection(也称为序列)。此接口的用户可以对列表中每个元素的插入位置进 行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元 素。与 set 不同,列表通常允许重复的元素。列表本身允许 null 元素,通常它们允 许多个 null 元素。
–2,特点
–元素有序
–元素有下标
–允许重复元素
–可以存 null 元素
–3,常用方法
–继承来的-略
–特有的
void add(int index, E element)
在列表的指定位置插入指定元素(可选操作)。
boolean addAll(int index, Collection<? extends E> c)
将指定 collection 中的所有元素都插入到列表中的指定位置(可选操作)。
E get(int index)
返回列表中指定位置的元素。
int indexOf(Object o)
返回此列表中第一次出现的指定元素的索引;
int lastIndexOf(Object o)
返回此列表中最后出现的指定元素的索引
ListIterator listIterator()
返回此列表元素的列表迭代器(按适当顺序)。
E remove(int index)
移除列表中指定位置的元素(可选操作)。
E set(int index, E element)
用指定元素替换列表中指定位置的元素(可选操作)。
List subList(int fromIndex, int toIndex)
返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分
–4,测试
package cn.tedu.collection;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
//测试 List接口
public class Test4_List {
public static void main(String[] args) {
//1,创建对象
List<String> list = new ArrayList<>() ;
//2,常用方法
//TODO --继承自Collection接口的方法
list.add("xiongda");
list.add("xionger");
list.add("guangtq");
list.add(null);
list.add("xiongda");
list.add("xionger");
//List特点:元素有序+元素可以重复+可以存null+元素都有下标
System.out.println(list);
//----List接口的特有方法们---都是根据下标操作数据的方式
list.add(2,"美队") ;//在指定下标处,插入指定的元素
System.out.println(list);
System.out.println(list.get(2));//根据下标获取元素
//获取指定元素第一次出现的索引值
System.out.println( list.indexOf("xiongda") );
//获取指定元素最后一次出现的索引值
System.out.println( list.lastIndexOf("xiongda") );
System.out.println( list.remove(2) );//按照索引删除元素并返回被删除的元素是谁
System.out.println( list.set(1, "皮皮霞"));//把指定索引对应的值替换掉
//截取前:[xiongda, 皮皮霞, guangtq, null, xiongda, xionger]
List<String> list2 = list.subList(2, 4);//[2,4)含头不含尾的截取子List
System.out.println(list2);//截取前:[guangtq, null]
//TODO 迭代List接口的方式:
//Iterator<E> iterator()
Iterator<String> it = list.iterator() ;
while(it.hasNext()) {//判断有下一个元素吗
String s = it.next() ;//获取下一个元素
System.out.println(s);
}
//Iterator<E> iterator() --继承自Collection--返回父接口--向后遍历
//ListIterator<E> listIterator() --子接口List--返回子接口--向后遍历/逆向遍历
ListIterator<String> it2 = list.listIterator() ;
while(it2.hasNext()) {//判断有下一个元素吗
String s = it2.next() ;//获取下一个元素
System.out.println(s);
}
//for循环
for(int i = 0 ; i < list.size() ; i++) {
System.out.println( list.get(i) );
}
//增强for/foreach -- for(数据的类型 变量名 : 要遍历的数据 ){ }
for(String s : list) {
System.out.println(s);
}
}
}
ArrayList实现类
–1,概述
List 接口的大小可变数组的实现。每个 ArrayList 实例都有一个容量。该容量是指 用来存储列表元素的数组的大小。
–2,特点
–元素有下标
–元素可重复
–元素有序
–底层是一个数组.方便查询.
–3,创建对象
ArrayList()
构造一个初始容量为 10 的空列表。
–4,测试
package cn.tedu.collection;
import java.util.ArrayList;
//测试 ArrayList
public class Test5_ArrayList {
public static void main(String[] args) {
//1,创建对象
//ArrayList底层为了一个数组Object[],用来存储多个元素.
//数组的默认大小是10.大于10的时候,底层会自动扩容.扩容方式是:是以前容量的1.5倍
ArrayList<Integer> list = new ArrayList<>();
//TODO 2,常用方法
//--继承自Collection接口的方法
list.add(1);
//--继承自List接口的方法
}
}
LinkedList实现类
–1,概述
是List接口的链接列表实现。
–2,特点
–底层是链表结构
–元素有序
–元素可重复
–元素有下标
–3,常用方法
–继承自List接口的方法 – 略
–继承自Collection接口的方法 – 略
–实现类自己的特有方法
void addFirst(E e)
将指定元素插入此列表的开头。
void addLast(E e)
将指定元素添加到此列表的结尾。
E getFirst()
返回此列表的第一个元素。
E getLast()
返回此列表的最后一个元素。
E removeFirst()
移除并返回此列表的第一个元素。
E removeLast()
移除并返回此列表的最后一个元素。
boolean offer(E e)
将指定元素添加到此列表的末尾(最后一个元素)。
boolean offerFirst(E e)
在此列表的开头插入指定的元素。
boolean offerLast(E e)
在此列表末尾插入指定的元素。
E peek()
获取但不移除此列表的头(第一个元素)。
E peekFirst()
获取但不移除此列表的第一个元素;如果此列表为空,则返回 null。
E peekLast()
E poll()
获取并移除此列表的头(第一个元素)
E pollFirst()
获取并移除此列表的第一个元素;如果此列表为空,则返回 null。
E pollLast()
获取并移除此列表的最后一个元素;如果此列表为空,则返回 null。
–4,创建对象
LinkedList()
构造一个空列表。
–5,测试
package cn.tedu.collection;
import java.util.LinkedList;
//测试 LinkedList
public class Test1_LinkedList {
public static void main(String[] args) {
//1,创建对象--底层是链表结构
LinkedList<Integer> list = new LinkedList<>();
//2,常用方法
//TODO 继承自List接口的方法
//TODO 继承自Collection接口的方法
list.add(1);
list.add(2);
list.add(3);
System.out.println(list);
//--实现类自己的特有方法--针对首尾元素进行操作
list.addFirst(99);//添加首元素
list.addLast(100);//添加尾元素
System.out.println(list);//[99, 1, 2, 3, 100]
System.out.println( list.getFirst());//获取首元素
System.out.println( list.getLast());//获取尾元素
System.out.println( list.removeFirst());//移除首元素
System.out.println( list.removeLast());//移除尾元素
System.out.println(list);//[1, 2, 3]
}
}
Set接口
–1,概述
一个不包含重复元素的 collection,最多包含一个 null 元素
–2,特点
–元素不能重复
–元素没有下标
–元素无序
–3,方法
–全都是 继承自Collection接口的方法
–4,测试
package cn.tedu.collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
//测试 Set接口
public class Test2_Set {
public static void main(String[] args) {
//1,创建对象 -- set通常用来给数据去重!!!
Set<String> set = new HashSet<>();
//TODO 2,常用方法
//全都是 继承自Collection接口的方法
set.add("2a");
set.add("1b");
set.add("d");
set.add("c");
set.add("jack");
set.add(null);
set.add("2a");
set.add("1b");
set.add("d");
//set是无序的+可以添加一个null+元素不能重复!!!
System.out.println(set);
//迭代set集合里的元素
//方式1:Iterator<E> iterator()
Iterator<String> it = set.iterator() ;
while(it.hasNext()) {//判断,有元素就返回true
String s = it.next() ;//获取元素
System.out.println(s);
}
//方式2:foreach
for(String s : set) {
System.out.println(s);
}
}
}
HashSet
–1,概述
此类实现 Set 接口,由哈希表(实际上是一个 HashMap 实例)支持。它不保证 set 的 迭代顺序.
通过hashCode()计算出元素的存储位置,并将这些元素正确地分布在桶中。
对此 set 进行迭代所需的时间与HashSet 实例的大小(元素的数量)和底层 HashMap 实例(桶的数量)的“容量”的和成比例。因此,如果迭代性能很重要,则不要将初始容量设置得 太高(或将加载因子设置得太低).
–2,特点
–底层是哈希表/散列表
–元素无序
–元素不能重复
–元素没有下标
–3,创建对象
HashSet()
构造一个新的空 set,其底层 HashMap 实例的默认初始容量是 16,加载因子是 0.75。
–4,常用方法
–继承自Set接口的方法们~~
–5,测试
package cn.tedu.collection;
import java.util.HashSet;
//测试 HashSet
public class Test3_HashSet {
public static void main(String[] args) {
//TODO 1,创建对象--桶--性能:初始值+加载因子
//我们创建的是HashSet对象,但是底层实际上是创建了一个HashMap对象
HashSet<Double> set = new HashSet<>();
//TODO 2,常用方法
//我们是向HashSet中添加数据,但是底层实际上是向HashMap中添加的
set.add(1.1);
}
}
Map接口
–1,概述
将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。
Map 接口提供三种collection 视图,允许以键集、值集或键-值映射关系集的形式查看某 个映射的内容。映射顺序 定义为迭代器在映射的 collection 视图上返回其元素的顺 序。某些映射实现可明确保证其顺序,如 TreeMap 类;另一些映射实现则不保证顺 序,如 HashMap 类。
–2,特点
–存的数据是键值对的格式
–其中键不能重复
–每个键对应一个值
–HashMap是无序的,TreeMap是有序的
–3,创建对象
接口无法创建对象,只能创建实现类对象
–4,常用方法
void clear()
从此映射中移除所有映射关系(可选操作)。
boolean containsKey(Object key)
如果此映射包含指定键的映射关系,则返回 true。
boolean containsValue(Object value)
如果此映射将一个或多个键映射到指定值,则返回 true。
Set<Map.Entry<K,V>> entrySet()
返回此映射中包含的映射关系的 Set 视图。
boolean equals(Object o)
比较指定的对象与此映射是否相等。
V get(Object key)
返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。
int hashCode()
返回此映射的哈希码值。
boolean isEmpty()
如果此映射未包含键-值映射关系,则返回 true。
Set keySet()
返回此映射中包含的键的 Set 视图。
V put(K key, V value)
将指定的值与此映射中的指定键关联(可选操作)。
void putAll(Map<? extends K,? extends V> m)
从指定映射中将所有映射关系复制到此映射中(可选操作)。
V remove(Object key)
如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。
int size()
返回此映射中的键-值映射关系数。
Collection values()
返回此映射中包含的值的 Collection 视图。
–5,测试
package cn.tedu.collection;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
//测试Map接口
public class Test4_Map {
public static void main(String[] args) {
//1,创建对象
Map<Integer,String> map = new HashMap<>();
//TODO 刚刚new出来的map里元素有值吗?--有,都是默认值.null=null
//2,常用方法
map.put(9527, "唐伯虎");
map.put(9528, "如花");
map.put(9528, "兵哥哥");
map.put(9529, "钟南山");
map.put(9530, "袁隆平");
//map里的key是唯一的,不能重复,如果重复了,value会被覆盖.
//HashMap无序
System.out.println(map);
//{9527=唐伯虎, 9528=兵哥哥, 9529=钟南山, 9530=袁隆平}
// map.clear();//清空集合
System.out.println( map.containsKey(9527));//判断map中是否包含指定的key
System.out.println( map.containsValue("袁隆平"));//判断map中是否包含指定的value
System.out.println( map.equals(123) );判断map是否和指定元素相等
System.out.println( map.get(9529) );//根据key查找对应的value
System.out.println( map.hashCode() );//获取哈希值
System.out.println( map.isEmpty() );//判读map是否为空
System.out.println( map.remove(9528) );//根据key删除记录
System.out.println( map.size() );//获取集合的长度
Collection<String> c = map.values() ;//把map里的所有value放入Collection中
System.out.println(c);//[唐伯虎, 钟南山, 袁隆平]
//迭代map里的数据--把map转成set的方式
//方式1--把map里的key存入set--Set<K> keySet()
Set<Integer> set = map.keySet() ;
//遍历set,获取每一个key
for (Integer key : set) {
//根据key,回map里找value
String value = map.get(key);
System.out.println(key+","+value);
}
//方式2--把map里的整条记录key和value一起存入set--Set<Map.Entry<K,V>> entrySet()
Set<Entry<Integer,String>> set2 = map.entrySet() ;
//遍历set获取每个Entry
for (Entry<Integer, String> entry : set2) {
//获取Entry对象封装着的key和value
Integer key = entry.getKey() ;
String value = entry.getValue() ;
System.out.println(key+"===="+value);
}
}
}
HashMap实现类
–1,特点/原理
–为了提高查询效率,底层会维护一个数组,把数据存入数组中
–底层根据hashCode()计算得到存储位置/哈希值
–如果该位置没有存过数据,直接放在该位置,也就是放在了数组节点上
–如果该位置存过数据(hash冲突/hash碰撞),会形成链表结构
–把新的数据作为链表的头节点
–如果形成了链表结构,会大大降低查询效率
–jdk1.8优化了链表中多个节点的查询效率,如果链表上节点数>8,会形成红黑 树结构,如果树上的节点<6会再次变回成链表
–2,创建对象
HashMap()
构造一个具有默认初始容量 (16) 和默认加载因子 (0.75) 的空 HashMap。
–3,测试
package cn.tedu.collection;
import java.util.HashMap;
import java.util.Map.Entry;
//测试 HashMap
public class Test5_HashMap {
public static void main(String[] args) {
//TODO 1,创建对象
HashMap<String,String> map = new HashMap<>();
//TODO 2,常用方法
map.put("k1", "杨幂");
map.put("k2", "Angelababy");
map.put("k3", "刘沛霞");
System.out.println(map);
//遍历Map --> Set
//把map里的key放到set里`
for(String key : map.keySet()) {
String value = map.get(key);
System.out.println("key="+key+",,,value="+value);
}
//把map里的key和value封装成Entry放入set里
for(Entry<String,String> entry : map.entrySet() ){
String key = entry.getKey() ;
String value = entry.getValue();
System.out.println("key="+key+":::value="+value);
}
}
}
–4,练习
–需求:统计字符串中字符出现的次数,接收用户输入的一串字符串,统计出现的每个字符的个数
–代码:
package cn.tedu.collection;
import java.util.HashMap;
import java.util.Scanner;
//测试 map练习
public class Test6_HashMap {
public static void main(String[] args) {
//1,接收用户输入的一串字符串
String input = new Scanner(System.in).nextLine();
//3,统计字符出现的次数,最终的数据结果类似:{a=5,b=3,c=2}
HashMap<Character, Integer> map = new HashMap<>();
//2,遍历字符串(底层是char[],根据下标不能遍历)
for (int i = 0; i < input.length(); i++) {
//4,把结果存入map--key是字符
char key = input.charAt(i) ;//获取每个字符
//拿着key去map里找value,看看是默认值null还是以前就统计过
Integer value = map.get(key);
if(value==null) {//如果以前没统计过就直接存1
map.put(key, 1);
}else {//如果以前统计过现在直接+1
map.put(key, value+1);
}
}
System.out.println(map);
}
}
Collections工具类
–0,概述
提供了大量的针对collection 集合的静态方法
–1,常用方法
static boolean addAll(Collection<? super T> c, T… elements)
将所有指定元素添加到指定 collection 中。
static T max(Collection<? extends T> coll)
根据元素的自然顺序,返回给定 collection 的最大元素。
static T min(Collection<? extends T> coll)
根据元素的自然顺序 返回给定 collection 的最小元素。
static void reverse(List<?> list)
反转指定列表中元素的顺序。
static void sort(List list)
根据元素的自然顺序 对指定列表按升序进行排序。
static void swap(List<?> list, int i, int j)
在指定列表的指定位置处交换元素。
–2,测试
package cn.tedu.collections;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
//测试 集合工具类Collections
public class Test1_Collections {
public static void main(String[] args) {
//TODO 创建List集合,并添加元素
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(7);
list.add(9);
list.add(3);
System.out.println(list);//[1, 7, 9, 3]
//static <T> boolean addAll(Collection<? super T> c, T... elements)
Collections.addAll(list, 2,4,6,8);//向指定集合中,一次性添加多个数据
System.out.println(list);//[1, 7, 9, 3, 2, 4, 6, 8]
//static T max(Collection<? extends T> coll)
//获取list集合里的最大值
System.out.println( Collections.max(list) );
//static T min(Collection<? extends T> coll)
//获取list集合里的最小值
System.out.println( Collections.min(list) );
//static void reverse(List<?> list)
Collections.reverse(list);//指定的list集合中的数据进行反转
System.out.println(list);//[8, 6, 4, 2, 3, 9, 7, 1]
//static void sort(List<T> list)
Collections.sort(list);//指定的list集合中的数据进行排序
System.out.println(list);//[1, 2, 3, 4, 6, 7, 8, 9]
//static void swap(List<?> list, int i, int j)
Collections.swap(list, 1, 6);//把list中,指定下标的两个元素进行位置交换
System.out.println(list);//[1, 8, 3, 4, 6, 7, 2, 9]
}
}