11. JAVA常用类库 Part 1 (StringBuffer、Runtime、国际化程序) ----- 学习笔记

本文详细阐述了Java中的String与StringBuffer类的区别,包括字符串连接、内容修改、反转、替换、截取和删除操作,并介绍了如何在实际应用中使用StringBuffer提高代码性能。此外,文章还探讨了Runtime类的功能,如获取JVM内存信息和执行本地命令,以及如何通过Locale和ResourceBundle实现国际化程序开发。

目标:

  1. 掌握String与StringBuffer的区别,可以熟练使用StringBuffer中的各种方法进行相关操作
  2. 能够自己编写一个得到日期的操作类,并将这些日期进行格式化操作
  3. 掌握比较器及其基本原理,并可以通过比较起进行对象数组的比较操作
  4. 掌握对象克隆技术及其实现要求
  5. 能够灵活地应用正则表达式对字符串的组成进行判断
  6. 了解并使用JAVA中提供的观察者操作机制
  7. 认识JAVA中的Random、Locale、Math等常用类,并可以使用Local进行国际化程序的编写
  8. 描述出Object、System类对垃圾收集的支持
  9. 使用NumberFormat、DecimalFormat、BigInteger、BigDecimal进行数字的操作
  10. 了解JAVA定时器任务调度的实现

11.1  StringBuffer类

          11.1.1 认识StringBuffer类

                String类: String 的内容一旦声明则不可改变。 如果要改变,改变的肯定是String 的引用地址!!!

                StringBuffer类: 如果一个字符串要经常被改变,为了节约资源,则必须使用StringBuffer类!!!

                字符串的连接方式: String类通过 “+” 进行字符串的连接; 而StringBuffer类只能使用append()方法进行字符串的连接。例如:String类用“+”,"Hello" + " " + "World" + " " + "!!!"      而StringBuffer类用append()方法 ,  "Hello" append " " append "World" append " " append "!!!"

下面来一一验证这些方法

tips: StringBuffer支持的方法大部分与String类似,因为StringBuffer在开发中可以提升代码的性能,所以使用较多,这样为了保证用户操作的适应性。

一, 字符串连接操作: 在程序中使用append()方法可以进行字符串的连接,而且此方法返回了一个StringBuffer类的实例,这样就可以采用代码链的形式一直调用append()方法。

package org.forfan06.stringbufferdemo;
public class StringBufferDemo01{
    public static void main(String args[]){
        StringBuffer buf = new StringBuffer();
        buf.append("Hello");
        buf.append("World").append("!!!");
        buf.append("\n");
        buf.append("数字 = ").append(1).append("\n");
        buf.append("字符 = ").append('C').append("\n");
        buf.append("布尔 = ").append(true);
        System.out.println(buf);
    }
}

运行结果:

-------------------------------------------------
Hello World!!!
数字 = 1
字符 = C
布尔 = true

-------------------------------------------------

/*验证StringBuffer的内容是可以修改的!!!*/
package org.forfan06.stringbufferdemo;
public class StringBufferDemo02{
    public static void main(String args[]){
        StringBuffer buf = new StringBuffer();
    	buf.append("Hello ");     //向StringBuffer对象中添加内容
    	fun(buf);                 //调用方法,传递StringBuffer引用
    	System.out.println(buf);   //输出结果是:Hello CSDN forfan06
    }
    //fun方法没有返回值,但是在方法中修改了StringBuffer对象的内容,主方法输出的是修改后的值。说明StringBuffer是引用数据类型。
    public static void fun(StringBuffer s){   //接收StringBuffer引用
        s.append("CSDN ").append("forfan06");   //修改StringBuffer内容
    }
}


/*在任意位置处向StringBuffer添加内容!!!*/
package org.forfan06.stringbufferdemo;
public class StringBufferDemo03{
    public static void main(String args[]){
        StringBuffer buf = new StringBuffer();
    	buf.append("World!!!");     //向StringBuffer对象中添加内容
    	buf.insert(0, "Hello ");    //在所有内容之前添加新的内容
        System.out.println(buf);    //输出结果是:Hello World!!!
        buf.insert(buf.length(), " forfan06");   //在最后添加新的内容
        System.out.println(buf);      //输出结果是:Hello World!!! forfan06
  }
}


