黑马程序员技术交流社区

标题: 【石家庄中心】java基础知识05 [打印本页]

作者: 逗比默默哒    时间: 2018-1-24 16:39
标题: 【石家庄中心】java基础知识05
本帖最后由 小石姐姐 于 2018-4-20 10:55 编辑

                                                    java基础知识05

删除一个文件夹内的所有文件和文件夹
  • File file = new File(imgPath);  
  • if (!file.exists()) return;  
  • deleteDirectory(file);  
  •   
  •   
  • public void deleteDirectory(File path) {  
  •             if( path.exists() ) {  
  •                   File[] files = path.listFiles();  
  •                   for(int i=0; i<files.length; i++) {  
  •                          if(files.isDirectory()) {  
  •                            deleteDirectory(files);  
  •                          }  
  •                          else {  
  •                            files.delete();  
  •                          }  
  •                   }  
  •             }  
  •       }  

关于JSP中的pageContext:
使用pageContext所设定的属性对象,其共享范围限于同一个JSP页面
使用request所设定的属性对象,其在同一个request处理期间可以共享(包括forward给其它JSP页面),
session对象所设定的属性对象则限于同一个进程作用期间可以共享,
而application对象所设定的属性,则在整个Web应用程序中的JSP页面都可以共享。
Final的初始化
1.  final修饰的成员变量没有默认值
2.  final初始化可以在三个地方
    (1)声明的时候初始化
    (2)构造函数里初始化
    (3)要是没有static修饰的话可以在非静态块里初始化,要是有static修饰的话可以在静态块里初始化
3.  使用final成员前要确保已经初始化,如果没初始化,或者初始化多次,则无法通过编译。
一些转换技巧
  • Map<String, HandlerMapping> matchingBeans =  
  •                 BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);  
  •   
  •     //map转换list  
  •     List<HandlerMapping> handlerMappings = new ArrayList<HandlerMapping>(matchingBeans.values());  
  •       
  •     //map判断空  
  •     if (!matchingBeans.isEmpty())  
  •       
  •     //数组转List (interceptors 数组)  
  •     interceptorList.addAll(Arrays.asList(this.interceptors));  
  •       
  •     //List转指定对象数组  
  •     interceptors = this.interceptorList.toArray(new HandlerInterceptor[this.interceptorList.size()]);  
java.lang.Number是所有基础类型的父类

  • public abstract class Number implements java.io.Serializable {  
  •       
  •     public abstract int intValue();  
  •       
  •     public abstract long longValue();  
  •       
  •     public abstract float floatValue();  
  •       
  •     public abstract double doubleValue();  
  •       
  •     public byte byteValue() {  
  •     return (byte)intValue();  
  •     }  
  •       
  •     public short shortValue() {  
  •     return (short)intValue();  
  •     }  
  • }  

  • public final class Long extends Number implements Comparable<Long>   
  •   
  • public final class Integer extends Number implements Comparable<Integer>   
