Java的多线程一 Li.046

多线程增加效率 并行, 就是多个任务同时进行, 多核cpu同时执行 并发, 多个任务轮流进行, cpu一个一个的执行 证明 JVM 是多线程的 垃圾回收和main线程间隔执行 public class Demo1_Thread { public static void main(String[] args) { for(int i=0; i < 10000000 ;i++){ new Demo(); } for(int i=0; i < 10000 ; i++){ System.out.println("主线程"); } } } class Demo{ @Override protected void finalize() throws Throwable { System.out.println("垃圾被回收了"); } } 继承Thread 开启一个线程 实际run() 方法 start() 开启线程 public class Demo2_ExtendsThread { public static void main(String[] args) { MyThread mt = new MyThread(); // mt.run(); mt.start(); for (int i=0; i <10000 ; i++){ System.out.println(i+"bbbbbbbbbbbbb"); } } } class MyThread extends Thread{ @Override public void run() { for(int i=0; i < 10000 ;i++){ System.out.println(i+"aaaaaaaaaaaaaaa"); } } } 实际 Runnable 接口的类 实际Runnable类, 类作为参数传递给线程, start() 开启线程 public class Demo3_Runnable { public static void main(String[] args) { MyRunnable d = new MyRunnable(); Thread t = new Thread(d); t.start(); for(int i=0; i < 10000 ;i++){ System.out.println(i+"bbbbbbbbbbbbbbb"); } } } class MyRunnable implements Runnable{ @Override public void run() { for(int i=0; i < 10000 ;i++){ System.out.println(i+"aaa"); } } } 多线程的2种区别 继承 Thread: 由于子类重写了Thread类的run()方法, 当调用start()时, 直接找子类的run()方法 实际 Runnable: 构造函数中传入了Runnable的引用, 成员变量记住了它, start()调用run() 方法时内部判断成员变量Runnable的引用是否为空, 不为空看的Runnable的run(), 运行时是子类的run()方法. 继承Thread实现简单, 方便使用, 有父类则不能使用这种方法 有父类时可以实际Runnable 接口实现多线程, 对继承Thread的补充, 使用时必须获取线程对象, 使用复杂 匿名内类实现多线程的方法 public class Demo4_NoNameThread { public static void main(String[] args) { new Thread(){ @Override public void run() { for(int i=0; i<100000 ;i++){ System.out.println("aaaaaa"); } } }.start(); Thread t = new Thread(new Runnable() { @Override public void run() { for(int i=0;i<10000;i++){ System.out.println("bbbbbbbbbbbbbbbbbbb"); } } }); t.start(); } } 匿名内部类设置线程名字 public class Demo5_ThreadName { public static void main(String[] args) { // demo1(); Thread t = new Thread(){ @Override public void run() { // this.setName("小明"); System.out.println(this.getName()+"aaaaa"); } }; t.setName("李明"); t.start(); new Thread(){ @Override public void run() { this.setName("小明"); System.out.println(this.getName()+"aaaaa"); } }.start(); } private static void demo1() { new Thread("小明"){ @Override public void run() { System.out.println(this.getName()+ "aaaaa"); } }.start(); new Thread("小红"){ @Override public void run() { System.out.println(this.getName()+ "bbbbbb"); } }.start(); } } 也可调用setName更改名称 获取本类的引用Thread.currentThread() ...

September 10, 2021&nbsp;·&nbsp;6 分钟&nbsp;·&nbsp;Lizicai

Java的递归 Li.045

递归练习, 计算文件夹大小 import java.io.File; import java.util.Scanner; public class Demo1_FolderSize { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String strFolder = null; long size = 0; while (true){ if( sc.hasNext()){ strFolder = sc.nextLine(); break; } } if( strFolder.equals(null)){ System.out.println("不能为空"); } else { File folder = new File(strFolder); if(folder.isFile()){ size = folder.length(); } else if(folder.isDirectory()){ size = getSize(folder); } else if(! folder.exists()){ System.out.println("文件夹不存在"); } } System.out.println(size); } public static long getSize(File folder){ long len = 0; File [] files = folder.listFiles(); for(File subFile:files){ if(subFile.isFile()){ len = len + subFile.length(); } else{ len = len + getSize(subFile); } } return len; } } 递归删除文件夹 删除文件内的文件 删除文件夹本身 import java.io.File; import java.util.Scanner; public class Demo2_DeleteFolder { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String strFolder = null; strFolder = getDir(sc); if( strFolder.equals(null)){ System.out.println("不能为空"); } else { File folder = new File(strFolder); if(folder.isFile()){ folder.delete(); } else if(folder.isDirectory()){ deleteFolder(folder); } else if(! folder.exists()){ System.out.println("文件夹不存在"); } } } private static void deleteFolder(File folder) { File[] files = folder.listFiles(); for (File f : files){ if(f.isFile()){ f.delete(); } else if(f.isDirectory()){ deleteFolder(f); f.delete(); } } folder.delete(); } public static String getDir(Scanner sc) { String strFolder; while (true){ if( sc.hasNext()){ strFolder = sc.nextLine(); break; } } return strFolder; } } 复制文件到指定文件夹下 源文件夹, 目标文件夹 在目标文件夹中创建源文件夹 遍历源文件夹, 文件则调用stream 复制到目标文件夹/源文件夹, 文件夹则递归调用 import java.io.*; public class Demo3_MvFolder { public static void main(String[] args) throws IOException { File folderSrc = new File("test"); File folderDes = new File("des"); copyFile3(folderSrc, folderDes); } public static void copyFile3(File folderSrc, File folderDes) throws IOException { if(! folderDes.isDirectory()){ System.out.println("请复制到文件夹中"); return; } File newFolder = new File(folderDes, folderSrc.getName()); newFolder.mkdir(); for(File f : folderSrc.listFiles()){ if( f.isFile()){ fileStream(f.getAbsolutePath(), newFolder.getAbsolutePath()+"/"+f.getName()); } else{ copyFile3(f, newFolder); } } } public static void copyFile2(File folderSrc, File folderDes) throws IOException{ if(! folderDes.isDirectory()){ System.out.println("请复制到文件夹中"); return; } File tempFolder = new File(folderDes.getAbsolutePath()+"/"+folderSrc.getName()); if( folderSrc.isDirectory()){ tempFolder.mkdir(); } for( File f : folderSrc.listFiles()){ if( f.isFile()){ fileStream(f.getAbsolutePath(), tempFolder.getAbsolutePath()+"/"+f.getName()); } else { copyFile2(f, tempFolder); } } } public static void copyFile(File folderSrc, File folderDes) throws IOException { if(! folderDes.isDirectory()){ System.out.println("请复制到文件夹中"); return; } if( folderSrc.isDirectory()){ new File(folderDes.getAbsolutePath()+"/"+folderSrc).mkdir(); } for(File f: folderSrc.listFiles()){ if ( f.isFile()){ fileStream(f.getAbsolutePath(), (folderDes.getAbsolutePath()+"/"+f.getPath())); } else if( f.isDirectory()){ copyFile(f, folderDes); } } } public static void fileStream(String src, String desc) throws IOException{ FileInputStream fis = new FileInputStream(src); int len; byte[] arr = new byte[1024*100]; FileOutputStream fos = new FileOutputStream(desc); while ( (len = fis.read(arr)) != -1){ fos.write(arr,0,len); } fis.close(); fos.close(); } } 打印文件夹的内文件, 保持层级 import java.io.File; public class Demo4_PrintFolder { public static void main(String[] args) { File folder = new File("test"); int lev = 0; printFolder(folder, lev); } public static void printFolder(File folder , int lev){ System.out.println(folder.getPath()); for ( File f : folder.listFiles()){ for (int i=0;i<=lev;i++){ System.out.print("\t"); } if(f.isFile()){ System.out.println(f.getPath()); } else { // lev不能用lev++或++lev, 改变了lev值 printFolder(f, lev+1); } } } } 斐波那契数列 public class Demo5_TwoZi { public static void main(String[] args) { System.out.println(twoZi(6)); } public static int twoZi(int month){ int sum = 0; if(month > 2){ sum = twoZi(month-1) + twoZi(month-2); } else if(month == 2){ sum = 1; } else if(1 == month){ sum = 1; } return sum; } } 1000的阶乘, 其中所有0和尾部0的个数 import java.math.BigInteger; public class Demo6_1000JieChen { public static void main(String[] args) { BigInteger bi = new BigInteger("1"); for(int i=1;i<=1000;i++) { BigInteger tmepBi = new BigInteger(i + ""); bi = bi.multiply(tmepBi); } int sum = 0; String str = String.valueOf(bi); for(int i=0;i<str.length();i++){ if('0'== (str.charAt(i))){ sum++; } } int num = 0; for(int j=str.length()-1;j>=0;j--){ if( '0' == str.charAt(j)){ num++; } else { break; } } System.out.println(sum); System.out.println(num); } } 约瑟夫环 import java.util.ArrayList; import java.util.Iterator; public class Demo7_LuckYue { public static void main(String[] args) { int num = 8; System.out.println(getLuck(num)); System.out.println(getLuck2(num)); } public static int getLuck2(int num) { ArrayList<Integer> arrayList = new ArrayList<>(); for(int i=1;i<= num;i++){ arrayList.add(i); } int sum = 1; for(int i=0; arrayList.size()!=1;i++){ if( i == arrayList.size() ){ i = 0; } if(0 == sum % 3){ arrayList.remove(i--); } sum ++; } return arrayList.get(0); } public static int getLuck(int num){ ArrayList<Integer> arrayList = new ArrayList<>(); for(int i=1;i<= num;i++){ arrayList.add(i); } int sum = 0; while (arrayList.size() > 1){ Iterator<Integer> iterator = arrayList.iterator() ; while (iterator.hasNext()){ Integer i = iterator.next(); // next()和remove方法依赖关系 sum++; if(0 == sum % 3){ iterator.remove(); } } } return arrayList.get(0); } }

September 8, 2021&nbsp;·&nbsp;4 分钟&nbsp;·&nbsp;Lizicai

Java的IO其他流(及Properties) Li.044

序列流 SequenceInputStream 关闭时会关闭所有流 public class Demo1_Stream { public static void main(String[] args) throws IOException { FileInputStream fr1 = new FileInputStream("read1.md"); FileInputStream fr2 = new FileInputStream("read2.md"); SequenceInputStream sis = new SequenceInputStream(fr1,fr2); FileOutputStream fos = new FileOutputStream("read3.md"); int b ; while ( ( b = sis.read()) != -1){ fos.write(b); } sis.close(); fos.close(); } public static void demo1() throws IOException { FileInputStream fr1 = new FileInputStream("read1.md"); FileOutputStream fos = new FileOutputStream("read3.md"); int b; while ((b = fr1.read()) != -1) { fos.write(b); } fr1.close(); FileInputStream fr2 = new FileInputStream("read2.md"); while ((b = fr2.read()) != -1) { fos.write(b); } fr2.close(); fos.close(); } } IO 流整合多个 public class Demo1_Stream { public static void main(String[] args) throws IOException { Vector<FileInputStream> v = new Vector<>(); FileInputStream fr1 = new FileInputStream("read1.md"); FileInputStream fr2 = new FileInputStream("read2.md"); v.add(fr1); v.add(fr2); Enumeration<FileInputStream> en = v.elements(); SequenceInputStream sis = new SequenceInputStream(en); FileOutputStream fos = new FileOutputStream("read3.md"); int b ; while ( (b = sis.read()) != -1){ fos.write(b); } sis.close(); fos.close(); } } ByteArrayOutputStream 获取数据 ByteArrayOutputStream 的 toString 可直接转为默认或指定的字符 import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.IOException; public class Deom2_ByteArrayOutputStream { public static void main(String[] args) throws IOException { FileInputStream fi = new FileInputStream("read1.md"); ByteArrayOutputStream baos = new ByteArrayOutputStream(); int b ; while ( (b = fi.read()) != -1){ baos.write(b); } fi.close(); System.out.println(baos.toString()); System.out.println(baos.toString("utf-8")); } private static void Demo1() throws IOException { FileInputStream fi = new FileInputStream("read1.md"); byte[] arr = new byte[3]; int len; while ( ( len = fi.read(arr)) != -1){ System.out.println(new String(arr,0,len)); } fi.close(); } } 内存输出 import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.IOException; public class Demo3_Test { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("read1.md"); byte[] arr = new byte[5]; int len; ByteArrayOutputStream bos = new ByteArrayOutputStream(); while ( (len = fis.read(arr)) != -1){ bos.write(arr,0,len); } fis.close(); System.out.println(bos.toString()); bos.close(); } } 随机读和存 RandomAccessFile import java.io.IOException; import java.io.RandomAccessFile; public class Demo4_RandomAccessFile { public static void main(String[] args) throws IOException { // Demo1(); Demo2(); } public static void Demo2() throws IOException{ RandomAccessFile raf = new RandomAccessFile("random.txt","rw"); int b; while ( (b = raf.read()) != -1){ System.out.println(b); } raf.close(); } private static void Demo1() throws IOException { RandomAccessFile raf = new RandomAccessFile("random.txt","rw"); raf.write(97); raf.seek(10); raf.write(98); raf.close(); } } 对象操作流 ObjecOutputStream 输出对象流, 序列化 import com.lizicai.bean.Person; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; public class Demo5_ObjectOutputStream { public static void main(String[] args) throws IOException { Person p1 = new Person("小明", 23); Person p2 = new Person("小红", 23); ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream("person.txt")); oos.writeObject(p1); oos.writeObject(p2); oos.close(); } } 读取对象流 import com.lizicai.bean.Person; import java.io.*; public class Deom6_ObjectInputStream { public static void main(String[] args) throws IOException, ClassNotFoundException { ObjectInputStream oos = new ObjectInputStream(new FileInputStream("person.txt")); Person p1 = (Person) oos.readObject(); System.out.println(p1.getName()+p1.getAge()); Person p2 = (Person) oos.readObject(); System.out.println(p2.getName()+p2.getAge()); } } 对象操作优化 对象放入集合中, 集合输出到流 import com.lizicai.bean.Person; import java.io.*; import java.util.ArrayList; public class Demo7_OptimeObjectStream { public static void main(String[] args) throws IOException, ClassNotFoundException { ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("hashSetPerson.txt")); ArrayList<Person> arrayList = new ArrayList<>(); arrayList.add(new Person("小明",25)); arrayList.add(new Person("小红",23)); arrayList.add(new Person("小王",26)); oos.writeObject(arrayList); oos.close(); ObjectInputStream ois = new ObjectInputStream(new FileInputStream("hashSetPerson.txt")); ArrayList<Person> personArrayList = ( ArrayList<Person> ) ois.readObject(); for(Person p : personArrayList){ System.out.println(p.getName() + p.getAge()); } } } IO 流增加 id 号 更改Person属性时更改serialVersionUID 可以准备知道原来Persion和现在Persion属性区别 import java.io.Serializable; public class Person implements Serializable { private static final long serialVersionUID= 1L; private String name; private int age; public Person(){} public Person(String name, int age) { this.name = name; this.age = age; } public void setName(String name) { this.name = name; } public String getName() { return name; } public void setAge(int age) { this.age = age; } public int getAge() { return age; } } IO 基本数据流, DataInputStream DataOutputStream import java.io.*; public class Demo8_DataInputStream { public static void main(String[] args) throws IOException { Demo1(); DataOutputStream dos = new DataOutputStream(new FileOutputStream("outData.txt")); dos.writeInt(997); dos.writeInt(998); dos.writeInt(999); dos.close(); DataInputStream dis = new DataInputStream(new FileInputStream("outData.txt")); int x = dis.readInt(); int y = dis.readInt(); int z = dis.readInt(); System.out.println(x); System.out.println(y); System.out.println(z); dis.close(); } private static void Demo1() throws IOException { FileOutputStream fos = new FileOutputStream("output.txt"); fos.write(997); fos.close(); } private static void Demo2() throws IOException { FileInputStream fis = new FileInputStream("output.txt"); int b = fis.read(); fis.close(); } } 打印流的概述和特点 PrintStream 和 PrintWriter 分别是打印的字节流和字符流 只操作数据目的 自动刷出作用不大 import java.io.*; public class Demo9_PrintStream { public static void main(String[] args) throws IOException { // Demo2(); PrintWriter pw = new PrintWriter(new FileOutputStream("printWriter.txt"), true); pw.println(97); } private static void Demo2() throws FileNotFoundException { PrintWriter pw = new PrintWriter("printWriter.txt"); pw.println(97); pw.write(97); pw.flush(); pw.close(); } private static void demo1() { PrintStream p = System.out; p.println("Hello World!"); p.write(97); p.close(); } } 标准输入输出流概述和输出语句 标准输入只有1个, 未关联到文件, 不用关闭, 关闭后无法打开了 标准输出流未关联文件, 也不用关闭 import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; public class Demo10_SystemInOut { public static void main(String[] args) throws IOException { // demo1(); System.setIn(new FileInputStream("systemin.txt")); System.setOut(new PrintStream("systemout.txt")); InputStream is = System.in; PrintStream ps = System.out; int b; while ( ( b = is.read()) != -1){ ps.write(b); } is.close(); ps.close(); } private static void demo1() throws IOException { InputStream is = System.in; int x = is.read(); System.out.println(x); is.close(); InputStream is2 = System.in; int y = is2.read(); System.out.println(y); } } 练习, 复制文件, 增加使用数组, 增加复制速度 import java.io.*; public class Demo11_SystemInOutTest { public static void main(String[] args) throws IOException { System.setIn(new FileInputStream("systemin.txt")); System.setOut(new PrintStream("systemout.txt")); InputStream is = System.in; PrintStream ps = System.out; byte [] arr = new byte[1024]; int len; while ( ( len = is.read(arr)) != -1){ ps.write(arr,0,len); } is.close(); ps.close(); } } 2种键盘录入方式 import java.util.Scanner; public class Demo12_SystemIn { public static void main(String[] args) throws IOException { // demo1(); Scanner sc = new Scanner(System.in); String s = null; if(sc.hasNext()){ s = sc.nextLine(); } System.out.println(s); } private static void demo1() throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String line = br.readLine(); System.out.println(line); } } Properties的概述和作为Map集合的使用 Object setProperty(String key, String value) 添加键值对 Enumeration<?> propertyNames() 获取 key值枚举 String getProperty(String key) 根据key 值获取 value import java.util.Enumeration; import java.util.Properties; public class Demo13_Properties { public static void main(String[] args) { // demo1(); Properties pp = new Properties(); pp.setProperty("name", "小明"); pp.setProperty("tel", "12310001000"); System.out.println(pp); Enumeration <String> en = (Enumeration<String>) pp.propertyNames(); while ( en.hasMoreElements()){ String key = en.nextElement(); System.out.println(key+pp.getProperty(key)); } } private static void demo1() { Properties p = new Properties(); p.put("intA", 12); System.out.println(p); } } Properties 读和存 void load(InputStream inStream) throws IOException 读取文件 void store(OutputStream out, String comments) throws IOException 写到文件, comments 加入注释 import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.Enumeration; import java.util.Properties; public class Demo13_Properties { public static void main(String[] args) throws IOException { Properties pp = new Properties(); System.out.println(pp); pp.load(new FileInputStream("config.properties")); System.out.println(pp); pp.setProperty("qq","123"); System.out.println(pp); pp.store(new FileOutputStream("config.properties"), "utf-8"); } }

September 6, 2021&nbsp;·&nbsp;5 分钟&nbsp;·&nbsp;Lizicai

Java的Reader和Writer类 Li.043

FileReader 读取文件 import java.io.FileReader; import java.io.IOException; public class Demo1_FileReader { public static void main(String[] args) throws IOException { // Demo1(); FileReader fr = new FileReader("m.txt"); int b ; while ( (b = fr.read()) != -1){ System.out.println((char)b); } fr.close(); } private static void Demo1() throws IOException { FileReader fr = new FileReader("m.txt"); int x = fr.read(); System.out.println(x); System.out.println((char)x); } } FileWriter 字符写入文件 import java.io.FileWriter; import java.io.IOException; public class Demo2_FileWriter { public static void main(String[] args) throws IOException { FileWriter fw = new FileWriter("output.txt"); String s = "这只羊叫Leon"; fw.write(s); fw.flush(); fw.close(); } } 字符复制 import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class Demo3_ReaderWriter { public static void main(String[] args) throws IOException { FileReader fr = new FileReader("input.txt"); FileWriter fw = new FileWriter("output.txt"); int b ; while ( (b = fr.read()) != -1){ fw.write(b); } fr.close(); fw.close(); } } 什么情况使用使用字符流 字符流也能复制文件, 但不推荐, 字节->字符, 字符->字节 多一步转换 程序需要读取一段文本, 或都需要写入一段文本的时候可以使用字符流 读取的时候按字符读出, 不会出现半个中文 写出时可直接字符串写出, 不用转换为字节数组 图片类文件不能使用字符流复制, 丢失数据 自定义数组复制 import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class Demo4_ReaderWriter { public static void main(String[] args) throws IOException { FileReader fr = new FileReader("input.txt"); FileWriter fw = new FileWriter("output.txt"); char[] arr = new char[1024]; int len; while ( (len = fr.read(arr)) != -1){ fw.write(arr, 0 , len); } fr.close(); fw.close(); } } BufferedReader 和 BufferedWriter 读取写入字符 import java.io.*; public class Demo5_BufferedReader { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new FileReader("input.txt")); BufferedWriter bw = new BufferedWriter(new FileWriter("output.txt")); int b ; while ( (b=br.read()) != -1){ bw.write(b); } br.close(); bw.close(); } } BufferedReader readLine()方法, BufferedWriter 的newLine方法 newLine 没有放在write(line)后, 并写在循环内, 这样写多写一个空行 import java.io.*; public class Demo6_ReadLine { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new FileReader("input.txt")); BufferedWriter bw = new BufferedWriter(new FileWriter("output.txt")); String line ; if( (line = br.readLine() ) != null ){ bw.write(line); } while ( (line = br.readLine()) != null){ bw.newLine(); bw.write(line); } br.close(); bw.close(); } } 练习, 读取行, 并行数反向输出 流, 最好晚开早关 import java.io.*; import java.util.ArrayList; public class Demo7_ReverseLine { public static void main(String[] args) throws IOException { ArrayList<String> arrayList = new ArrayList<>(); String str ; BufferedReader br = new BufferedReader(new FileReader("input.txt")); while( ( str=br.readLine()) != null){ arrayList.add(str); } br.close(); BufferedWriter bw = new BufferedWriter(new FileWriter("output.txt")); for(int i= arrayList.size()-1;i>=0 ;i--){ bw.write(arrayList.get(i)); if( i == 0 ){ break; } bw.newLine(); } bw.close(); } } LineNumberReader import java.io.FileReader; import java.io.IOException; import java.io.LineNumberReader; public class Demo8_LineNumberReader { public static void main(String[] args) throws IOException { LineNumberReader lnr = new LineNumberReader(new FileReader("input.txt")); String line; lnr.setLineNumber(3); while ( (line = lnr.readLine()) != null){ System.out.println(lnr.getLineNumber() + " "+line); } lnr.close(); } } 装饰设计模式 使用被装饰的类, 对类中方法升级增加内容 好处 耦合性不强, 被装饰类的变化与装饰类的变化无关 public class Demo9_Wrap { public static void main(String[] args) { JiuCai j = new JiuCai(new Student()); j.code(); } } class Student { private String name; private int age; public void code(){ System.out.println("C"); System.out.println("Java"); } } interface Coder{ public void code(); } class JiuCai implements Coder{ JiuCai (Student stu){ this.stu = stu; } private Student stu; @Override public void code() { stu.code(); System.out.println("JavaEE"); System.out.println("SprintBoot"); } } 使用指定被码表读写字符 utf8格式写到gbk中, 乱码 ...

September 2, 2021&nbsp;·&nbsp;4 分钟&nbsp;·&nbsp;Lizicai

Java的IO流 Li.042

Java 的 IO 流 字节流, 字节流可以操作任何数据, 计算机中存储是字节流 InputStream OutputStream 字符流, 只能操作纯字符数据, 比较方便 Reader Writer 使用IO流要导入包, 使用时要进行异常处理, 使用后要释放资源 FileInputStream 读取一个文件 import java.io.FileInputStream; import java.io.IOException; public class Demo1_FileInputStream { public static void main(String[] args) throws IOException { FileInputStream fps = new FileInputStream("test.txt"); int x; while ((x = fps.read() ) != -1){ System.out.println(x); } fps.close(); } } read() 为什么接收的int类型 因为字节输入流可以操作任意类型的文件,比如图片音频等, 这些文件底层都是以二进制形式的存储的,如果每次读取都返回byte, 有可能在读到中间的时候遇到111111111,那么这11111111是byte类型的-1, 我们的程序是遇到-1就会停止不读了,后面的数据就读不到了,所以在读取的时候用int类型接收, 如果11111111会在其前面补上24个0凑足4个字节,那么byte类型的-1就变成int类型的255了这样可以保证整个数据读完, 而结束标记的-1就是int类型 字节输出流 write() void write(int b) throws IOException 在输出时int 去掉前3个byte字节, 写入第4个byte到文件中, 这个写是覆盖 import java.io.FileOutputStream; import java.io.IOException; public class Deom2_FileOutputStream { public static void main(String[] args) throws IOException { FileOutputStream fps = new FileOutputStream("test.txt"); fps.write(100); fps.write(101); fps.write(102); fps.close(); } } 字节输出流 追加 FileOutputStream(File file, boolean append) throws FileNotFoundException 输出字节流是否选择追加 import java.io.FileOutputStream; import java.io.IOException; public class Demo3_FileOutputStream { public static void main(String[] args) throws IOException { FileOutputStream fps = new FileOutputStream("test.txt", true); fps.write(100); fps.write(101); fps.close(); } } 复制文件 byte字节读取, byte复制 import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class Demo4_FileInOutStream { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("test.txt"); FileOutputStream fos = new FileOutputStream("copy.txt"); int b = 0; while ( (b = fis.read() )!= -1){ fos.write(b); } fis.close(); fos.close(); } } FileInputStream 的 available方法 int available() throws IOException 返回输入流的长度 import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class Demo5_FileInOutStream { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("test.txt"); FileOutputStream fos = new FileOutputStream("copy.txt"); int len = fis.available(); byte[] arr = new byte[fis.available()]; fis.read(arr); fos.write(arr); fis.close(); fos.close(); } } 通过数组 byte[] 读取写入 import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class Demo6_FileInOutStream { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("test.txt"); FileOutputStream fos = new FileOutputStream("copy.txt"); byte[] arr = new byte[1024 * 1024]; int b = 0; while ( (b =fis.read(arr)) != -1 ){ fos.write(arr,0,b); } fis.close(); fos.close(); } private static void errSimple() throws IOException { FileInputStream fis = new FileInputStream("test.txt"); FileOutputStream fos = new FileOutputStream("copy.txt"); byte[] arr = new byte[3]; int b = 0; while ( (b =fis.read(arr)) != -1 ){ fos.write(arr); } fis.close(); fos.close(); } } BufferedInputStream BufferedOutputStream 原码先读取1024*8个字节到内存, 复制给 BufferedOutputStream 1024*8 然后才写入文件 只需要关闭BufferedInputStream BufferedOutputStream 就能关闭所有流 import java.io.*; public class Demo7_BufferInputStream { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("test.txt"); FileOutputStream fos = new FileOutputStream("copy.txt"); BufferedInputStream bis = new BufferedInputStream(fis); BufferedOutputStream bos = new BufferedOutputStream(fos); int b ; while( ( b = bis.read() ) != -1){ bos.write(b); } // 只需关闭 BufferedInputStream BufferedOutputStream bis.close(); bos.close(); } } flush和close方法的区别 flush 刷新缓冲区, 缓冲区写到文件中, 刷完可以继续写. close 关闭前 就会刷新缓冲区 将缓冲区内容存到文件中 import java.io.*; public class Demo8_FlushClose { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("test.txt"); FileOutputStream fos = new FileOutputStream("copy.txt"); BufferedInputStream bis = new BufferedInputStream(fis); BufferedOutputStream bos = new BufferedOutputStream(fos); int b ; while ( (b = bis.read()) != -1 ){ bos.write(b); bos.flush(); } bis.close(); bos.close(); } } 字节流读取中文有乱码 UTF-8中英文1个字节, 中文3个字节, 按字节读取都会读出乱码 import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; public class Demo9_CharIO { public static void main(String[] args) throws IOException { // Demo1(); FileOutputStream fos = new FileOutputStream("chinese.txt"); fos.write("你好啊, 世界!".getBytes(StandardCharsets.UTF_8)); fos.write("\r".getBytes(StandardCharsets.UTF_8)); fos.close(); } private static void Demo1() throws IOException { FileInputStream fis = new FileInputStream("chinese.txt"); byte[] arr = new byte[3]; String s; int len ; while ( ( len=fis.read(arr) ) != -1){ System.out.println(new String(arr,0,len)); } } } 异常处理 流初始化null try 关闭流 能关闭一个就关闭一个 import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class Demo10_IOException { public static void main(String[] args) throws IOException{ FileInputStream fis = null; FileOutputStream fos = null; try { fis = new FileInputStream("test.txt"); fos = new FileOutputStream("copy.txt"); } finally { try{ if(null != fis){ fis.close(); } } finally { if(null != fos){ fos.close(); } } } } } 图片加密解密 加密把输出的字节异或一个数, 解密时再异或这个数 import java.io.*; public class Demo12_Encrypt { public static void main(String[] args) throws IOException { String src = "beauty.png"; String dest = "copy.png"; String dest2 = "copy1.png"; // extracted(src, dest); extracted(dest, dest2); } private static void extracted( String src, String dest) throws IOException { BufferedInputStream fis = new BufferedInputStream(new FileInputStream(src)); BufferedOutputStream fos = new BufferedOutputStream(new FileOutputStream(dest)); int b ; while ( (b = fis.read()) != -1){ fos.write(b ^ 123 ); } fis.close(); fos.close(); } } 输入文件复制到当前路径下 import java.io.*; import java.util.Scanner; public class Demo13_CopyFile { public static void main(String[] args) throws IOException { Scanner sc = new Scanner(System.in); String src = null; if(sc.hasNext()){ src = sc.nextLine(); } BufferedInputStream fis =null; int b ; BufferedOutputStream fos = null; if(src != null){ File file = new File(src); fis = new BufferedInputStream(new FileInputStream(src)); fos = new BufferedOutputStream(new FileOutputStream("./"+file.getName())); if( file.isFile()){ while ( (b = fis.read()) != -1){ fos.write(b); } } else if( file.isDirectory()){ System.out.println("文件夹无法复制"); } } fis.close(); fos.close(); } } 练习, 录入输入字符到文件中 import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.Scanner; public class Demo14_InputKey { public static void main(String[] args) throws IOException { Scanner sc = new Scanner(System.in); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("test.txt", true)); String input = null; while ( sc.hasNext()){ input = sc.nextLine(); if( "quit".equals(input)){ break; } else{ bos.write(input.getBytes(StandardCharsets.UTF_8)); bos.write("\n".getBytes(StandardCharsets.UTF_8)); } } bos.close(); } }

August 30, 2021&nbsp;·&nbsp;4 分钟&nbsp;·&nbsp;Lizicai

Java的File类 Li.041

File 相对路径文件或目录 绝对路径文件或目录 File(String pathname) 文件路径或目录 File(String parent, String child) 父文件路径, 和子文件名 File(File parent, String child) 父文件路径file, 和子文件名 import java.io.File; public class Demo1_File { public static void main(String[] args) { // Demo1(); // Demo2(); File parentFile = new File("/usr/local/etc/nginx/"); String child = "nginx.conf"; File file = new File(parentFile, child); } private static void Demo2() { String parent = "/usr/local/etc/nginx/"; String child = "nginx.conf"; File file = new File(parent,child); System.out.println(file.exists()); } // a.c 与 src 在同级目录下 private static void Demo1() { File file = new File("/usr/local/etc/nginx/nginx.conf"); System.out.println(file.exists()); File file2 = new File("a.c"); System.out.println(file2.exists()); } } File 的方法 boolean createNewFile() throws IOException 如果没有则创建true, 有则不创建false. boolean mkdir() 无则创建文件夹, 有则不创建false boolean mkdirs() 无则创建多级文件夹, 有则不创建false import java.io.File; import java.io.IOException; public class Demo2_FileMethod { public static void main(String[] args) throws IOException { File file = new File("aaa.c"); System.out.println(file.createNewFile()); File file2 = new File("test"); System.out.println(file2.mkdir()); File file3 = new File("test/aaa"); System.out.println(file3.mkdirs()); } } boolean renameTo(File dest) 就是mv命令 boolean delete() 删除文件或删除空文件夹, 文件夹内有文件或文件夹(空的也算)则删除不了 import java.io.File; import java.io.IOException; public class Demo3_FileMethod { public static void main(String[] args) throws IOException { File file1 = new File("aaa.c"); File file2 = new File("bbb.c"); System.out.println(file1.renameTo(file2)); System.out.println(file2.delete()); File file3 = new File("test/aaa"); System.out.println(file3.delete()); File file4 = new File("test/ccc"); System.out.println(file4.mkdirs()); file4.delete(); File file5 = new File( "test"); System.out.println(file5.delete()); } } boolean isDirectory() 判断是否文件夹 boolean isFile() 判断是否文件 boolean exists() 判断是否存在 boolean canRead() 判断是否可读权限 boolean canWrite() 判断是否可写权限 boolean isHidden() 判断是否隐藏 import java.io.File; import java.io.IOException; public class Demo4_FileMethod { public static void main(String[] args) throws IOException { File file1 = new File("test"); System.out.println(file1.isDirectory()); File file2 = new File("test.c"); System.out.println(file1.isFile()); System.out.println(file2.isFile()); File file3 = new File("aaa.c"); System.out.println(file3.exists()); System.out.println(file3.createNewFile()); System.out.println(file3.exists()); File file4 = new File("ccc.c"); System.out.println(file4.createNewFile()); System.out.println(file4.canRead()); File file5 = new File("ddd.c"); System.out.println(file5.createNewFile()); System.out.println(file5.canWrite()); File file6 = new File("root.c"); System.out.println(file6.setReadable(false)); System.out.println(file6.canRead()); System.out.println(file6.canWrite()); File file7 = new File("test.c"); System.out.println(file7.isHidden()); File file8 = new File(".idea"); System.out.println(file8.isHidden()); } } String getAbsolutePath() String getPath() String getName() long length() long lastModified() String[] list() File[] listFiles() import java.io.File; import java.text.SimpleDateFormat; import java.util.Date; public class Demo5_FileMethod { public static void main(String[] args) { File file = new File("aaa.c"); File file2 = new File("/Users/test/IdeaProjects/day19/"); System.out.println(file.getAbsoluteFile()); System.out.println(file2.getAbsoluteFile()); System.out.println(file.getPath()); System.out.println(file2.getPath()); System.out.println(file.getName()); System.out.println(file2.getName()); System.out.println(file.length()); System.out.println(file2.length()); System.out.println(file.lastModified()); System.out.println(file2.lastModified()); Date date = new Date(file.lastModified()); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println(simpleDateFormat.format(date)); String [] arr = file.list(); // for(String s: arr){ // System.out.println(s); // } String [] arr2 = file2.list(); for(String s: arr2){ System.out.println(s); } File[] list1 = file.listFiles(); // for(File f : list1){ // System.out.println(f); // } File[] list2 = file2.listFiles(); for(File f : list2){ System.out.println(f); } } } 练习 查找文件夹下所有的.c结尾的文件 遍历所有的文件, 碰到文件夹则进入遍历 文件名字正则匹配, 匹配输出 或使用String endsWith 匹配 import java.io.File; public class Demo6_FileTest { public static void main(String[] args) { File file = new File("/Users/test/workplace/test"); File file2 = new File("/Users/test/workplace/test"); File[] arrFile = file.listFiles(); File[] arrFile2 = file2.listFiles(); String regex = ".*[\\.][c]$"; String strEnd = ".c"; fileFind(arrFile, strEnd); fileFindRegex(arrFile2, regex); } public static void fileFind(File[] file, String strEnd){ for(File f : file){ if(f.isDirectory()){ fileFind(f.listFiles(), strEnd); } else{ if( f.getName().endsWith(strEnd) ){ System.out.println(f.getName()); } } } return ; } public static void fileFindRegex(File[] file, String regex){ for(File f : file){ if(f.isDirectory()){ fileFindRegex(f.listFiles(), regex); } else{ if( f.getName().matches(regex) ){ System.out.println(f.getName()); } } } return ; } } String[] list(FilenameFilter filter) 实现FilenameFilter 接口, 返回匹配的数组 原码 ...

August 29, 2021&nbsp;·&nbsp;3 分钟&nbsp;·&nbsp;Lizicai

Java的异常类 Li.040

Java 的异常类 异常的体系 Throwable Error Exception RuntimeException 如果程序没有处理异常, JVM 自行处理, 把异常的名称和信息, 打印在控制台上. 异常的2种处理方式 try catch finally try catch try catch finally try finally throws public class Demo1_Exception { public static void main(String[] args) { Demo1 demo1 = new Demo1(); int x; try{ x = demo1.div(10,0); } catch (ArithmeticException e){ System.out.println(e.getClass()); System.out.println("test"); }finally { System.out.println("最后执行了吗"); } } } class Demo1 { public int div (int a, int b){ return a/b; } } public class Demo2_Exception { public static void main(String[] args) { int a = 0; int b = 10; int[] arr = {1, 2, 3}; int x ; arr = null; try { // x = b / a; System.out.println(arr[10]); } catch (ArithmeticException e){ System.out.println(e.getClass()); } catch (IndexOutOfBoundsException e){ System.out.println(e.getClass()); } catch (Exception e){ System.out.println("有异常"); } } } public class Demo3_Exception { public static void main(String[] args) { try { System.out.println(10/0); } catch (ArithmeticException | IndexOutOfBoundsException e){ System.out.println("Exception"); } } } 异常throwable 的方法 String getMessage() 获取异常信息 String toString() 获取异常类和异常信息 void printStackTrace() 获取异常类和异常信息, 异常在程序出现的位置 public class Demo3_Exception { public static void main(String[] args) { try { System.out.println(10/0); } catch (ArithmeticException | IndexOutOfBoundsException e){ System.out.println(e.getMessage()); System.out.println(e.toString()); e.printStackTrace(); } } } 方法上的2种异常 RuntimeException 运行时异常, 不需要在方法向上抛出, 使用的时候也不需要在使用的方法上向上抛出 非RuntimeException 的异常, 必须在方法上向上抛出, 使用方法时也必须向上抛出异常 import lombok.Getter; import lombok.Setter; public class Person { public Person(){} public Person(String name, int age){ this.name = name; this.age = age; } @Getter @Setter private String name; @Getter private int age; public void setAge(int age) { if(age < 1 || age > 150){ throw new RuntimeException ("年龄非法"); } this.age = age; } } import lombok.Getter; import lombok.Setter; public class Person { public Person(){} public Person(String name, int age){ this.name = name; this.age = age; } @Getter @Setter private String name; @Getter private int age; public void setAge(int age) throws Exception{ if(age < 1 || age > 150){ throw new Exception ("年龄非法"); } this.age = age; } } public class Demo4_Exception { public static void main(String[] args) throws Exception{ Person p = new Person(); p.setAge(-12); System.out.println("MM"); } } throws 和 throw 区别 throws 用在方法声明后, 跟的是异常类名 跟以跟多个类名, 用逗号隔开 表示抛出异常, 由该方法的调用者处理 throw 用在方法内, 跟的是异常对象名 只能抛出一个异常对象名 表示抛出异常, 由方法体内的语句处理 finally finally 的特点 被finally 控制的语句一定会执行 特殊情况: 在执行finally 前 JVM 退出了(如System.exit(0)) finally 的作用 用于释放资源, 在IO 操作和数据库操作中会见到 return 的区别 return 执行后, 如果有finally 则执行finally 类 public class Demo5_Exception { public static void main(String[] args) { try { System.out.println(1/0); } catch (Exception e){ System.out.println("异常"); } finally { System.out.println("最后一定执行"); } } } final finally finalize 区别 final final 可以修饰类, 但不能被继承 修饰方法不能被重写 修饰变量只能赋值一次 finally try catch finally 体系中的一个语句, 不能单独使用 finalize 当垃圾回收器确定不存在该对象的更多引用时, 对象回收器则调用此方法 public class Demo6_Exception { public static void main(String[] args) { System.out.println(demo1()); } public static int demo1(){ int x = 10; try { x = 20; System.out.println(1/0); return x; } catch (Exception e){ x = 30; return x; } finally { x = 40; } } } x 会返回30, return 把x=30装箱返回回去 ...

August 27, 2021&nbsp;·&nbsp;4 分钟&nbsp;·&nbsp;Lizicai

Java的Map类 Li.039

Map 将键映射到值的对象 一个映射不能包含重复的键 每个键最多只能映射到一个值 Map 与 Collection 接口的不同 Map 是双列的, Collection 是单列的 Map 是键唯一, Collection 的子体系Set是唯一的 Map 集合的数据结构值针对键有效, 跟值无关; Collection集合的数据结构是针对元素有效 Map 方法 V put(K key, V value) 添加键和值, 成功返回null, 覆盖重复key值, 则返回被覆盖的Value值 V remove(Object key) 通过key删除元素, 删除成功则返回Value值 boolean containsKey(Object key) Map 中是否包含Key值 boolean containsValue(Object value) Map 中是否包含Value值 boolean isEmpty() Map 是否为空 clear() 清空Map import java.util.Collection; import java.util.HashMap; import java.util.Map; public class Demo1_Map { public static void main(String[] args) { // Demo1(); Map<String, Integer> hashMap = new HashMap<>(); hashMap.put("小明", 18); hashMap.put("小红", 19); hashMap.put("小王", 20); System.out.println(hashMap); Integer i = hashMap.remove("小王"); System.out.println(i); System.out.println(hashMap); System.out.println(hashMap.containsKey("小明")); System.out.println(hashMap.containsValue(19)); System.out.println(hashMap.isEmpty()); Collection<Integer> v = hashMap.values(); System.out.println(v); hashMap.clear(); System.out.println(hashMap.size()); } private static void Demo1() { Map<String,Integer> map = new HashMap<>(); Integer i1 = map.put("s1",12); Integer i2 = map.put("s2",22); Integer i3 = map.put("s3",33); Integer i4 = map.put("s3",34); Integer i5 = map.put("s5",35); Integer i6 = map.put("s6",35); System.out.println(map); System.out.println(i4); System.out.println(i5); System.out.println(i6); } } Map 根据键获取值 import java.util.HashMap; public class Demo2_Iterator { public static void main(String[] args) { HashMap<String, Integer> hashMap = new HashMap<>(); hashMap.put("a", 100); hashMap.put("b",90); hashMap.put("c",98); for(String s:hashMap.keySet()){ System.out.println(s + "="+ hashMap.get(s)); } } } Map 的键值对, 来获取Map中的Key 与 Value import java.util.HashMap; import java.util.Map; public class Demo3_Iterator { public static void main(String[] args) { HashMap<String, Integer> hashMap = new HashMap<>(); hashMap.put("a", 90); hashMap.put("b",95); hashMap.put("c",98); for(Map.Entry<String,Integer> single: hashMap.entrySet()){ System.out.println(single.getKey() + " "+ single.getValue()); } } } HashMap 存入Student类和String时, 重写 hashCode 和 equals方法 import lombok.Getter; import lombok.Setter; import java.util.Objects; public class Student { public Student(){} public Student(String name, int age){ this.name = name; this.age = age; } @Getter @Setter private String name; @Getter @Setter private int age; @Override public String toString() { return "Student "+this.name+this.age; } @Override public int hashCode() { return Objects.hash(name, age); } @Override public boolean equals(Object obj) { Student s = (Student) obj; return this.name == s.name && this.age == s.age; } } import com.lizicai.bean.Student; import java.util.HashMap; public class Demo4_HashMap { public static void main(String[] args) { HashMap<Student, String> hashMap = new HashMap<>(); hashMap.put(new Student("小明",23), "上海"); hashMap.put(new Student("小明",23), "北京"); hashMap.put(new Student("小王",26), "北京"); hashMap.put(new Student("莱昂纳多",28), "美国"); System.out.println(hashMap); } } LinkedHashMap import java.util.LinkedHashMap; public class Demo5_LinkedHashMap { public static void main(String[] args) { LinkedHashMap<String,Integer> linkedHashMap = new LinkedHashMap<>(); linkedHashMap.put("a", 20); linkedHashMap.put("b", 20); linkedHashMap.put("c", 20); System.out.println(linkedHashMap); } } TreeMap 必须实现 Comparable 接口, 2种方式 方式一在bean类中实现Comparable 接口 import lombok.Getter; import lombok.Setter; import java.util.Objects; public class Student implements Comparable<Student>{ public Student(){} public Student(String name, int age){ this.name = name; this.age = age; } @Getter @Setter private String name; @Getter @Setter private int age; @Override public String toString() { return "Student "+this.name+this.age; } @Override public int hashCode() { return Objects.hash(name, age); } @Override public boolean equals(Object obj) { Student s = (Student) obj; return this.name == s.name && this.age == s.age; } @Override public int compareTo(Student o) { int numName = this.name.compareTo(o.name); int numAge = numName == 0 ? this.age-o.age : numName; return numAge; } } public class Demo6_TreeMap { public static void main(String[] args) { // Demo1(); TreeMap<Student, String> treeMap = new TreeMap<>(); treeMap.put(new Student("ab",23), "上海"); treeMap.put(new Student("ab",23), "北京"); treeMap.put(new Student("ac",26), "北京"); treeMap.put(new Student("abc",28), "美国"); System.out.println(treeMap); } } 方式二, 在创建TreeMap时实现 Comparator 接口 public static void main(String[] args) { TreeMap<Student, String> treeMap = new TreeMap<>(new Comparator<Student>() { @Override public int compare(Student o1, Student o2) { int numName = o1.getName().compareTo(o2.getName()); int numAge = numName == 0 ? o1.getAge()-o2.getAge() : numName; return numAge; } }); treeMap.put(new Student("ab",23), "上海"); treeMap.put(new Student("ab",23), "北京"); treeMap.put(new Student("ac",26), "北京"); treeMap.put(new Student("abc",28), "美国"); System.out.println(treeMap); } 练习, 字符串 aaabbbccccfgkj 统计字母出现次数 字母在Map里Key 没有, 由存入key,1, 有则存key, value+1 import java.util.HashMap; import java.util.Map; public class Demo7_HashMap { public static void main(String[] args) { HashMap<Character, Integer> hashMap = new HashMap<>(); String str = "aaabbbbccccd"; char[] cArray = str.toCharArray(); for(char c : cArray){ if( ! hashMap.containsKey(c)){ hashMap.put(c,1); } else { hashMap.put(c, hashMap.get(c)+1); } } for(Map.Entry<Character,Integer> ci:hashMap.entrySet()){ System.out.println(ci.getKey() + "=" + ci.getValue() ); } } } 练习 HashMap 嵌套 HashMap import lombok.Getter; import lombok.Setter; import java.util.Objects; public class Student implements Comparable<Student>{ public Student(){} public Student(String name, int age){ this.name = name; this.age = age; } @Getter @Setter private String name; @Getter @Setter private int age; @Override public String toString() { return "Student "+this.name+this.age; } @Override public int hashCode() { return Objects.hash(name, age); } @Override public boolean equals(Object obj) { Student s = (Student) obj; return this.name == s.name && this.age == s.age; } import com.lizicai.bean.Student; import java.util.HashMap; import java.util.Map; public class Demo8_HashMapHashMap { public static void main(String[] args) { HashMap<Student, String> hashMap1 = new HashMap<>(); hashMap1.put(new Student("小明",23), "上海"); hashMap1.put(new Student("小王",26), "北京"); hashMap1.put(new Student("莱昂纳多",28), "美国"); HashMap<Student, String> hashMap2 = new HashMap<>(); hashMap2.put(new Student("小明",23), "上海"); hashMap2.put(new Student("小王",26), "北京"); hashMap2.put(new Student("莱昂纳多",29), "美国"); HashMap<HashMap<Student,String>,String > hashMap = new HashMap<>(); hashMap.put(hashMap1,"班级1"); hashMap.put(hashMap2,"班级2"); for(Map.Entry<HashMap<Student,String>, String> HH : hashMap.entrySet()){ for(Map.Entry<Student,String> HHS : HH.getKey().entrySet()){ System.out.println(HHS.getKey() + HHS.getValue()+HH.getValue()); } } System.out.println(hashMap); } } HashMap 和 Hashtable 区别 共同点 都是双链集合 区别 HashMap 是线程不安全的, 效率高JDK 1.2 版本 Hashtable 是线程安全的, 效率低, JDK 1.0 版本 HashMap 可以存储null 键 和 null 值 Hashtable 不可以存储null 键 及 null 值 import java.util.HashMap; import java.util.Hashtable; public class Demo9_HashMapHashtable { public static void main(String[] args) { HashMap<String, Integer> hashMap = new HashMap<>(); hashMap.put(null, 10); hashMap.put("a", null); System.out.println(hashMap); Hashtable<String, Integer> hashtable = new Hashtable<>(); hashtable.put(null, 10); hashtable.put("a", null); System.out.println(hashtable); } } Collections 中的方法 static <T extends Comparable<? super T» void sort(List list) 排序 static int binarySearch(List<? extends Comparable<? super T» list, T key) 二分查找 static <T extends Object & Comparable<? super T» T max(Collection<? extends T> coll) 返回最大值 static void reverse(List<?> list) 反转列表 static void shuffle(List<?> list) list 序列洗牌 private static void Demo5() { ArrayList<String> arrayList = new ArrayList<>(); arrayList.add("d"); arrayList.add("a"); arrayList.add("a"); arrayList.add("b"); arrayList.add("c"); arrayList.add("f"); System.out.println(arrayList); Collections.shuffle(arrayList); System.out.println(arrayList); } private static void Demo4() { ArrayList<String> arrayList = new ArrayList<>(); arrayList.add("d"); arrayList.add("a"); arrayList.add("a"); arrayList.add("b"); arrayList.add("c"); arrayList.add("f"); System.out.println(arrayList); Collections.reverse(arrayList); System.out.println(arrayList); } private static void Demo3() { ArrayList<String> arrayList = new ArrayList<>(); arrayList.add("d"); arrayList.add("a"); arrayList.add("a"); arrayList.add("b"); arrayList.add("c"); arrayList.add("f"); String max = Collections.max(arrayList); System.out.println(max); } private static void Demo2() { ArrayList<String> arrayList = new ArrayList<>(); arrayList.add("d"); arrayList.add("a"); arrayList.add("a"); arrayList.add("b"); arrayList.add("c"); arrayList.add("a"); Collections.sort(arrayList); System.out.println(arrayList); int index = Collections.binarySearch(arrayList, "b"); System.out.println(index); System.out.println(Collections.binarySearch(arrayList,"o")); } private static void Demo1() { ArrayList<String> arrayList = new ArrayList<>(); arrayList.add("d"); arrayList.add("a"); arrayList.add("a"); arrayList.add("b"); arrayList.add("c"); arrayList.add("a"); System.out.println(arrayList); Collections.sort(arrayList); System.out.println(arrayList); } 练习, 54 张牌, 每人17张, 剩下3张, 打印每个人牌和底牌 import java.util.ArrayList; import java.util.Collections; import java.util.Scanner; public class Demo2_Collections { public static void main(String[] args) { String[] nu = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"}; String[] color = { "♠️", "♥️", "♦️", "♣️"}; ArrayList<String> arrayList = new ArrayList<>(); for(String nuStr : nu){ for(String colorStr : color){ arrayList.add(nuStr + colorStr); } } arrayList.add("Big King"); arrayList.add("Small King"); for(int i=0;i<3;i++){ Collections.shuffle(arrayList); } System.out.println(arrayList); ArrayList<String> list1 = new ArrayList<>(); ArrayList<String> list2 = new ArrayList<>(); ArrayList<String> list3 = new ArrayList<>(); ArrayList<String> list4 = new ArrayList<>(); Scanner sc = new Scanner(System.in); for(int i=0;i<53;i++){ if(i >= 50 ){ list4.add(arrayList.get(i)); } else if( i % 3 == 0){ list1.add(arrayList.get(i)); } else if( i % 3 == 1) { list2.add(arrayList.get(i)); } else if( i % 3 ==2 ){ list3.add(arrayList.get(i)); } } System.out.println(list4); System.out.println(list1); System.out.println(list2); System.out.println(list3); } } 练习使用 HashMap 模拟一副牌 用HashMap 的 Key 生成arraylist来洗牌 import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.TreeMap; public class Demo3_Collections { public static void main(String[] args) { HashMap<Integer, String> poker = new HashMap<>(); String[] nu = { "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A","2"}; String[] color = { "♠️", "♥️", "♦️", "♣️"}; int count = 0; ArrayList<Integer> pokerIndex = new ArrayList<>(); for(String nuStr : nu){ for(String colorStr : color){ poker.put(count, (colorStr + nuStr)); pokerIndex.add(count); count++; } } poker.put(count, "Small King"); pokerIndex.add(count); count++; poker.put(count, "Big King"); pokerIndex.add(count); TreeMap<Integer, String> gaojin = new TreeMap<>(); TreeMap<Integer, String> jp = new TreeMap<>(); TreeMap<Integer, String> tiger = new TreeMap<>(); TreeMap<Integer, String> dipai = new TreeMap<>(); System.out.println(pokerIndex.size()); Collections.shuffle(pokerIndex); System.out.println(pokerIndex); for(int i=0;i< pokerIndex.size(); i++){ int index = pokerIndex.get(i); if(i > 50){ dipai.put( index , poker.get( index)); } else if ( i % 3 == 0){ gaojin.put( index, poker.get(index )); } else if (i % 3 == 1){ jp.put( index , poker.get( index )); } else if (i % 3 == 2){ tiger.put( index, poker.get( index )); } } System.out.println(gaojin); System.out.println(jp); System.out.println(tiger); System.out.println(dipai); } } ? Super E 情况 TreeSet TreeMap 会调用 import lombok.Getter; import lombok.Setter; import java.util.Objects; public class Student implements Comparable<Student>{ public Student(){} public Student(String name, int age){ this.name = name; this.age = age; } @Getter @Setter private String name; @Getter @Setter private int age; @Override public String toString() { return "Student "+this.name+this.age; } @Override public int hashCode() { return Objects.hash(name, age); } @Override public boolean equals(Object obj) { Student s = (Student) obj; return this.name == s.name && this.age == s.age; } @Override public int compareTo(Student o) { int numName = this.name.compareTo(o.name); int numAge = numName == 0 ? this.age-o.age : numName; return numAge; } } public class BaseStudent extends Student{ public BaseStudent(){} public BaseStudent(String name, int age){ super(name, age); } } import com.lizicai.bean.BaseStudent; import com.lizicai.bean.Student; import java.util.ArrayList; import java.util.Comparator; import java.util.TreeSet; public class Demo4_Generic { public static void main(String[] args) { // Demo1(); TreeSet<Student> treeSet = new TreeSet<>(new CompareByAge()); treeSet.add(new Student("小明",22)); treeSet.add(new Student("小红",22)); treeSet.add(new Student("小王",22)); System.out.println(treeSet); TreeSet<BaseStudent> treeSet2 = new TreeSet<>(new CompareByAge()); treeSet2.add(new BaseStudent("小明",22)); treeSet2.add(new BaseStudent("小红",22)); treeSet2.add(new BaseStudent("小王",22)); System.out.println(treeSet2); } private static void Demo1() { ArrayList<Student> arrayList = new ArrayList<>(); arrayList.add(new Student("小明",22)); arrayList.add(new Student("小红",22)); arrayList.add(new Student("小王",22)); ArrayList<BaseStudent> arrayList2 = new ArrayList<>(); arrayList2.add(new BaseStudent("小明",22)); arrayList2.add(new BaseStudent("小红",22)); arrayList2.add(new BaseStudent("小王",22)); arrayList.addAll(arrayList2); System.out.println(arrayList); } } class CompareByAge implements Comparator<Student> { @Override public int compare(Student o1, Student o2) { int num = o1.getAge() - o2.getAge(); int numName = num == 0 ? o1.getName().compareTo(o2.getName()): num; return numName; } } Collection List 存取有序, 有索引, 可重复 ArrayList 底层数组实现的, 线程不安全, 查找修改快, 增删慢 LinkedList 底层是链表实现的, 线程不安全, 查找慢, 增删快 Vetor 底层数组实现的, 线程安全, 查找修改增删都慢 如果查找修改多用ArrayList, 增和删多用LinkedList, 如果都多用ArrayList ...

August 24, 2021&nbsp;·&nbsp;8 分钟&nbsp;·&nbsp;Lizicai