/*StringBuffer字符串反转操作!!!*/
package org.forfan06.stringbufferdemo;
public class StringBufferDemo04{
    public static void main(String args[]){
        StringBuffer buf = new StringBuffer();
        buf.append("World!!!");
        buf.insert(0, "Hello ");
        String str = buf.reverse().toString();   //将buf内容反转后,转换成String类型。效果与buf.reverse()然后直接输出buf一样。
        System.out.println(str);           //输出结果:!!!dlroW olleH
    }
}

注意,在字符串的操作中,反转是一种较为常见的操作!!!最早的字符串反转操作实际上是通过入栈和出栈功能来完成的。

/*替换StringBuffer字符串中指定范围的内容!!!*/
package org.forfan06.stringbufferdemo;
public class StringBufferDemo05{
    public static void main(String args[]){
        StringBuffer buf = new StringBuffer();
        buf.append("Hello ").append("World!!!");
        System.out.println(buf);            //输出结果:Hello World!!!
        buf.replace(6, 11, "forfan06");    //用字符串forfan06替换buf从6到11的字符
        System.out.println("内容替换之后的结果是:" + buf);   //输出结果:Hello forfan06!!!
    }
}

在String中如果要进行替换,则使用的是replaceAll()方法,而在StringBuffer中使用的是replace()方法!!!!

<span style="color:#ff0000;">public StringBuffer replace(int start, int end, String str)</span>

三个参数的含义:  start - 开始索引,包含此点; end - 终止索引,不包含此点; str - 要插入的串

/*截取StringBuffer字符串!!!*/
package org.forfan06.stringbufferdemo;
public class StringBufferDemo06{
    public static void main(String args[]){
        StringBuffer buf = new StringBuffer();
        buf.append("Hello ").append("World!!!");
        System.out.println(buf);            //输出结果:Hello World!!!
        buf.replace(6, 11, "forfan06");    //用字符串forfan06替换buf从6到11的字符
        System.out.println("内容替换之后的结果是:" + buf);   //输出结果:Hello forfan06
        
        String str = buf.substring(6, 15);   //包含start点,不包括end点
        System.out.println("截取之后的内容:" + str);   //输出结果:forfan06!
    }
}


/*删除StringBuffer字符串中指定范围的字符串!!!*/
package org.forfan06.stringbufferdemo;
public class StringBufferDemo07{
    public static void main(String args[]){
        StringBuffer buf = new StringBuffer();
        buf.append("Hello ").append("World!!!");
        System.out.println(buf);            //输出结果:Hello World!!!
        buf.replace(6, 11, "forfan06");    //用字符串forfan06替换buf从6到11的字符
        System.out.println("内容替换之后的结果是:" + buf);   //输出结果:Hello forfan06
        
        String str = buf.delete(6, 15).toString();   //包含start点,不包括end点
        System.out.println("删除之后的内容:" + str);   //输出:Hello !!
    }
}


查找指定的内容是否存在: 通过indexOf()方法可以查找指定的内容。如果找到了,则返回内容的位置;如果没有找到则返回-1

/*删除StringBuffer字符串中指定范围的字符串!!!*/
package org.forfan06.stringbufferdemo;
public class StringBufferDemo08{
    public static void main(String args[]){
        StringBuffer buf = new StringBuffer();
        buf.append("Hello ").append("World!!!");
        System.out.println(buf);            //输出结果:Hello World!!!
        if(buf.indexOf("Hello") == -1){
            System.out.println("没有找到指定的内容");
        }else{
            System.out.println("找到了指定内容:" + buf.indexOf("Hello"));   //输出结果:找到了指定内容:0
        }
    }
}


          11.1.2 StringBuffer类的应用

对于频繁修改字符串内容的地方,最好使用StringBuffer类完成。 其优点可以从下面程序看出:

/*使用String类实现修改字符串的功能!!!*/
package org.forfan06.stringbufferdemo;
public class StringBufferDemo09{
    public static void main(String args[]){
        String str = "forfan06";
        for (int i = 0; i < 100; i++){
            str += i;
        }
        System.out.println(str);
    }
}

上面程序中,虽然修改了字符串的内容,但实际上是通过不断修改对象的引用来实现的。其性能很差。 要解决此类的问题可以依靠StringBuffer类。因为StringBuffer类的内容是可以修改的。