JDK、JRE、JVM
JDK:Java Development ToolKit
Java开发工具包
JRE:Java Runtime Environment
Java运行环境
JVM:Java Virtual Machine
Java虚拟机
JMM:Java Memory Model
Java内存模型
JDK是SUN公司发布的用于开发Java程序的工具包
在它的bin目录下有很多工具,常见的包括:javac.exe,java.exe,javadoc.exe等(其中有很多都是用Java编写的)各种版本的IDE工具也是需要使用JDK来完成编译,打包,运行等各种功能的。
JRE顾名思义,java的运行环境
JDK是开发工具,在它的安装目录下包含了JRE目录,其实在安装JDK时(1.4版本以上),有一个安装选项,如果勾上时,在Java的安装目录下会多一个JRE目录,这里的JRE与JDK下的JRE目录基本上是完全一致的,那么为什么需要两个JRE呢?
前面已经提到过,JDK的bin目录下的很多工具都是用Java编写的使用这些工具的时候也是需要运行环境的,通过这些.exe包装器(这些包装器提供了寻找tools.jar中的一些java类的快捷方法,不需要输入一长串的包名和类名)来使用那些工具时,java会自动寻找父目录下的JRE,所以在这里放置了JRE。
JVM:Java虚拟机,在window下作为动态连接库(jvm.dll)存在,用于解释执行Java字节码。jvm.dll文件路径为:jre7\bin\server
可以把它理解成是专门用来执行Java程序的一台机器。也就是说JVM提供了Java执行的硬件平台。JVM上执行的代码都存放在.CLASS文件中。JVM只执行字节码文件。
==================================================================
Java的跨平台如何体现:
JVM也是一个软件,不同的平台有不同的版本。我们编写的Java源码,编译后会生成一种 .class 文件,称为字节码文件。Java虚拟机就是负责将字节码文件翻译成特定平台下的机器码然后运行。也就是说,只要在不同平台上安装对应的JVM,就可以运行字节码文件,运行我们编写的Java程序。
注意:编译的结果不是生成机器码,而是生成字节码,字节码不能直接运行,必须通过JVM翻译成机器码才能运行。不同平台下编译生成的字节码是一样的,但是由JVM翻译成的机器码却不一样。
所以,运行Java程序必须有JVM的支持,因为编译的结果不是机器码,必须要经过JVM的再次翻译才能执行。即使你将Java程序打包成可执行文件(例如 .exe),仍然需要JVM的支持。
注意:跨平台的是Java程序,不是JVM。JVM是用C/C++开发的,不能跨平台,不同平台下需要安装不同版本的JVM。
finalize()
Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。
这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在 Object 类中定义的,因此所有的类都继承了它。子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作。
finalize() 方法是在垃圾收集器删除对象之前对这个对象调用的。
垃圾收集器只知道释放那些由new分配的内存,所以不知道如何释放对象的“特殊”内存。为解决这个问题
Java提供了一个名为finalize()的方法,它的工作原理应该是这样的:一旦垃圾收集器准备好释放对象占用的存储空间,它首先调用finalize(),而且只有在下一次垃圾收集过程中,才会真正回收对象的内存
所以如果使用finalize(),就可以在垃圾收集期间进行一些重要的清除或清扫工作(如关闭流等操作)。但JVM(Java虚拟机)不保证此方法总被调用。
原子操作AtomicInteger
  • public class AtomicLong extends Number  
  •                 implements Serializable  
API
不使用synchronized关键字,AtomicInteger通过另一种线程安全的方法实现加减操作
AtomicInteger为什么能够达到多而不乱,处理高并发应付自如呢?
这是由硬件提供原子操作指令实现的,这里面用到了一种并发技术:CAS。在非激烈竞争的情况下,开销更小,速度更快。
Java.util.concurrent中实现的原子操作类包括:
AtomicBoolean、AtomicInteger、AtomicIntegerArray、AtomicLong、AtomicReference、AtomicReferenceArray。
J2SE 5.0提供了一组atomic class来帮助我们简化同步处理
基本工作原理是使用了同步synchronized的方法实现了对一个long, integer, 对象的增、减、赋值(更新)操作. 比如对于++运算符, AtomicInteger可以将它持有的integer 能够atomic 地递增。在需要访问两个或两个以上 atomic变量的程序代码(或者是对单一的atomic变量执行两个或两个以上的操作)通常都需要被synchronize以便两者的操作能够被当作是一个atomic的单元。
  • addAndGet(long delta)   
  •     //以原子方式将给定值添加到当前值。  
  •   
  • getAndSet() :   
  •     //设置新值,返回旧值.   
  •   
  • compareAndSet(expectedValue, newValue) :   
  •     //如果当前值 == 预期值,则以原子方式将该值设置为给定的更新值  
  •     //如果更新成功,返回true, 否则返回false  
  •     //换句话可以这样说: 将原子变量设置为新的值, 但是如果从我上次看到的这个变量之后到现在被其他线程修改了(和我期望看到的值不符), 那么更新失败   
  •     /*  单线程下, compareAndSet返回永远为true,      
  •      *  多线程下, 在与result进行compare时, counter可能被其他线程set了新值, 这时需要重新再取一遍再比较,      
  •      *  如果还是没有拿到最新的值, 则一直循环下去, 直到拿到最新的那个值  
  •     */  
  •   
  • int incrementAndGet()   
  •           以原子方式将当前值加 1。  
