• Java_基础知识回顾


    1、ByteArrayInputStream、 ByteArrayOutputStream 

    1. String str = "ZHANGSAN"; 
    2.       //System.out.println(str.toLowerCase()); 
    3.       ByteArrayInputStream inputStream = new ByteArrayInputStream(str.getBytes()); 
    4.       ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 
    5.       int b; 
    6.       while((b = inputStream.read()) != -1){ 
    7.           char lowerCase = Character.toLowerCase((char)b); 
    8.           outputStream.write(lowerCase); 
    9.       } 
    10.       byte[] lowerCases = outputStream.toByteArray(); 
    11.       System.out.println(new String(lowerCases,0, lowerCases.length)); 

    全部在内存中完成byte的转换

    2、PrintStream:向目标打印

    属于OutputStream的实现类,向目标(可能是文件、标准输出屏幕、输出流、网络等)打印各种样式,不过比一般的输出提供了更多的打印方式,可以打印各种数据类型和样式等

    1. OutputStream outputStream = System.out; 
    2.         outputStream.write("helloABC张三".getBytes()); 
    3.         outputStream.close(); 

    列出当前操作系统的系统参数,输出到文件中

    1. PrintStream printStream = new PrintStream("hello.txt"); 
    2.       System.getProperties().list(printStream); 
    3.       printStream.close(); 

    3、InputStreamReader、OutputStreamWriter, 计算机存储都是字节流的形式,而读取到内存中需要识别一个个的字符(人只能识别字符),有可能1个字节就代表一个字符(例如英文),也有可能多个字节才能转换成一个字符(例如中文),如果中间存在丢失或无法转换,则看到的就是一堆?

    InputStreamReader:将输入的内容字节变成字符

    OutputStreamWriter:将输出的内容从字符变成字节

    4、合并流:SequenceInputStream 

    1. File file1 = new File("hello.txt"); 
    2.    File file2 = new File("test.txt"); 
    3.  
    4.    InputStream inputStream1 = new FileInputStream(file1); 
    5.    InputStream inputStream2 = new FileInputStream(file2); 
    6.     
    7.    SequenceInputStream sequenceInputStream = new SequenceInputStream(inputStream1, 
    8.            inputStream2); 
    9.    BufferedInputStream bufferedInputStream = new BufferedInputStream(sequenceInputStream); 
    10.     
    11.    int c; 
    12.    while((c = bufferedInputStream.read()) != -1){ 
    13.        System.out.print((char)c); 
    14.    } 
    15.    bufferedInputStream.close(); 
    16.    sequenceInputStream.close(); 
    17.    inputStream1.close(); 
    18.    inputStream2.close(); 
    19.     

    测试结果:helloworld 

    在实验中,从bufferedInputStream去取到两个文件大小相加的byte数组中,代码如下,转换出来有问题,有点奇怪,只读到了前一个流中的内容,后面一个流中的内容没读取进来。思考中...

    1. File file1 = new File("hello.txt"); 
    2.     File file2 = new File("test.txt"); 
    3.  
    4.     InputStream inputStream1 = new FileInputStream(file1); 
    5.     InputStream inputStream2 = new FileInputStream(file2); 
    6.      
    7.     SequenceInputStream sequenceInputStream = new SequenceInputStream(inputStream1, 
    8.             inputStream2); 
    9.     BufferedInputStream bufferedInputStream = new BufferedInputStream(sequenceInputStream); 
    10.      
    11.     int length = (int) (file1.length() + file2.length()); 
    12.     byte[] b = new byte[length]; 
    13.     bufferedInputStream.read(b, 0, length); 
    14.     System.out.println(new String(b,0,length)); 
    15.      
    16.     bufferedInputStream.close(); 
    17.     sequenceInputStream.close(); 
    18.     inputStream1.close(); 
    19.     inputStream2.close(); 

     测试结果如下:hello

    5、Zip压缩与解压

    压缩程序:

    1. ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream("hello.zip")); 
    2.        zipOutputStream.setLevel(9); 
    3.         
    4.        ZipEntry zipEntry = new ZipEntry("a.txt"); 
    5.        zipOutputStream.putNextEntry(zipEntry); 
    6.         
    7.        BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("test.txt")); 
    8.        int content; 
    9.        while((content = bufferedInputStream.read()) != -1){ 
    10.            zipOutputStream.write(content); 
    11.        } 
    12.        bufferedInputStream.close(); 
    13.        zipOutputStream.closeEntry(); 
    14.        zipOutputStream.flush(); 
    15.        zipOutputStream.close(); 

     解压程序:

    1. ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream("hello.zip")); 
    2.    ZipEntry zipEntry = null; 
    3.    while ((zipEntry = zipInputStream.getNextEntry()) != null) { 
    4.        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream( 
    5.                new FileOutputStream(zipEntry.getName())); 
    6.        int content = 0; 
    7.        while((content = zipInputStream.read()) != -1){ 
    8.            bufferedOutputStream.write(content); 
    9.        } 
    10.        bufferedOutputStream.flush(); 
    11.        bufferedOutputStream.close(); 
    12.    } 
    13.    zipInputStream.close(); 

    6、zip压缩某目录下的所有文件及子文件

    1. public void zipDirectory(File pathname, ZipOutputStream zipOutputStream) throws Exception { 
    2.     if (!pathname.isDirectory()) { 
    3.         return; 
    4.     } 
    5.     File[] files = pathname.listFiles(); 
    6.     for (File file : files) { 
    7.         if (file.isDirectory()) { 
    8.             zipDirectory(file, zipOutputStream); 
    9.         } else { 
    10.             ZipEntry zipEntry = new ZipEntry(pathname.getName() + File.separator 
    11.                     + file.getName()); 
    12.             zipOutputStream.putNextEntry(zipEntry); 
    13.  
    14.             BufferedInputStream bufferedInputStream = new BufferedInputStream( 
    15.                     new FileInputStream(file)); 
    16.  
    17.             int i; 
    18.             while ((i = bufferedInputStream.read()) != -1) { 
    19.                 zipOutputStream.write(i); 
    20.             } 
    21.  
    22.             bufferedInputStream.close(); 
    23.             zipOutputStream.flush(); 
    24.             zipOutputStream.closeEntry(); 
    25.         } 
    26.     } 
    27.  

     问题:中文编码存在问题,建议选用import org.apache.tools.zip.ZipEntry;

    import org.apache.tools.zip.ZipOutputStream,由于其存在方法out.setEncoding("gbk");//指定编码为gbk

    6、ThreadLocal

    1. final ThreadLocal<String> threadLocal = new ThreadLocal<String>(); 
    2.       threadLocal.set("main--"); 
    3.  
    4.       Thread thread = new Thread() { 
    5.           @Override 
    6.           public void run() { 
    7.               threadLocal.set("thread--"); 
    8.               Thread.yield(); 
    9.               System.out.println(Thread.currentThread().getName() + ":" + threadLocal.get()); 
    10.           } 
    11.  
    12.       }; 
    13.       thread.start(); 
    14.       Thread.yield(); 
    15.       System.out.println(Thread.currentThread().getName() + ":" + threadLocal.get()); 

    7、数组和List之间的转换

    数组->List: Arrays.asList(a)

    List->数组:list.toArray()

    8、正则表达式

    (1)^:在[]内表示取反,在外面表示开头

    (2)group

    1. String regex = "[a-z]{3,5}"; 
    2.         Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE); 
    3.         Matcher matcher = pattern.matcher("Abc_defgh_aa_ABCD1"); 
    4.         while (matcher.find()) { 
    5.             System.out.print("位置[左闭右开区间):"+matcher.start() + "_" + matcher.end() + ", 匹配内容:"); 
    6.             System.out.println(matcher.group()); 
    7.         } 

    测试结果:

    1. 位置[左闭右开区间):0_3, 匹配内容:Abc 
    2. 位置[左闭右开区间):4_9, 匹配内容:defgh 
    3. 位置[左闭右开区间):13_17, 匹配内容:ABCD 

    (3)邮件的正则表达式

    [\w[_.]]+@[\w[_.]]+\.[\w]+

    (4)"."点号在正则表达式中表示任何字符, 需要表示点号的时候必须转义\.

    (5)group的分组

    分组是以正则表达式中的小括号'()'为标准的,当匹配成功后,group或group(0)表示匹配的整个字符串,group(1)代表正则中第一个小括号匹配到的内容,group(2)代表第二个小括号代表的内容,依次类推

    (6)匹配require引入文件

    "^[\s]*#require[\s]*\("([\w./]+)"\)[\s]*$"含义为:以任意空白字符开头,在#require,再任意空白字符,再(",再任意字母、点号、斜线, 再"),最后任意个空白字符结尾

    测试代码:

    1. public static void main(String[] args) { 
    2.      FileInputStream fileInputStream = null; 
    3.      try { 
    4.          fileInputStream = new FileInputStream(new File( 
    5.                  "C:/Documents and Settings/***/My Documents/tmp/hello.js")); 
    6.      } catch (FileNotFoundException e) { 
    7.          e.printStackTrace(); 
    8.      } 
    9.  
    10.      InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, 
    11.              Charset.defaultCharset()); 
    12.  
    13.      BufferedReader bufferedReader = new BufferedReader(inputStreamReader); 
    14.      String line = ""; 
    15.      try { 
    16.          while ((line = bufferedReader.readLine()) != null) { 
    17.              String requireFile = getRequireFile(line); 
    18.              System.out.println(requireFile); 
    19.          } 
    20.      } catch (IOException e) { 
    21.          e.printStackTrace(); 
    22.      } finally { 
    23.          try { 
    24.              bufferedReader.close(); 
    25.              inputStreamReader.close(); 
    26.              fileInputStream.close(); 
    27.          } catch (IOException e) { 
    28.              e.printStackTrace(); 
    29.          } 
    30.      } 
    31.  
    32.  } 
    33.  
    34.  private static String getRequireFile(String line) { 
    35.      String requireFile = ""; 
    36.      Pattern pattern = Pattern 
    37.              .compile("^[\s]*#require[\s]*\("([\w./]+)"\)[\s]*$", Pattern.MULTILINE); 
    38.      Matcher matcher = pattern.matcher(line); 
    39.      while (matcher.find()) { 
    40.          requireFile = matcher.group(1); 
    41.      } 
    42.      return requireFile; 
    43.  } 

    测试文件内容:

    1. var param; 
    2. #require("hello/world_util/alibaba123_utils.js") 
    3.     #require("/abc/world_util/alibaba12666_utils.js") 

    测试结果

    1. hello/world_util/alibaba123_utils.js 
    2. /abc/world_util/alibaba12666_utils.js 

    9、FileReader有待完备的地方,只能使用系统默认的字符集,而没有提供传递字符集的构造函数

    FileReader继承了InputStreamReader,但并没有实现父类中带字符集参数的构造函数,所以
    FileReader只能按系统默认的字符集来解码

    10、阻塞队列:BlockingQueue 

    生产者中的 put() 操作会在没有空间可用时阻塞,而消费者的 take() 操作会在队列中没有任何东西时阻塞。

    11、信号量:Semaphore, 允许规定数量的线程进入操作,释放之后其他进入执行

    1. Runnable limitedCall = new Runnable() { 
    2.         final Random    rand      = new Random(); 
    3.         final Semaphore available = new Semaphore(3); 
    4.         int             count     = 0; 
    5.  
    6.         public void run() { 
    7.             int time = rand.nextInt(15); 
    8.             int num = count++; 
    9.  
    10.             try { 
    11.                 available.acquire(); 
    12.  
    13.                 System.out.println("Executing " + "long-running action for " + time 
    14.                         + " seconds... #" + num); 
    15.  
    16.                 Thread.sleep(time * 1000); 
    17.  
    18.                 System.out.println("Done with #" + num + "!"); 
    19.  
    20.                 available.release(); 
    21.             } catch (InterruptedException intEx) { 
    22.                 intEx.printStackTrace(); 
    23.             } 
    24.         } 
    25.     }; 
    26.  
    27.     for (int i = 0; i < 10; i++) 
    28.         new Thread(limitedCall).start(); 

     12、死锁

    1. public class Demo06 { 
    2.     public static void main(String[] args) { 
    3.         DeadLock deadLock1 = new DeadLock(); 
    4.         DeadLock deadLock2 = new DeadLock(); 
    5.         deadLock1.setFlag(true); 
    6.         deadLock2.setFlag(false); 
    7.  
    8.         new Thread(deadLock1).start(); 
    9.         new Thread(deadLock2).start(); 
    10.     } 
    11.  
    12. class DeadLock implements Runnable { 
    13.     private boolean flag = false; 
    14.  
    15.     public boolean isFlag() { 
    16.         return flag; 
    17.     } 
    18.  
    19.     public void setFlag(boolean flag) { 
    20.         this.flag = flag; 
    21.     } 
    22.  
    23.     private static Object object1 = new Object(); 
    24.     private static Object object2 = new Object(); 
    25.  
    26.     public void run() { 
    27.         if (flag) { 
    28.             synchronized (object1) { 
    29.                 System.out.println(Thread.currentThread().getName() + " get object1."); 
    30.                 try { 
    31.                     Thread.sleep(1000); 
    32.                 } catch (InterruptedException e) { 
    33.                     e.printStackTrace(); 
    34.                 } 
    35.                 synchronized (object2) { 
    36.                     System.out.println(Thread.currentThread().getName() + " get object2."); 
    37.  
    38.                 } 
    39.             } 
    40.  
    41.         } else { 
    42.             synchronized (object2) { 
    43.                 System.out.println(Thread.currentThread().getName() + " get object2."); 
    44.                 try { 
    45.                     Thread.sleep(1000); 
    46.                 } catch (InterruptedException e) { 
    47.                     e.printStackTrace(); 
    48.                 } 
    49.                 synchronized (object1) { 
    50.                     System.out.println(Thread.currentThread().getName() + " get object1."); 
    51.  
    52.                 } 
    53.             } 
    54.  
    55.         } 
    56.     } 
    57.  

    13、反射:通过classloader加载类,标准做法如下:

    1. ClassLoader cl = Thread.currentThread().getContextClassLoader();  
    2. if (cl == null) cl = MyClass.class.getClassLoader(); // fallback  
    3. Class clazz = cl.loadClass(name);  

    14、文件大小限制

    错误做法:

    1. public int getFileSize(File f) {  
    2.   long l = f.length();  
    3.   return (int) l;  
    4. }  

    正确做法如下:

    不支持传递超过2GB的文件. 最好的做法是对长度进行检查, 溢出时抛出异常

    1. public int getFileSize(File f) {  
    2.   long l = f.length();  
    3.   if (l > Integer.MAX_VALUE) throw new IllegalStateException("int overflow");  
    4.   return (int) l;  
    5. }  

     15、线程sleep中断

    1. try {  
    2.         Thread.sleep(1000);  
    3. catch (InterruptedException e) {  
    4.         Thread.currentThread().interrupt();  
    5. }  
    6. or   
    7. while (true) {  
    8.         if (Thread.currentThread().isInterrupted()) break;  
    9. }  

    16、开发中常用术语解释

    java的几种对象(PO,VO,DAO,BO,POJO)解释  
       一、PO:persistant object 持久对象,可以看成是与数据库中的表相映射的java对象。最简单的PO就是对应数据库中某个表中的一条记录,多个记录可以用PO的集合。PO中应该不包含任何对数据库的操作。

       二、VO:value object值对象。通常用于业务层之间的数据传递,和PO一样也是仅仅包含数据而已。但应是抽象出的业务对象,可以和表对应,也可以不,这根据业务的需要.个人觉得同DTO(数据传输对象),在web上传递。 

       三、DAO:data access object 数据访问对象,此对象用于访问数据库。通常和PO结合使用,DAO中包含了各种数据库的操作方法。通过它的方法,结合PO对数据库进行相关的操作。 

       四、BO:business object 业务对象,封装业务逻辑的java对象,通过调用DAO方法,结合PO,VO进行业务操作。 

       五、POJO:plain ordinary java object 简单无规则java对象,我个人觉得它和其他不是一个层面上的东西,VO和PO应该都属于它。 

    17、多线售票系统:

    1. class TicketSeller implements Runnable { 
    2.     private int ticketCount = 10; 
    3.     @Override 
    4.     public void run() { 
    5.         while (ticketCount > 0) { 
    6.             synchronized (this) { 
    7.                 if (ticketCount > 0) { 
    8.                     try { 
    9.                         Thread.sleep(100); 
    10.                     } catch (InterruptedException e) { 
    11.                         e.printStackTrace(); 
    12.                     } 
    13.                     System.out.println(Thread.currentThread().getName() 
    14.                             + " sell ticket: " + ticketCount--); 
    15.                 } 
    16.  
    17.             } 
    18.         } 
    19.     } 
    20.  
    21.  
    22. public class Demo01 { 
    23.     public static void main(String[] args) { 
    24.         TicketSeller ticketSeller = new TicketSeller(); 
    25.         new Thread(ticketSeller, "Thread A").start(); 
    26.         new Thread(ticketSeller, "Thread B").start(); 
    27.         new Thread(ticketSeller, "Thread C").start(); 
    28.         new Thread(ticketSeller, "Thread D").start(); 
    29.     } 
     测试结果:
    1. Thread A sell ticket: 10 
    2. Thread A sell ticket: 9 
    3. Thread D sell ticket: 8 
    4. Thread D sell ticket: 7 
    5. Thread D sell ticket: 6 
    6. Thread C sell ticket: 5 
    7. Thread C sell ticket: 4 
    8. Thread C sell ticket: 3 
    9. Thread B sell ticket: 2 
    10. Thread B sell ticket: 1 
    18、中断处理
    1. class TicketSeller implements Runnable { 
    2.  
    3.     @Override 
    4.     public void run() { 
    5.         try { 
    6.             System.out.println("线程启动"); 
    7.             Thread.sleep(10000); 
    8.         } catch (InterruptedException e) { 
    9.             System.out.println("线程被中断"); 
    10.             // e.printStackTrace(); 
    11.         } 
    12.     } 
    13.  
    14.  
    15. public class Demo01 { 
    16.     public static void main(String[] args) throws InterruptedException { 
    17.         TicketSeller ticketSeller = new TicketSeller(); 
    18.         Thread thread = new Thread(ticketSeller, "Thread A"); 
    19.         thread.start(); 
    20.  
    21.         System.out.println("====主线程执行==="); 
    22.         Thread.sleep(1000); 
    23.         // thread.interrupt(); 
    24.         System.out.println("线程被中断否:" + thread.isInterrupted()); 
    25.         thread.interrupt(); 
    26.         System.out.println("线程被中断否:" + thread.isInterrupted()); 
    27.         System.out.println("线程被中断否2:" + thread.isInterrupted()); 
    28.         System.out.println("主线程是否被中断:" + Thread.interrupted()); 
    29.  
    30.         System.out.println("====主线程结束==="); 
    31.  
    32.     } 
     测试结果:
    1. ====主线程执行=== 
    2. 线程启动 
    3. 线程被中断否:false 
    4. 线程被中断否:true 
    5. 线程被中断否2:true 
    6. 主线程是否被中断:false 
    7. 线程被中断 
    8. ====主线程结束=== 

    结论: 

     interrupt中断该线程, isInterrupted检查该线程是否被中断, interrupted检查当前线程是否被中断。

  • 相关阅读:
    面向切面编程AOP
    多线程:Monitor、synchronized、volatile
    约束布局ConstraintLayout
    【转】StackTraceElement获取方法调用栈的信息
    Java中的Type
    Android App 架构演变
    Java泛型
    web测试方法总结
    机器学习 损失函数
    深度学习 激活函数
  • 原文地址:https://www.cnblogs.com/gisblogs/p/4269543.html
Copyright © 2020-2023  润新知