/*使用StringBuffer类实现修改字符串的功能!!!*/
package org.forfan06.stringbufferdemo;
public class StringBufferDemo10{
    public static void main(String args[]){
        StringBuffer buf = new StringBuffer();
        buf.append("forfan06");
        for (int i = 0; i < 100; i++){
            buf.append(i);
        }
        System.out.println(buf);
    }
}

11.2 Runtime类

          11.2.1 认识Runtime类

           在Java中Runtime类表示运行时操作类,是一个封装了JVM进程的类,每一个JVM都对应一个Runtime类的实例,此实例由JVM运行时为其实例化。所以在JDK文档中不会发现任何有关Runtime类中构造方法的定义,这是因为Runtime类本身的构造方法是私有化的(单例设计), 如果想要去的一个Runtime类的实例,则只能通过以下方法:

Runtime run = Runtime.getRuntime();

也就是说Runtime类中提供了一个静态方法getRuntime()方法,此方法可以取得Runtime类的实例。

因为Runtime表示的是每一个JVM实例,则可以通过Runtime取得一些系统信息。 方法如下所示:

  1. public static Runtime getRuntime()     //取得Runtime类的实例
  2. public long freeMemory()             //返回Java虚拟机中的空闲内存量
  3. public long maxMemory()              //返回JVM的最大内存量
  4. public void gc()                     //运行垃圾回收器,释放空间
  5. public Process exec(String command) throws IOException               //执行本机命令,返回的是一个Process的实例化对象

          11.2.2 得到JVM的内存空间信息

              使用Runtime类可以取得JVM中的内存空间,包括最大内存空间、空闲内存空间等等。通过这些信息可以清楚地知道JVM的内存使用情况。程序代码如下:

/*观察JVM的内存空间!!!*/
package org.forfan06.runtimedemo;
public class RuntimeDemo01{
    public static void main(String args[]){
        Runtime run = Runtime.getRuntime();  //通过Runtime类的静态方法为其进行实例化操作
        System.out.println("JVM最大内存量:" + run.maxMemory());  //观察最大内存量,根据机器环境会存在差异
        System.out.println("JVM空闲内存量:" + run.freeMemory());   //取得程序运行之前的内存空闲量
        
        String str = "Hello " + "World" + "!!!" + "\t" +"Welcome " + "To" + "CSDN" + "!";
        System.out.println(str);
        for (int i = 0; i < 100; i++){
            str += i;
        }
        System.out.println("操作String之后的,JVM空闲内存量:" + run.freeMemory());  //观察有多个垃圾空间产生之后的内存空闲量
        
        run.gc();   //运行垃圾收集,释放空间
        
        System.out.println("垃圾回收之后,JVM空闲内存量:" + run.freeMemory());
        
        StringBuffer buf = new StringBuffer();
        buf.append("Hello ").append("World").append("!!!").append("\t").append("Welcome ").append("To ").append("CSDN").append("!");
        for (int i = 0; i < 100; i++){
            buf.append(i);
        }
        System.out.println("操作StringBuffer之后的,JVM空闲内存量:" + run.freeMemory());
    }
}

运行结果:

c:\JAVA Demo\runtimedemo>javac -d . RuntimeDemo01.java

c:\JAVA Demo\runtimedemo>java org.forfan06.runtimedemo.RuntimeDemo01
Max memory is: 259522560
Free meomory is: 15601616
After change String 100 time, free memory is: 15510968
After running gc, free memory is: 15746544
After change StringBuffer 100 times, free memory is: 15562848

          11.2.3 Runtime类与Process类

                    可以直接使用Runtime类运行本机的可执行程序。例如下面程序可以调用本机的记事本程序,记事本程序的执行命令是“notepad.exe”。

/*Runtime类与Process类:调用本机可执行程序,如记事本!!!*/
package org.forfan06.runtimedemo;
import java.io.*;
package org.forfan06.runtimedemo;
public class RuntimeDemo02{
    public static void main(String args{}){
        Runtime run = Runtime.getRuntime();
        try {
            run.exec("notepad.exe");    //调用本机可执行程序。必须进行异常处理。因为exec定义出throws IOException
        }catch(IOException e){
            e.printStackTrace();
        }
    }
}

运行下面命令