为了提高性能,AtomicLong等类在实现同步时,没有用synchronized关键字,而是直接使用了最低层(本地c语言实现代码)来完成的,
因而你是看不到用synchronized关键字的.
比如:AtomicLong类中原子操作方法:
public final boolean compareAndSet(long expect, long update) ;
就是直接使用SUN公司低层本地代码的原子方法(native方法):
public final native boolean compareAndSwapLong(...)来实现的.
Example:
  • import java.util.*;   
  • import java.util.concurrent.*;   
  • import java.util.concurrent.atomic.*;   
  • /*  
  • * ava.util.concurrent中实现的原子操作类包括:  
  • AtomicBoolean、AtomicInteger、AtomicIntegerArray、AtomicLong、AtomicReference、  
  • AtomicReferenceArray。  
  • *   
  • */   
  • public class AtomicOperationDemo {   
  •        static AtomicInteger count=new AtomicInteger(0);   
  •        public static class AddThread implements Runnable{   
  •         @Override   
  •         public void run() {   
  •             for(int k=0;k<1000;k++){   
  •                 count.incrementAndGet();   
  •             }   
  •          }     
  •        }   
  •          
  •          
  •        public static void AtomicIntShow(){   
  •          System.out.println("AtomicIntShow() enter");   
  •          ExecutorService threadpool =   Executors.newFixedThreadPool(10);   
  •             
  •          //开100个线程   
  •          for(int k=0;k<100;k++){   
  •              threadpool.submit(new AddThread());   
  •          }   
  •             
  •          try {   
  •             Thread.sleep(2000);   
  •         } catch (InterruptedException e) {   
  •             // TODO Auto-generated catch block   
  •             e.printStackTrace();   
  •         }   
  •             
  •          /* output  
  •           * AtomicIntShow() enter  
  •           * result of acumulated sum=100000  
  •           * AtomicIntShow() exit  
  •           */   
  •             
  •          System.out.println("result of acumulated sum="+count);   
  •          threadpool.shutdown();   
  •          System.out.println("AtomicIntShow() exit");   
  •          return ;   
  •             
  •     }   
  • }   
  •   
  •   
  • public class Maintest {   
  •     public static void main(String[] args) {   
  •         AtomicOperationDemo.AtomicIntShow();   
  •     }   
  • }   
  •   
  •   
  • 结果:  
  • /* output  
  •           * AtomicIntShow() enter  
  •           * result of acumulated sum=100000  
  •           * AtomicIntShow() exit  
  •           */   
Object、String类中equals方法的不同
StringBuffer / StringBuilder的equals方法都是继承的Object方法
String类中对equals方法进行了重写
Object类的equals方法的实现:
  • public boolean equals(Object obj) {  
  •     return (this == obj);  
  • }  

Object中的equals就是用==来比较当前对象和传入的参数的。

再看看String的equals实现

  • public boolean equals(Object anObject) {  
  •     if (this == anObject) {  
  •         return true;  
  •     }  
  •     if (anObject instanceof String) {  
  •         String anotherString = (String)anObject;  
  •         int n = count;  
  •         if (n == anotherString.count) {  
  •         char v1[] = value;  
  •         char v2[] = anotherString.value;  
  •         int i = offset;  
  •         int j = anotherString.offset;  
  •         while (n-- != 0) {  
  •             if (v1[i++] != v2[j++])  
  •             return false;  
  •         }  
  •         return true;  
  •         }  
  •     }  
  •     return false;  
  • }  

它去比较内容了。

再看StringBuilder,在其源码里没有发现equals方法,那么它就继承了Object的实现,用==来比较传进来的参数。

我们看到equals是个实例方法(非static),实例方法是可以被子类重写而去实现自己想要的行为的,因此,不能轻易的说equals就是比较内容的,其行为是特定于实现的。但==确实是比较地址的。因为java中不支持(至少现在不支持)运算符重载,我们不能改变==的含义,其行为是固定死的。

记得下次不要说“==比较地址,equals比较内容”这样的话了,如果要说,也在前面加上特定的条件,如“如果比较String”,勿断章取义

不借助中间变量交换元素
  • a = a + b  
  • b = a - b   
  • a = a - b   