javac -d . RuntimeDemo02.java
<pre class="java" name="code">java org.forfan06.runtimedemo.RuntimeDemo02

 

Runtime类对exec方法的定义如下:

public Process exec(String command) throws IOException


可以发现,exec方法的返回值类是一个Process的实例。并且调用exec方法处必须进行异常的捕获处理。

我们可以利用Process类来对系统进程进行控制。例如,销毁一个进程可以方法:

public void destroy()

/*Runtime类与Process类:调用本机可执行程序,如记事本!!!*/
package org.forfan06.runtimedemo;
import java.io.*;
package org.forfan06.runtimedemo;
public class RuntimeDemo02{
    public static void main(String args{}){
        Runtime run = Runtime.getRuntime();
        Process pro = null;
        try {
            pro = run.exec("notepad.exe");    //调用本机可执行程序。必须进行异常处理。因为exec定义出throws IOException
        }catch(IOException e){
            e.printStackTrace();
        }
        try {
            Thread.sleep(5000);
        }catch(InterruptedException e){
            e.printStackTrace();
        }
        pro.destroy();
    }
}

11.3 国际化程序

            国际化程序的操作就是指一个程序可以同时适应多门语言。让一个程序适应各个国家的语言要求。 其程序代码是不变的,只是其显示文字上有所差异而已!!!

            实现国际化程序需要Locale类、属性文件、ResourceBundle类的支持!!!所谓的属性文件是指后缀为.properties的文件,文件中的内容保存结构为“key = value”形式(关于属性文件的具体操作可以参考jva类集部分)。 因为国际化的程序只是显示语言的不同,那么就可以根据不同的国家定义不同的属性文件,属性文件中保存真正要用的文字信息,要访问这些属性文件,可以使用ResourcdBundle类来完成。


          11.3.1 国际化程序的实现思路

    根据各个不同的国家配置不同的资源文件(资源文件也称为属性文件,因为其后缀是.properties),所有的资源文件以“key --> value”的形式出现(类似 message = 你好!),在程序执行中只是根据key找到value并将value的内容进行显示。也就是说,只要key不变,value的内容可以任意更换。

       如果要实现java程序的国际化操作必须通过以下3个类完成:

  1. java.util.Locale:   用于表示一个国家语言类
  2. java.util.ResourceBundle:    用于访问资源文件,也就是属性文件
  3. java.text.MessageFormat:    格式化资源文件的占位字符串

  这3个类的具体操作流程为: 通过Locale类所指定的区域码,然后ResourceBundle根据Locale类所指定的区域码找到对应的资源文件,如果资源文件存在动态文本,则使用MessageFormat进行格式化。

          11.3.2 Locale类

                要实现程序的国际化首先要认识Locale类,因为此类是实现国际化的一个重要类。 下面列出了Locale类的构造方法:

public Locale(String language)         //根据语言代码构造一个语言环境
public Locale(String language, String country)                              //根据语言和国家构造一个语言环境
  
             对于各个国家都有对应的ISO编码。 例如中国的编码是zh-CN; 英语-美国的编码是en-US; 法语的编码为fr-FR。

          11.3.3 ResourceBundle类

             ResourceBundle类主要作用是读取属性文件,读取属性文件时可以直接指定属性文件的名称(指定名称时不需要文件的后缀名),也可以根据Locale所指定的区域码来选取指定的资源文件,ResourceBundle类的常用方法如下:

public static final ResourceBundle getBundel(String baseName)                     //取得ResourceBundle的实例,并指定要操作的资源文件名称
public static final ResourceBundle getBundle(String baseName, Locale locale)                  //取得ResourceBundle的实例,并指定要操作的资源文件名称和区域码
public final String getString(String key)                     //根据key从资源文件中取出对应的value

          如果现在要使用ResourceBundle对象,则肯定直接通过ResourceBundle类中的静态方法getBundle()取得。

实例:通过ResourceBundle取得资源文件中的内容

(1)定义资源文件Message.properties

                       info = HELLO

(2)从资源文件中取得内容

import java.util.ResourceBundle;
public class InterDemo01{
    public static void main(String args[]){
        ResourceBundle rb = ResourceBundle.getBundle("Message");          //找到资源文件
        System.out.println("内容:" + rb.getString("info"));         //从资源文件中取得内容
    }
}

          11.3.4 Java国际化程序实现

                在程序中结合Locale类和ResourceBundle类一起完成一个国际化的程序开发。

                下面完成一个简单的国际化操作,可以根据Locale所选择的国家不同,输出不同国家的“你好!”   中文: 你好!     英语: Hello!    法语: Bonjour!

             首先根据不同的国家代码建立不同的属性文件,建立的属性文件与生成的*.class保存在同一个文件夹中。 因为现在程序要使用的有3种语言,所以要定义3种属性文件,在属性文件定义时必须按照“名称_国家代码”的形式命名,即所有相关的属性文件的名称全部一样,只有国家代码不一样,代码如下所示。

(1)中文的属性文件: Message_zh_CN.properties

info = \u4f60\u597d\uff01

实际上以上的信息就是中文的“你好!”, 在属性文件的操作中是不能直接写入中文字符的;就算是写入了中文字符,读取出来的也必然是乱码, 因此必须将相应的中文变为Unicode编码才可以,要成功地将一个中文编码变为Unicode编码,可以直接在运行处执行“native2ascii.exe”命令,输入相应的中文之后会自动将其进行编码。

                        *******native2ascii.exe是java的一个文件转码工具,是将特殊各异的内容 转为 用指定的编码标准文本形式统一的表现出来,通常位于JDK_home\bin目录下*******

(2)英语的属性文件: Message_en_US.properties

info = Hello!

(3)法语的属性文件: Message_fr_FR.properties

info = Bonjour!

通过Locale类和ResourceBundle类读取属性文件的内容,测试代码如下:

<pre class="java" name="code">import java.util.ResourceBundle;
import java.util.Locale;
public class InterDemo02{
    public static void main(String args[]){
        Locale zhLoc = new Locale("zh", "CN");
        Locale enLoc = new Locale("en", "US");
        Locale frLoc = new Locale("fr", "FR");
        
        ResourceBundle zhrb = ResourceBundle.getBundle("Message", zhLoc);          //找到资源文件
        ResourceBundle enrb = ResourceBundle.getBundle("Message", enLoc);
        ResourceBundle frrb = ResourceBundle.getBundle("Message", frLoc);
        
        System.out.println("中文:" + zhrb.getString("info"));         //从资源文件中取得内容
        System.out.println("英语:" + enrb.getString("info"));
        System.out.println("法语:" + frrb.getString("info"));
    }
}
通过上面程序可以发现,根据Locale所制定的国家不同,读取的资源文件也不同,这样也就实现了国际化程序。

 

摘录: JAVA国际化

Locale的设置:

  Locale(String language, String country)

  例如中文:zh_CN,new Locale("zh","CN");//表示中国的Locale,由语言,国家组成

  美国英语:en_US,new Locale("en","US");

ResourceBundle的操作:

ResourceBundle resource=ResourceBundle.getBundle(String baseName, Locale locale);

  baseName,跟properties要对应,是第一个"_"前面的内容(资源文件名=baseName_local.language_locale.country.properties);

  locale,就是上面的Locale;

e.g.: Locale zhLoc = new Locale("zh","CN");

ResourceBundle resource=ResourceBundle.getBundle("Message",zhLoc);

这里调用的资源文件就是Message_zh_CN.properties;

如果要更改语言类型。

ResourceBundle resource=ResourceBundle.getBundle("Message",new Locale("en","US"));

这时候调用的资源文件就是Message_en_US.properties了

如果要取出对应的Text,可以使用resource.getString("")方法。

          11.3.5 处理动态文本

              以上程序中,所有资源内容都是固定的,但是输出的消息中如果包含了一些动态文本,则必须使用占位符清楚地表示出动态文本的位置,占位符使用“  {编号}  ” 的格式出现。使用占位符之后,程序可以直接通过MessgeFormat对信息进行格式化,为占位符动态设置文本内容。

             MessageFormat是Format类的子类,Format类主要实现格式化操作,除了MessageFormat子类之外,Format还有NumberFormat、DateFormat两个子类,这两个子类也是非常重要的章节。

  • 在进行国际化操作时,不光只有文字需要处理,实际上数字的显示、日期的显示都要符合各个区域的要求。 可以通过PC端Control Panel的“区域和语言选项”对话框观察到,需要同时改变的有数字、货币、时间等等。 所以Format类提供了MessageFormat、 NumberFormat、 DateFormat这3个子类。