UUID
UUID(Universally Unique Identifier)
全局唯一标识符
是指在一台机器上生成的数字,是1.5中新增的一个类,在java.util下,用它可以产生一个号称全球唯一的ID
按照开放软件基金会(OSF)制定的标准计算,用到了以太网卡地址、纳秒级时间、芯片ID码和许多可能的数字。
由以下几部分的组合:当前日期和时间(UUID的第一个部分与时间有关,如果你在生成一个UUID之后,过几秒又生成一个UUID,则第一个部分不同,其余相同),时钟序列,全局唯一的IEEE机器识别号(如果有网卡,从网卡获得,没有网卡以其他方式获得),UUID的唯一缺陷在于生成的结果串会比较长。
JDK1.5
如果使用的JDK1.5的话,那么生成UUID变成了一件简单的事,以为JDK实现了UUID:
java.util.UUID,直接调用即可.
String s = UUID.randomUUID().toString();  
UUID是由一个十六位的数字组成,表现出来的形式例如
550E8400-E29B-11D4-A716-446655440000   
获取随机数
法1:
  • int num = getRandom(1000);  
  •    
  • public static int getRandom(int num) {  
  •     return (int) Math.round(Math.random() * num);  
  • }  
API:
double java.lang.Math.random()
//Returns a double value greater than or equal to 0.0 and less than 1.0
long java.lang.Math.round(double a)
法2:
  • Random random = new Random();  
  • int num = random.nextInt(50);  
API:
int java.util.Random.nextInt(int n)
//Returns a int value between 0 (inclusive) and the specified value (exclusive),
公共方法:
  • public static final String allChar = "023456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ";  
  •     public static final String numberChar = "023456789";  
  •   
  •     /*
  •      * 获取随机字符串
  •      */  
  •     public static String generateString(int length){  //参数为返回随机数的长度  
  •         StringBuffer sb = new StringBuffer();  
  •         Random random = new Random();  
  •         for (int i = 0; i < length; i++) {  
  •             sb.append(allChar.charAt(random.nextInt(allChar.length())));  
  •         }  
  •         return sb.toString();  
  •     }  
  •       
  •     public static String generateNumber(int length){  //参数为返回随机数的长度  
  •         StringBuffer sb = new StringBuffer();  
  •         Random random = new Random();  
  •         for (int i = 0; i < length; i++) {  
  •             sb.append(numberChar.charAt(random.nextInt(numberChar.length())));  
  •         }  
  •         return sb.toString();  
  •     }  
request.getParameterMap()
在servlet中GET请求可以通过HttpServletRequest的getRequestURL方法和getQueryString()得到完整的请求路径和请求所有参数列表,
POST的需要getParameterMap()方法遍历得到,
不论GET或POST都可以通过getRequestURL+getParameterMap()来得到请求完整路径
request.getParameterMap()的返回类型是Map类型的对象,也就是符合key-value的对应关系,但这里要注意的是,value的类型是String[],而不是String.
得到jsp页面提交的参数很容易,但通过它可以将request中的参数和值变成一个map,以下是将得到的参数和值
打印出来,形成的map结构:map(key,value[]),即:key是String型,value是String型数组。
例如:request中的参数t1=1&t1=2&t2=3
形成的map结构:
key=t1;value[0]=1,value[1]=2
key=t2;value[0]=3
如果直接用map.get("t1"),得到的将是:Ljava.lang.String; value只所以是数组形式,就是防止参数名有相同的
情况。
  • public class ParamsUitl {  
  •   
  •     public static Map<String, String> getParamsMap(HttpServletRequest request) {  
  •         Map<String,String> params = new HashMap<String,String>();  
  •         Map requestParams = request.getParameterMap();  
  •         for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {  
  •             String name = (String) iter.next();  
  •             String[] values = (String[]) requestParams.get(name);  
  •             String valueStr = "";  
  •             for (int i = 0; i < values.length; i++) {  
  •                 valueStr = (i == values.length - 1) ? valueStr + values
  •                         : valueStr + values + ",";  
  •             }  
  •             valueStr = new String(valueStr);  
  •             params.put(name, valueStr);  
  •         }  
  •         return params;  
  •     }     
  • }  

特殊字符过滤
  • private String formatString(String oldStr){  
  •         String regEx="[`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~!@#¥%……&*()——+|{}【】‘;:”“’。,、?\r\n|\r|\n|\n\r]";   
  •         Pattern   p   =   Pattern.compile(regEx);      
  •         Matcher   m   =   p.matcher(oldStr);      
  •         return m.replaceAll("").trim();  
  •     }  





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2