现在以输出信息是“你好,xxx!",其中xxx的内容是程序动态设置的,所以此时要修改之前的3个属性文件,让其动态地接收程序的3个文本。

(1) 中文的属性文件: Message_zh_CN.properties

info = \u4f60\u597d\uff0c{0}\uff01

(2) 英文的属性文件: Message_en_US.properties

info = Hello, {0}!

(3) 法语的属性文件: Message_fr_FR.properties

info = Bonjour, {0}!

   以上3个属性文件中,都加入了“   {0}   ” ,表示一个占位符,如果有更多的占位符,则直接在后面继续加上“  {1}  ” 、“  {2}   ”即可。

  然后继续使用之前的Locale类和ResourceBundle类读取资源文件的内容,但是读取之后的文件因为要处理占位符的内容,所以要使用MessageFormat类进行处理。主要使用以下方法:

public static String format(String pattern, Object...arguments)

        上面format()方法中,第1个参数表示要匹配的字符串, 第2个参数“Object...arguments”表示输入参数可以任意多个,没有个数的限制!!!

测试代码如下:

import java.util.ResourceBundle;
import java.util.Locale;
import java.text.MessageFormat;
public class InterDemo03{
    public static void main(String args[]){
        Locale zhLoc = new Locale("zh", "CN");
        Locale enLoc = new Locale("en", "US");
        Locale frLoc = new Locale("fr", "FR");
        
        ResourceBundle zhrb = ResourceBundle.getBundle("Message", zhLoc);          //找到资源文件
        ResourceBundle enrb = ResourceBundle.getBundle("Message", enLoc);
        ResourceBundle frrb = ResourceBundle.getBundle("Message", frLoc);
        
        String str1 = zhrb.getString("info");
        String str2 = enrb.getString("info");
        String str3 = frrb.getString("info");
        
        System.out.println("中文:" + MessageFormat.format(str1, "某某某"));         
        System.out.println("英语:" + MessageFormat.format(str2, "forfan06"));
        System.out.println("法语:" + MessageFormat.format(str3, "forfan08"));
    }
}

补充:java新特性 -- 可变参数传递中可以接收多个对象。

 在方法传递参数时可以使用如下的格式:

返回值类型 方法名称(Object...arguments)

表示方法可以接收任意多个参数,然后按照数组的方式输出即可!!!!!!!!!!!!!!!!!!

/*测试可变参数的传递*/
public class MultiArgs01{
    public static void main(String args[]){
        System.out.print("The first running: ");
        fun("forfan06", "dylan", "CSDN");
        
        System.out.print("\nThe second running: ");
        fun("Heaven");
    }
    public static void fun(Object...args){
        for (int i = 0; i < args.length; i++){
            System.out.print(args[i] + "、");
        }
    }
}

也可以使用数组的方式向可变参数传递内容:  和上面的方式效果是一样的。

/*使用数组传递参数*/
public class MultiArgs02{
    public static void main(String args[]){
        System.out.print("The first time running: ");
        Object args1[] = {"forfan06", "dylan", "CSDN"};
        fun(args1);
        
        System.out.print("\nThe second time running: ");
        Object[] args2 = {"Heaven"};
        fun(args2);
        
        System.out.print("\nThe third time running: ");
        Object args3[] = {};
        fun(args3);
    }
    public static void fun(Object...args){
        for (int i = 0; i < args.length; i++){
            System.out.print(args[i] + "、");
        }
    }
}

          11.3.6 使用类代替资源文件

                可以使用属性文件保存所有的资源信息,当然,在java中也可以使用类来保存所有的资源信息,但是在开发中此种做法并不多见,主要还是以属性文件的应用为主。

                大胆猜想:使用属性文件做到了数据和代码的分离~~~~~~~~~~~~~~~

          与之前的资源文件一样,如果使用类保存信息,则也必须按照 key-value的形式出现,而且类的命名必须与属性文件一致;且此类必须继承自ListResourceBundle类!!!继承之后要覆写此类中的getContents()方法。

/*建立中文的资源类*/
package org.forfan06.internaltionaldemo;
import java.until.ListResourceBundle;
public class Message_zh_CN extends ListResourceBundle{
    private final Object data[][] = {"info", "你好,{0}"};
    public Object[][] getContents(){
        return data;
    }
}
/*在国际化中使用以上定义的类*/
import java.util.ResourceBundle;
import java.util.Locale;
import java.text.MessageFormat;
public class InterDemo04{
    public static void main(String args[]){
        Locale zhLoc = new Locale("zh", "CN");
        
        ResourceBundle zhrb = ResourceBundle.getBunlde("org.forfan06.internationaldemo.Message", zhLoc);
        
        String str1 = zhrb.getString("info");
        
        System.out.println("中文:" + MessageFormat.format(str1, "某某某"));
    }
}


!!!!!!!!!!!!!!!!在资源类中的属性一定是一个二维数组!!!!!!!!!!!!!!!!!

  • 如果在程序中同时出现了Message.properties、Message_zh_CN.properties、 Message_zh_CN.class 该如何访问??? 只会使用一个,按照优先级使用。顺序为:Message_zh_CN.class、Message_zh_CN.properties、 Message.properties
内容概要:本文提出了一种基于改进扩散模型的高海拔地区新能源高波动出力场景生成方法,并提供了完整的Python代码实现。该方法针对高海拔地区风能、光伏等新能源出力波动剧烈、不确定性高的特点,通过优化扩散模型的结构与训练策略,有效捕捉历史数据的概率分布特征与时序相关性,从而生成高质量、多样化的出力场景。文中详细阐述了模型的数学推导、网络架构设计、损失函数优化及采样算法改进,并通过实验证明其在拟合精度、场景多样性与稳定性方面优于传统生成模型,为电力系统在高比例新能源接入下的规划、调度与风险评估提供了可靠的场景输入支持。; 适合人群:具备一定Python编程能力和机器学习基础,从事新能源发电预测、电力系统分析、智能优化、场景生成等方向研究的科研人员、高校研究生及工程技术人员。; 使用场景及目标:①用于高海拔地区风电、光伏出力的不确定性建模与多场景生成;②支撑含高渗透率新能源的电力系统随机优化调度、鲁棒决策与风险评估;③为相关学术研究、论文复现与算法改进提供可运行的技术方案与代码基础; 阅读建议:建议读者结合所提供的完整资源(代码、数据集、说明文档)进行实践操作,重点关注扩散模型的前向加噪与反向去噪过程的设计细节,以及如何将其适配于新能源时序数据的生成任务,通过参数调优与对比实验深入理解模型的生成机制与性能边界。
内容概要:本文围绕基于静态约束法的配电网电动汽车接入容量评估展开研究,提出了一种在新型电力系统背景下评估主动配电网对电动汽车承载能力的方法。研究通过构建数学模型,结合潮流计算与关键约束条件(如电压越限、线路过载等),量化分析配电网可承受的最大电动汽车充电负荷容量,旨在识别规模化电动汽车接入带来的潜在运行风险,并为电网规划与运行提供科学依据。文中配套提供了完整的Matlab代码实现,便于仿真验证与结果复现。此外,该研究与分布式光伏承载力评估、电动汽车可调能力分析等方向形成技术联动,展现了多主题协同的研究体系。; 适合人群:具备电力系统分析基础理论知识及Matlab编程能力的高校研究生、科研机构研究人员,以及从事新能源并网、智能配电网规划与运行等相关领域的工程技术人员。; 使用场景及目标:①用于学术研究中的模型复现与论文撰写支撑;②评估实际配电网中电动汽车大规模接入的可行性与安全边界,指导充电基础设施布局;③作为高校教学案例,帮助学生深入理解电网承载力评估的核心原理、建模方法与仿真技术; 阅读建议:建议结合文中提及的相关研究方向(如二阶锥规划、多面体聚合方法等)进行对比学习,充分利用所提供的Matlab代码与网盘资料开展仿真实验,重点关注约束条件的设定逻辑与潮流计算模块的实现细节,以深化对评估模型机理与工程应用价值的理解。
内容概要:本文围绕“考虑隐私保护的分布式联邦学习电力负荷预测研究”展开,提出了一种基于Python实现的联邦学习框架,旨在解决居民或行业电力负荷预测中用户电表数据隐私泄露的风险。该研究通过构建分布式机器学习模型,使各参与方在不共享原始数据的前提下协同训练全局模型,有效实现了数据“可用不可见”。文中详细阐述了联邦学习的整体架构设计、本地模型训练流程、参数加密传输与安全聚合机制,并结合差分隐私等技术进一步增强系统的隐私保护能力。同时,研究利用真实电力负荷数据集进行了实验验证,展示了方法在预测精度与隐私保障之间的良好平衡,并提供了完整的代码实例与复现指南,便于后续研究与应用拓展。; 适合人群:具备一定机器学习基础和电力系统背景知识,从事智慧能源、隐私计算或人工智能相关方向研究的研究生、科研人员及工程技术人员。; 使用场景及目标:① 实现跨区域、跨主体的电力负荷协同预测,打破数据孤岛;② 在确保用户用电数据隐私安全的前提下提升负荷预测准确性;③ 推动联邦学习在智能电网、需求响应、虚拟电厂等场景中的实际部署与应用。; 阅读建议:建议结合文中提供的Python代码与网盘资料进行动手实践,重点关注联邦学习的通信轮次设计、模型聚合算法(如FedAvg)的实现细节以及差分隐私噪声添加策略,深入理解其对模型性能与隐私强度的影响,为进一步优化与创新奠定基础。
VDA_Band_19.1_3rd edition_2026 English Inspection of Technical Cleanliness 内容概要:本文档为德国汽车工业协会(VDA)发布的第三版《技术清洁度检验:功能相关汽车部件的颗粒污染检测》(VDA 19.1),系统规范了汽车行业中零部件技术清洁度的检测方法与流程。文件涵盖从取样、提取、过滤到分析的全流程标准化操作,重点更新了干法提取(如 Stamp Test 和刷吸法)、小于50µm颗粒的检测、光学子系统和SEM/EDX标准分析方法,并引入统一材料分类体系以提升结果可比性。同时明确了“标准分析”与“自由检验”的区别,前者用于高兼容性检测,后者允许客户与供应商协商定制参数。文档还强化了对非可测组件的技术清洁保障、测量不确定度评估及方法验证的要求,并提供了多个实际案例支持应用落地。; 适合人群:适用于汽车制造业中从事质量控制、工艺开发、供应商管理及相关检测实验室的技术人员和管理人员,尤其适合具备一定质量管理或洁净度检测基础的专业人员。; 使用场景及目标:①用于制定和执行零部件清洁度检测标准;②指导 incoming/outgoing 检验及生产过程监控;③支持失效分析与质量改进项目;④作为企业内部审核和技术交流的依据; 阅读建议:建议结合VDA 19.2及其他相关标准配套使用,重点关注各章节中的起始参数设定、方法选择逻辑及附录中的检查表示例,在实际操作中同步开展方法验证与人员培训,确保检测结果的有效性和可追溯性。
内容概要:本研究聚焦于电动汽车(EV)作为灵活可调资源的能力评估,提出了一种基于多面体聚合与闵可夫斯基和的数学建模方法,用以精确刻画大规模电动汽车集群的可调能力范围。通过将单辆电动汽车的充放电行为抽象为几何空间中的多面体可行域,并利用闵可夫斯基和实现对群体可行域的高效聚合,从而构建出能够反映整体调节潜力的统一数学表达。该方法在Matlab平台上实现了完整的仿真代码,支持对不同场景下电动汽车集群的上、下调能力进行量化评估,为电网调度、需求响应及电力市场机制设计提供了理论依据与工具支撑。; 适合人群:具备电力系统分析、优化理论及Matlab编程基础的研究生、科研人员及从事新能源、智能电网相关工作的工程师。; 使用场景及目标:①用于评估大规模电动汽车接入背景下系统的灵活性资源潜力;②支撑含高比例可再生能源的电力系统调度与规划决策;③为需求响应项目中EV聚合商参与电力市场提供能力申报的技术手段;④作为教学案例帮助理解集合运算在电力系统中的应用。; 阅读建议:学习者应结合Matlab代码深入理解多面体建模与闵可夫斯基和的实现细节,建议从单车模型入手逐步过渡到集群聚合,并尝试调整参数(如数量、SOC分布、功率限制)观察聚合结果的变化,以增强对模型特性的掌握。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值