当前位置: 首页 > news >正文

电子商务网站建设的安全性珠海网站建设网

电子商务网站建设的安全性,珠海网站建设网,公司章程范本,上海工程相关的公司文章目录 1. 字符串相关类之不可变字符序列#xff1a;String1.1 String的特性1.2 String的内存结构1.2.1 概述1.2.2 练习类型1#xff1a;拼接1.2.3 练习类型2#xff1a;new1.2.4 练习类型3#xff1a;intern() 1.3 String的常用API-11.3.1 构造器1.3.2 字符串对象的比较… 文章目录 1. 字符串相关类之不可变字符序列String1.1 String的特性1.2 String的内存结构1.2.1 概述1.2.2 练习类型1拼接1.2.3 练习类型2new1.2.4 练习类型3intern() 1.3 String的常用API-11.3.1 构造器1.3.2 字符串对象的比较1.3.3 空字符的比较1.3.4 String与其他结构间的转换 1.4 String的常用API-21.4.1 系列1常用方法1.4.2 系列2查找1.4.3 系列3字符串截取1.4.4 系列4和字符/字符数组相关1.4.5 系列5开头与结尾1.4.6 系列6替换1.4.7 系列7正则匹配1.4.8 系列8拆分 1.5 常见算法题目 2. 字符串相关类之可变字符序列StringBuffer、StringBuilder2.1 StringBuffer与StringBuilder的理解2.2 StringBuilder、StringBuffer的API2.3 效率测试 3. JDK8之前日期时间API3.1 java.lang.System类的方法3.2 java.util.Date3.3 java.text.SimpleDateFormat3.4 java.util.Calendar(日历) 4. JDK8新的日期时间API4.1 本地日期时间LocalDate、LocalTime、LocalDateTime4.2 瞬时Instant4.3 日期时间格式化DateTimeFormatter4.4 其它API4.5 与传统日期处理的转换 5. Java比较器5.1 自然排序java.lang.Comparable5.2 定制排序java.util.Comparator 6. 系统相关类6.1 java.lang.System类6.2 java.lang.Runtime类 7. 和数学相关的类7.1 java.lang.Math7.2 java.math包7.2.1 BigInteger7.2.2 BigDecimal7.2.3 RoundingMode枚举类 7.3 java.util.Random 1. 字符串相关类之不可变字符序列String 1.1 String的特性 java.lang.String 类代表字符串。Java程序中所有的字符串文字例如hello 都可以看作是实现此类的实例。 字符串是常量用双引号引起来表示。它们的值在创建之后不能更改。 字符串String类型本身是final声明的意味着我们不能继承String。 String对象的字符内容是存储在一个字符数组value[]中的。abc 等效于 char[] data{h,e,l,l,o}。 //jdk8中的String源码 public final class Stringimplements java.io.Serializable, ComparableString, CharSequence {/** The value is used for character storage. */private final char value[]; //String对象的字符内容是存储在此数组中/** Cache the hash code for the string */private int hash; // Default to 0 private意味着外面无法直接获取字符数组而且String没有提供value的get和set方法。 final意味着字符数组的引用不可改变而且String也没有提供方法来修改value数组某个元素值 因此字符串的字符数组内容也不可变的即String代表着不可变的字符序列。即一旦对字符串进行修改就会产生新对象。 JDK9只有底层使用byte[]数组。 public final class String implements java.io.Serializable, ComparableString, CharSequence { Stableprivate final byte[] value; }//官方说明... that most String objects contain only Latin-1 characters. Such characters require only one byte of storage, hence half of the space in the internal char arrays of such String objects is going unused.//细节... The new String class will store characters encoded either as ISO-8859-1/Latin-1 (one byte per character), or as UTF-16 (two bytes per character), based upon the contents of the string. The encoding flag will indicate which encoding is used.Java 语言提供对字符串串联符号“”以及将其他对象转换为字符串的特殊支持toString()方法。 1.2 String的内存结构 1.2.1 概述 因为字符串对象设计为不可变那么所以字符串有常量池来保存很多常量对象。 JDK6中字符串常量池在方法区。JDK7开始就移到堆空间直到目前JDK17版本。举例内存结构分配 1.2.2 练习类型1拼接 String s1 hello; String s2 hello; System.out.println(s1 s2); // 内存中只有一个hello对象被创建同时被s1和s2共享。对应内存结构为以下内存结构以JDK6为例绘制 进一步 Person p1 new Person(); p1.name “Tom;Person p2 new Person(); p2.name “Tom;System.out.println(p1.name .equals( p2.name)); // System.out.println(p1.name p2.name); // System.out.println(p1.name “Tom); //1.2.3 练习类型2new String str1 “abc”; 与 String str2 new String(“abc”);的区别 str2 首先指向堆中的一个字符串对象然后堆中字符串的value数组指向常量池中常量对象的value数组。 字符串常量存储在字符串常量池目的是共享。 字符串非常量对象存储在堆中。 练习 String s1 javaEE; String s2 javaEE; String s3 new String(javaEE); String s4 new String(javaEE);System.out.println(s1 s2);//true System.out.println(s1 s3);//false System.out.println(s1 s4);//false System.out.println(s3 s4);//false练习String str2 new String(“hello”); 在内存中创建了几个对象 两个1.2.4 练习类型3intern() String s1 “a”; 说明在字符串常量池中创建了一个字面量为a的字符串。 s1 s1 “b”; 说明实际上原来的“a”字符串对象已经丢弃了现在在堆空间中产生了一个字符串s1“b”也就是ab)。如果多次执行这些改变串内容的操作会导致大量副本字符串对象存留在内存中降低效率。如果这样的操作放到循环中会极大影响程序的性能。 String s2 “ab”; 说明直接在字符串常量池中创建一个字面量为ab的字符串。 String s3 “a” “b”; 说明s3指向字符串常量池中已经创建的ab的字符串。 String s4 s1.intern(); 说明堆空间的s1对象在调用intern()之后会将常量池中已经存在的ab字符串赋值给s4。 练习 String s1 hello; String s2 world; String s3 hello world; String s4 s1 world; String s5 s1 s2; String s6 (s1 s2).intern();System.out.println(s3 s4); System.out.println(s3 s5); System.out.println(s4 s5); System.out.println(s3 s6);结论 1常量常量结果是常量池。且常量池中不会存在相同内容的常量。 2常量与变量 或 变量与变量结果在堆中 3拼接后调用intern方法返回值在常量池中 练习 Test public void test01(){String s1 hello;String s2 world;String s3 helloworld;String s4 s1 world;//s4字符串内容也helloworlds1是变量world常量变量 常量的结果在堆中String s5 s1 s2;//s5字符串内容也helloworlds1和s2都是变量变量 变量的结果在堆中String s6 hello world;//常量 常量 结果在常量池中因为编译期间就可以确定结果System.out.println(s3 s4);//falseSystem.out.println(s3 s5);//falseSystem.out.println(s3 s6);//true }Test public void test02(){final String s1 hello;final String s2 world;String s3 helloworld;String s4 s1 world;//s4字符串内容也helloworlds1是常量world常量常量常量结果在常量池中String s5 s1 s2;//s5字符串内容也helloworlds1和s2都是常量常量 常量 结果在常量池中String s6 hello world;//常量 常量 结果在常量池中因为编译期间就可以确定结果System.out.println(s3 s4);//trueSystem.out.println(s3 s5);//trueSystem.out.println(s3 s6);//true }Test public void test01(){String s1 hello;String s2 world;String s3 helloworld;String s4 (s1 world).intern();//把拼接的结果放到常量池中String s5 (s1 s2).intern();System.out.println(s3 s4);//trueSystem.out.println(s3 s5);//true }练习下列程序运行的结果 public class TestString {public static void main(String[] args) {String str hello;String str2 world;String str3 helloworld;String str4 hello.concat(world);String str5 helloworld;System.out.println(str3 str4);//falseSystem.out.println(str3 str5);//true} }concat方法拼接哪怕是两个常量对象拼接结果也是在堆。 练习下列程序运行的结果 public class StringTest {String str new String(good);char[] ch { t, e, s, t };public void change(String str, char ch[]) {str test ok;ch[0] b;}public static void main(String[] args) {StringTest ex new StringTest();ex.change(ex.str, ex.ch);System.out.print(ex.str and );//System.out.println(ex.ch);} } 1.3 String的常用API-1 1.3.1 构造器 public String() 初始化新创建的 String对象以使其表示空字符序列。 String(String original) 初始化一个新创建的 String 对象使其表示一个与参数相同的字符序列换句话说新创建的字符串是该参数字符串的副本。public String(char[] value) 通过当前参数中的字符数组来构造新的String。public String(char[] value,int offset, int count) 通过字符数组的一部分来构造新的String。public String(byte[] bytes) 通过使用平台的默认字符集解码当前参数中的字节数组来构造新的String。public String(byte[] bytes,String charsetName) 通过使用指定的字符集解码当前参数中的字节数组来构造新的String。 举例 //字面量定义方式字符串常量对象 String str hello;//构造器定义方式无参构造 String str1 new String();//构造器定义方式创建hello字符串常量的副本 String str2 new String(hello);//构造器定义方式通过字符数组构造 char chars[] {a, b, c,d,e}; String str3 new String(chars); String str4 new String(chars,0,3);//构造器定义方式通过字节数组构造 byte bytes[] {97, 98, 99 }; String str5 new String(bytes); String str6 new String(bytes,GBK);public static void main(String[] args) {char[] data {h,e,l,l,o,j,a,v,a};String s1 String.copyValueOf(data);String s2 String.copyValueOf(data,0,5);int num 123456;String s3 String.valueOf(num);System.out.println(s1);System.out.println(s2);System.out.println(s3); }1.3.2 字符串对象的比较 1、比较是对象的地址 只有两个字符串变量都是指向字符串的常量对象时才会返回true String str1 hello; String str2 hello; System.out.println(str1 str2);//trueString str3 new String(hello); String str4 new String(hello); System.out.println(str1 str4); //false System.out.println(str3 str4); //false2、equals比较的是对象的内容因为String类型重写equals区分大小写 只要两个字符串的字符内容相同就会返回true String str1 hello; String str2 hello; System.out.println(str1.equals(str2));//trueString str3 new String(hello); String str4 new String(hello); System.out.println(str1.equals(str3));//true System.out.println(str3.equals(str4));//true3、equalsIgnoreCase比较的是对象的内容不区分大小写 String str1 new String(hello); String str2 new String(HELLo); System.out.println(str1.equalsIgnoreCase(strs)); //true4、compareToString类型重写了Comparable接口的抽象方法自然排序按照字符的Unicode编码值进行比较大小的严格区分大小写 String str1 hello; String str2 world; str1.compareTo(str2) //小于0的值5、compareToIgnoreCase不区分大小写其他按照字符的Unicode编码值进行比较大小 String str1 new String(hello); String str2 new String(HELLO); str1.compareToIgnoreCase(str2) //等于01.3.3 空字符的比较 1、哪些是空字符串 String str1 ; String str2 new String(); String str3 new String();空字符串长度为0 2、如何判断某个字符串是否是空字符串 if(.equals(str))if(str!null str.isEmpty())if(str!null str.equals())if(str!null str.length()0)1.3.4 String与其他结构间的转换 字符串 -- 基本数据类型、包装类 Integer包装类的public static int parseInt(String s)可以将由“数字”字符组成的字符串转换为整型。类似地使用java.lang包中的Byte、Short、Long、Float、Double类调相应的类方法可以将由“数字”字符组成的字符串转化为相应的基本数据类型。 基本数据类型、包装类 -- 字符串 调用String类的public String valueOf(int n)可将int型转换为字符串相应的valueOf(byte b)、valueOf(long l)、valueOf(float f)、valueOf(double d)、valueOf(boolean b)可由参数的相应类型到字符串的转换。 字符数组 -- 字符串 String 类的构造器String(char[]) 和 String(char[]int offsetint length) 分别用字符数组中的全部字符和部分字符创建字符串对象。 字符串 -- 字符数组 public char[] toCharArray()将字符串中的全部字符存放在一个字符数组中的方法。 public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)提供了将指定索引范围内的字符串存放到数组中的方法。 字节数组 -- 字符串解码 String(byte[])通过使用平台的默认字符集解码指定的 byte 数组构造一个新的 String。String(byte[]int offsetint length) 用指定的字节数组的一部分即从数组起始位置offset开始取length个字节构造一个字符串对象。String(byte[]字符编码方式 ) 或 new String(byte[], int, int字符编码方式)解码按照指定的编码方式进行解码。 字符串 -- 字节数组编码 public byte[] getBytes() 使用平台的默认字符集将此 String 编码为 byte 序列并将结果存储到一个新的 byte 数组中。public byte[] getBytes(String charsetName) 使用指定的字符集将此 String 编码到 byte 序列并将结果存储到新的 byte 数组。 代码示例 Testpublic void test01() throws Exception {String str 中国;System.out.println(str.getBytes(ISO8859-1).length);// 2// ISO8859-1把所有的字符都当做一个byte处理处理不了多个字节System.out.println(str.getBytes(GBK).length);// 4 每一个中文都是对应2个字节System.out.println(str.getBytes(UTF-8).length);// 6 常规的中文都是3个字节/** 不乱码1保证编码与解码的字符集名称一样2不缺字节*/System.out.println(new String(str.getBytes(ISO8859-1), ISO8859-1));// 乱码System.out.println(new String(str.getBytes(GBK), GBK));// 中国System.out.println(new String(str.getBytes(UTF-8), UTF-8));// 中国}Testpublic void test02()throws Exception{byte[] data {(byte)0B11100101, (byte)0B10110000, (byte)0B10011010, (byte)0B11000111, (byte)0B10101011,(byte)0B01110110};System.out.println(new String(data,ISO8859-1));System.out.println(new String(data,GBK));System.out.println(new String(data,UTF-8));}1.4 String的常用API-2 String 类包括的方法可用于检查序列的单个字符、比较字符串、搜索字符串、提取子字符串、创建字符串副本并将所有字符全部转换为大写或小写。 1.4.1 系列1常用方法 1boolean isEmpty()字符串是否为空 2int length()返回字符串的长度 3String concat(xx)拼接 4boolean equals(Object obj)比较字符串是否相等区分大小写 5boolean equalsIgnoreCase(Object obj)比较字符串是否相等不区分大小写 6int compareTo(String other)比较字符串大小区分大小写按照Unicode编码值比较大小 7int compareToIgnoreCase(String other)比较字符串大小不区分大小写 8String toLowerCase()将字符串中大写字母转为小写 9String toUpperCase()将字符串中小写字母转为大写 10String trim()去掉字符串前后空白符 11public String intern()结果在常量池中共享 Testpublic void test01(){//将用户输入的单词全部转为小写如果用户没有输入单词重新输入Scanner input new Scanner(System.in);String word;while(true){System.out.print(请输入单词);word input.nextLine();if(word.trim().length()!0){word word.toLowerCase();break;}}System.out.println(word);}Testpublic void test02(){//随机生成验证码验证码由0-9A-Z,a-z的字符组成char[] array new char[26*210];for (int i 0; i 10; i) {array[i] (char)(0 i);}for (int i 10,j0; i 1026; i,j) {array[i] (char)(A j);}for (int i 1026,j0; i array.length; i,j) {array[i] (char)(a j);}String code ;Random rand new Random();for (int i 0; i 4; i) {code array[rand.nextInt(array.length)];}System.out.println(验证码 code);//将用户输入的单词全部转为小写如果用户没有输入单词重新输入Scanner input new Scanner(System.in);System.out.print(请输入验证码);String inputCode input.nextLine();if(!code.equalsIgnoreCase(inputCode)){System.out.println(验证码输入不正确);}}1.4.2 系列2查找 11boolean contains(xx)是否包含xx 12int indexOf(xx)从前往后找当前字符串中xx即如果有返回第一次出现的下标要是没有返回-1 13int indexOf(String str, int fromIndex)返回指定子字符串在此字符串中第一次出现处的索引从指定的索引开始 14int lastIndexOf(xx)从后往前找当前字符串中xx即如果有返回最后一次出现的下标要是没有返回-1 15int lastIndexOf(String str, int fromIndex)返回指定子字符串在此字符串中最后一次出现处的索引从指定的索引开始反向搜索。 Testpublic void test01(){String str 尚硅谷是一家靠谱的培训机构尚硅谷可以说是IT培训的小清华JavaEE是尚硅谷的当家学科尚硅谷的大数据培训是行业独角兽。尚硅谷的前端和UI专业一样独领风骚。;System.out.println(是否包含清华 str.contains(清华));System.out.println(培训出现的第一次下标 str.indexOf(培训));System.out.println(培训出现的最后一次下标 str.lastIndexOf(培训));}1.4.3 系列3字符串截取 16String substring(int beginIndex) 返回一个新的字符串它是此字符串的从beginIndex开始截取到最后的一个子字符串。 17String substring(int beginIndex, int endIndex) 返回一个新字符串它是此字符串从beginIndex开始截取到endIndex(不包含)的一个子字符串。 Testpublic void test01(){String str helloworldjavaatguigu;String sub1 str.substring(5);String sub2 str.substring(5,10);System.out.println(sub1);System.out.println(sub2);}Testpublic void test02(){String fileName 快速学习Java的秘诀.dat;//截取文件名System.out.println(文件名 fileName.substring(0,fileName.lastIndexOf(.)));//截取后缀名System.out.println(后缀名 fileName.substring(fileName.lastIndexOf(.)));}1.4.4 系列4和字符/字符数组相关 18char charAt(index)返回[index]位置的字符 19char[] toCharArray() 将此字符串转换为一个新的字符数组返回 20static String valueOf(char[] data) 返回指定数组中表示该字符序列的 String 21static String valueOf(char[] data, int offset, int count) 返回指定数组中表示该字符序列的 String 22static String copyValueOf(char[] data) 返回指定数组中表示该字符序列的 String 23static String copyValueOf(char[] data, int offset, int count)返回指定数组中表示该字符序列的 String Testpublic void test01(){//将字符串中的字符按照大小顺序排列String str helloworldjavaatguigu;char[] array str.toCharArray();Arrays.sort(array);str new String(array);System.out.println(str);}Testpublic void test02(){//将首字母转为大写String str jack;str Character.toUpperCase(str.charAt(0))str.substring(1);System.out.println(str);}Testpublic void test03(){char[] data {h,e,l,l,o,j,a,v,a};String s1 String.copyValueOf(data);String s2 String.copyValueOf(data,0,5);int num 123456;String s3 String.valueOf(num);System.out.println(s1);System.out.println(s2);System.out.println(s3);}1.4.5 系列5开头与结尾 24boolean startsWith(xx)测试此字符串是否以指定的前缀开始 25boolean startsWith(String prefix, int toffset)测试此字符串从指定索引开始的子字符串是否以指定前缀开始 26boolean endsWith(xx)测试此字符串是否以指定的后缀结束 Testpublic void test1(){String name 张三;System.out.println(name.startsWith(张));}Testpublic void test2(){String file Hello.txt;if(file.endsWith(.java)){System.out.println(Java源文件);}else if(file.endsWith(.class)){System.out.println(Java字节码文件);}else{System.out.println(其他文件);}}1.4.6 系列6替换 27String replace(char oldChar, char newChar)返回一个新的字符串它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的。 不支持正则。 28String replace(CharSequence target, CharSequence replacement)使用指定的字面值替换序列替换此字符串所有匹配字面值目标序列的子字符串。 29String replaceAll(String regex, String replacement)使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。 30String replaceFirst(String regex, String replacement)使用给定的 replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。 Test public void test1(){String str1 hello244world.java;887;//把其中的非字母去掉str1 str1.replaceAll([^a-zA-Z], );System.out.println(str1);String str2 12hello34world5java7891mysql456;//把字符串中的数字替换成,如果结果中开头和结尾有的话去掉String string str2.replaceAll(\\d, ,).replaceAll(^,|,$, );System.out.println(string);}1.4.7 系列7正则匹配 31boolean matchs(正则表达式)判断当前字符串是否匹配某个正则表达式。 Test public void test1(){//简单判断是否全部是数字这个数字可以是1~n位String str 12a345;//正则不是Java的语法它是独立与Java的规则//在正则中\是表示转义//同时在Java中\也是转义boolean flag str.matches(\\d);System.out.println(flag); }Test public void test2(){String str 123456789;//判断它是否全部由数字组成并且第1位不能是0长度为9位//第一位不能是0那么数字[1-9]//接下来8位的数字那么[0-9]{8}boolean flag str.matches([1-9][0-9]{8});System.out.println(flag); }Test public void test3(){//密码要求必须有大写字母小写字母数字组成6位System.out.println(Cly892.matches(^(?.*[A-Z])(?.*[a-z])(?.*[0-9])[A-Za-z0-9]{6}$));//trueSystem.out.println(1A2c45.matches(^(?.*[A-Z])(?.*[a-z])(?.*[0-9])[A-Za-z0-9]{6}$));//trueSystem.out.println(Clyyyy.matches(^(?.*[A-Z])(?.*[0-9])[A-Za-z0-9]{6}$));//false/*1密码的长度为6且只能有[A-Za-z0-9]组成。2另外三个非捕获组都能匹配到自己的值。(?.*[A-Z])匹配值 C(?.*[a-z])匹配值 Clyya(?.*[0-9])匹配值 Clyya1三个非捕获组都有值。*/ }1.4.8 系列8拆分 32String[] split(String regex)根据给定正则表达式的匹配拆分此字符串。 33String[] split(String regex, int limit)根据匹配给定的正则表达式来拆分此字符串最多不超过limit个如果超过了剩下的全部都放到最后一个元素中。 Testpublic void test1(){String str Hello World java atguigu;String[] all str.split( );for (int i 0; i all.length; i) {System.out.println(all[i]);}} Testpublic void test2(){String str 1Hello2World3java4atguigu;str str.replaceFirst(\\d, );System.out.println(str);String[] all str.split(\\d);for (int i 0; i all.length; i) {System.out.println(all[i]);}}Testpublic void test3(){String str 1Hello2World3java4atguigu5;str str.replaceAll(^\\d|\\d$, );String[] all str.split(\\d);for (int i 0; i all.length; i) {System.out.println(all[i]);}}Testpublic void test4(){String str 张三.23|李四.24|王五.25;//|在正则中是有特殊意义我这里要把它当做普通的|String[] all str.split(\\|);//转成一个一个学生对象Student[] students new Student[all.length];for (int i 0; i students.length; i) {//.在正则中是特殊意义我这里想要表示普通的.String[] strings all[i].split(\\.);//张三, 23String name strings[0];int age Integer.parseInt(strings[1]);students[i] new Student(name,age);}for (int i 0; i students.length; i) {System.out.println(students[i]);} }1.5 常见算法题目 **题目1**模拟一个trim方法去除字符串两端的空格。 public String myTrim(String str) {if (str ! null) {int start 0;// 用于记录从前往后首次索引位置不是空格的位置的索引int end str.length() - 1;// 用于记录从后往前首次索引位置不是空格的位置的索引while (start end str.charAt(start) ) {start;}while (start end str.charAt(end) ) {end--;}if (str.charAt(start) ) {return ;}return str.substring(start, end 1);}return null;}Testpublic void testMyTrim() {String str a ;// str ;String newStr myTrim(str);System.out.println(--- newStr ---);}**题目2**将一个字符串进行反转。将字符串中指定部分进行反转。比如“abcdefg”反转为”abfedcg” // 方式一public String reverse1(String str, int start, int end) {// start:2,end:5if (str ! null) {// 1.char[] charArray str.toCharArray();// 2.for (int i start, j end; i j; i, j--) {char temp charArray[i];charArray[i] charArray[j];charArray[j] temp;}// 3.return new String(charArray);}return null;}// 方式二public String reverse2(String str, int start, int end) {// 1.String newStr str.substring(0, start);// ab// 2.for (int i end; i start; i--) {newStr str.charAt(i);} // abfedc// 3.newStr str.substring(end 1);return newStr;}// 方式三推荐 相较于方式二做的改进public String reverse3(String str, int start, int end) {// ArrayList list new ArrayList(80);// 1.StringBuffer s new StringBuffer(str.length());// 2.s.append(str.substring(0, start));// ab// 3.for (int i end; i start; i--) {s.append(str.charAt(i));}// 4.s.append(str.substring(end 1));// 5.return s.toString();}Testpublic void testReverse() {String str abcdefg;String str1 reverse3(str, 2, 5);System.out.println(str1);// abfedcg}**题目3**获取一个字符串在另一个字符串中出现的次数。 比如获取“ ab”在 “abkkcadkabkebfkabkskab” 中出现的次数 // 第3题// 判断str2在str1中出现的次数public int getCount(String mainStr, String subStr) {if (mainStr.length() subStr.length()) {int count 0;int index 0;// while((index mainStr.indexOf(subStr)) ! -1){// count;// mainStr mainStr.substring(index subStr.length());// }// 改进while ((index mainStr.indexOf(subStr, index)) ! -1) {index subStr.length();count;}return count;} else {return 0;}}Testpublic void testGetCount() {String str1 cdabkkcadkabkebfkabkskab;String str2 ab;int count getCount(str1, str2);System.out.println(count);}**题目4**获取两个字符串中最大相同子串。比如 str1 abcwerthelloyuiodef“;str2 “cvhellobnm” 提示将短的那个串进行长度依次递减的子串与较长的串比较。 // 第4题// 如果只存在一个最大长度的相同子串public String getMaxSameSubString(String str1, String str2) {if (str1 ! null str2 ! null) {String maxStr (str1.length() str2.length()) ? str1 : str2;String minStr (str1.length() str2.length()) ? str2 : str1;int len minStr.length();for (int i 0; i len; i) {// 0 1 2 3 4 此层循环决定要去几个字符for (int x 0, y len - i; y len; x, y) {if (maxStr.contains(minStr.substring(x, y))) {return minStr.substring(x, y);}}}}return null;}// 如果存在多个长度相同的最大相同子串// 此时先返回String[]后面可以用集合中的ArrayList替换较方便public String[] getMaxSameSubString1(String str1, String str2) {if (str1 ! null str2 ! null) {StringBuffer sBuffer new StringBuffer();String maxString (str1.length() str2.length()) ? str1 : str2;String minString (str1.length() str2.length()) ? str2 : str1;int len minString.length();for (int i 0; i len; i) {for (int x 0, y len - i; y len; x, y) {String subString minString.substring(x, y);if (maxString.contains(subString)) {sBuffer.append(subString ,);}}System.out.println(sBuffer);if (sBuffer.length() ! 0) {break;}}String[] split sBuffer.toString().replaceAll(,$, ).split(\\,);return split;}return null;}// 如果存在多个长度相同的最大相同子串使用ArrayList // public ListString getMaxSameSubString1(String str1, String str2) { // if (str1 ! null str2 ! null) { // ListString list new ArrayListString(); // String maxString (str1.length() str2.length()) ? str1 : str2; // String minString (str1.length() str2.length()) ? str2 : str1; // // int len minString.length(); // for (int i 0; i len; i) { // for (int x 0, y len - i; y len; x, y) { // String subString minString.substring(x, y); // if (maxString.contains(subString)) { // list.add(subString); // } // } // if (list.size() ! 0) { // break; // } // } // return list; // } // // return null; // }Testpublic void testGetMaxSameSubString() {String str1 abcwerthelloyuiodef;String str2 cvhellobnmiodef;String[] strs getMaxSameSubString1(str1, str2);System.out.println(Arrays.toString(strs));}**题目5**对字符串中字符进行自然顺序排序。 提示 1字符串变成字符数组。 2对数组排序选择冒泡Arrays.sort(); 3将排序后的数组变成字符串。 // 第5题Testpublic void testSort() {String str abcwerthelloyuiodef;char[] arr str.toCharArray();Arrays.sort(arr);String newStr new String(arr);System.out.println(newStr);}2. 字符串相关类之可变字符序列StringBuffer、StringBuilder 因为String对象是不可变对象虽然可以共享常量对象但是对于频繁字符串的修改和拼接操作效率极低空间消耗也比较高。因此JDK又在java.lang包提供了可变字符序列StringBuilder和StringBuffer类型。 2.1 StringBuffer与StringBuilder的理解 java.lang.StringBuffer代表可变的字符序列JDK1.0中声明可以对字符串内容进行增删此时不会产生新的对象。比如 //情况1: String s new String(我喜欢学习); //情况2 StringBuffer buffer new StringBuffer(我喜欢学习); buffer.append(数学); 继承结构 StringBuilder 和 StringBuffer 非常类似均代表可变的字符序列而且提供相关功能的方法也一样。区分String、StringBuffer、StringBuilder String:不可变的字符序列 底层使用char[]数组存储(JDK8.0中)StringBuffer:可变的字符序列线程安全方法有synchronized修饰效率低底层使用char[]数组存储 (JDK8.0中)StringBuilder:可变的字符序列 jdk1.5引入线程不安全的效率高底层使用char[]数组存储(JDK8.0中) 2.2 StringBuilder、StringBuffer的API StringBuilder、StringBuffer的API是完全一致的并且很多方法与String相同。 1、常用API 1StringBuffer append(xx)提供了很多的append()方法用于进行字符串追加的方式拼接 2StringBuffer delete(int start, int end)删除[start,end)之间字符 3StringBuffer deleteCharAt(int index)删除[index]位置字符 4StringBuffer replace(int start, int end, String str)替换[start,end)范围的字符序列为str 5void setCharAt(int index, xx)替换[index]位置字符 6char charAt(int index)查找指定index位置上的字符 7StringBuffer insert(int index, xx)在[index]位置插入xx 8int length()返回存储的字符数据的长度 9StringBuffer reverse()反转 当append和insert时如果原来value数组长度不够可扩容。 如上(1)(2)(3)(4)(9)这些方法支持方法链操作。原理 2、其它API 1int indexOf(String str)在当前字符序列中查询str的第一次出现下标 2int indexOf(String str, int fromIndex)在当前字符序列[fromIndex,最后]中查询str的第一次出现下标 3int lastIndexOf(String str)在当前字符序列中查询str的最后一次出现下标 4int lastIndexOf(String str, int fromIndex)在当前字符序列[fromIndex,最后]中查询str的最后一次出现下标 5String substring(int start)截取当前字符序列[start,最后] 6String substring(int start, int end)截取当前字符序列[start,end) 7String toString()返回此序列中数据的字符串表示形式 8void setLength(int newLength) 设置当前字符序列长度为newLength Testpublic void test1(){StringBuilder s new StringBuilder();s.append(hello).append(true).append(a).append(12).append(atguigu);System.out.println(s);System.out.println(s.length());}Testpublic void test2(){StringBuilder s new StringBuilder(helloworld);s.insert(5, java);s.insert(5, chailinyan);System.out.println(s);}Testpublic void test3(){StringBuilder s new StringBuilder(helloworld);s.delete(1, 3);s.deleteCharAt(4);System.out.println(s);}Testpublic void test4(){StringBuilder s new StringBuilder(helloworld);s.reverse();System.out.println(s);}Testpublic void test5(){StringBuilder s new StringBuilder(helloworld);s.setCharAt(2, a);System.out.println(s);}Testpublic void test6(){StringBuilder s new StringBuilder(helloworld);s.setLength(30);System.out.println(s);}2.3 效率测试 //初始设置 long startTime 0L; long endTime 0L; String text ; StringBuffer buffer new StringBuffer(); StringBuilder builder new StringBuilder();//开始对比 startTime System.currentTimeMillis(); for (int i 0; i 20000; i) {buffer.append(String.valueOf(i)); } endTime System.currentTimeMillis(); System.out.println(StringBuffer的执行时间 (endTime - startTime));startTime System.currentTimeMillis(); for (int i 0; i 20000; i) {builder.append(String.valueOf(i)); } endTime System.currentTimeMillis(); System.out.println(StringBuilder的执行时间 (endTime - startTime));startTime System.currentTimeMillis(); for (int i 0; i 20000; i) {text text i; } endTime System.currentTimeMillis(); System.out.println(String的执行时间 (endTime - startTime)); 3. JDK8之前日期时间API 3.1 java.lang.System类的方法 System类提供的public static long currentTimeMillis()用来返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差。 此方法适于计算时间差。 计算世界时间的主要标准有 UTC(Coordinated Universal Time)GMT(Greenwich Mean Time)CST(Central Standard Time) 在国际无线电通信场合为了统一起见使用一个统一的时间称为通用协调时(UTC, Universal Time Coordinated)。UTC与格林尼治平均时(GMT, Greenwich Mean Time)一样都与英国伦敦的本地时相同。这里UTC与GMT含义完全相同。 3.2 java.util.Date 表示特定的瞬间精确到毫秒。 构造器 Date()使用无参构造器创建的对象可以获取本地当前时间。Date(long 毫秒数)把该毫秒值换算成日期时间对象 常用方法 getTime(): 返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。toString(): 把此 Date 对象转换为以下形式的 String dow mon dd hh:mm:ss zzz yyyy 其中 dow 是一周中的某一天 (Sun, Mon, Tue, Wed, Thu, Fri, Sat)zzz是时间标准。其它很多方法都过时了。 举例 Testpublic void test1(){Date d new Date();System.out.println(d);}Testpublic void test2(){long time System.currentTimeMillis();System.out.println(time);//1559806982971//当前系统时间距离1970-1-1 0:0:0 0毫秒的时间差毫秒为单位}Testpublic void test3(){Date d new Date();long time d.getTime();System.out.println(time);//1559807047979}Testpublic void test4(){long time 1559807047979L;Date d new Date(time);System.out.println(d);}Testpublic void test5(){long time Long.MAX_VALUE;Date d new Date(time);System.out.println(d);}3.3 java.text.SimpleDateFormat Date类的API不易于国际化大部分被废弃了java.text.SimpleDateFormat类是一个不与语言环境有关的方式来格式化和解析日期的具体类。 可以进行格式化日期 -- 文本 可以进行解析文本 -- 日期 格式化 SimpleDateFormat() 默认的模式和语言环境创建对象public SimpleDateFormat(String pattern)该构造方法可以用参数pattern指定的格式创建一个对象该对象调用public String format(Date date)方法格式化时间对象date 解析 public Date parse(String source)从给定字符串的开始解析文本以生成一个日期。 //格式化Testpublic void test9(){Date d new Date();SimpleDateFormat sf new SimpleDateFormat(yyyy年MM月dd日 HH时mm分ss秒 SSS毫秒 E Z);//把Date日期转成字符串按照指定的格式转String str sf.format(d);System.out.println(str);}//解析Testpublic void test10() throws ParseException{String str 2022年06月06日 16时03分14秒 545毫秒 星期四 0800;SimpleDateFormat sf new SimpleDateFormat(yyyy年MM月dd日 HH时mm分ss秒 SSS毫秒 E Z);Date d sf.parse(str);System.out.println(d);} 3.4 java.util.Calendar(日历) Calendar 类是一个抽象类主用用于完成日期字段之间相互操作的功能。 获取Calendar实例的方法 使用Calendar.getInstance()方法 调用它的子类GregorianCalendar公历的构造器。 一个Calendar的实例是系统时间的抽象表示可以修改或获取 YEAR、MONTH、DAY_OF_WEEK、HOUR_OF_DAY 、MINUTE、SECOND等 日历字段对应的时间值。 public void set(int field,int value) 将给定的日历字段设置为指定的值public int get(int field)返回给定日历字段的值public void add(int field,int amount)根据日历的规则为给定的日历字段添加或者减去指定的时间量public final Date getTime()将Calendar转成Date对象public final void setTime(Date date)使用指定的Date对象重置Calendar的时间 常用字段 注意 获取月份时一月是0二月是1以此类推12月是11获取星期时周日是1周二是2 。。。。周六是7 示例代码 import org.junit.Test;import java.util.Calendar; import java.util.TimeZone;public class TestCalendar {Testpublic void test1(){Calendar c Calendar.getInstance();System.out.println(c);int year c.get(Calendar.YEAR);int month c.get(Calendar.MONTH)1;int day c.get(Calendar.DATE);int hour c.get(Calendar.HOUR_OF_DAY);int minute c.get(Calendar.MINUTE);System.out.println(year - month - day hour : minute);}Testpublic void test2(){TimeZone t TimeZone.getTimeZone(America/Los_Angeles);Calendar c Calendar.getInstance(t);int year c.get(Calendar.YEAR);int month c.get(Calendar.MONTH)1;int day c.get(Calendar.DATE);int hour c.get(Calendar.HOUR_OF_DAY);int minute c.get(Calendar.MINUTE);System.out.println(year - month - day hour : minute);}Testpublic void test3(){Calendar calendar Calendar.getInstance();// 从一个 Calendar 对象中获取 Date 对象Date date calendar.getTime();// 使用给定的 Date 设置此 Calendar 的时间date new Date(234234235235L);calendar.setTime(date);calendar.set(Calendar.DAY_OF_MONTH, 8);System.out.println(当前时间日设置为8后,时间是: calendar.getTime());calendar.add(Calendar.HOUR, 2);System.out.println(当前时间加2小时后,时间是: calendar.getTime());calendar.add(Calendar.MONTH, -2);System.out.println(当前日期减2个月后,时间是: calendar.getTime()); } }4. JDK8新的日期时间API 如果我们可以跟别人说“我们在1502643933071见面别晚了”那么就再简单不过了。但是我们希望时间与昼夜和四季有关于是事情就变复杂了。JDK 1.0中包含了一个java.util.Date类但是它的大多数方法已经在JDK 1.1引入Calendar类之后被弃用了。而Calendar并不比Date好多少。它们面临的问题是 可变性像日期和时间这样的类应该是不可变的。 偏移性Date中的年份是从1900开始的而月份都从0开始。 格式化格式化只对Date有用Calendar则不行。 此外它们也不是线程安全的不能处理闰秒等。 闰秒是指为保持协调世界时接近于世界时时刻由国际计量局统一规定在年底或年中也可能在季末对协调世界时增加或减少1秒的调整。由于地球自转的不均匀性和长期变慢性主要由潮汐摩擦引起的会使世界时民用时和原子时之间相差超过到±0.9秒时就把协调世界时向前拨1秒负闰秒最后一分钟为59秒或向后拨1秒正闰秒最后一分钟为61秒 闰秒一般加在公历年末或公历六月末。 目前全球已经进行了27次闰秒均为正闰秒。 总结对日期和时间的操作一直是Java程序员最痛苦的地方之一。 第三次引入的API是成功的并且java 8中引入的java.time API 已经纠正了过去的缺陷将来很长一段时间内它都会为我们服务。 Java 8 以一个新的开始为 Java 创建优秀的 API。新的日期时间API包含 java.time – 包含值对象的基础包java.time.chrono – 提供对不同的日历系统的访问。java.time.format – 格式化和解析时间和日期java.time.temporal – 包括底层框架和扩展特性java.time.zone – 包含时区支持的类 说明大多数开发者只会用到基础包和format包也可能会用到 temporal 包。因此尽管有68个新的公开类型大多数开发者大概将只会用到其中的三分之一。 比如新的 java.time 中包含了所有关于时钟Clock本地日期LocalDate、本地时间LocalTime、本地日期时间LocalDateTime、时区ZonedDateTime和持续时间Duration的类。 4.1 本地日期时间LocalDate、LocalTime、LocalDateTime 方法描述now() / now(ZoneId zone)静态方法根据当前时间创建对象/指定时区的对象of(xx,xx,xx,xx,xx,xxx)静态方法根据指定日期/时间创建对象getDayOfMonth()/getDayOfYear()获得月份天数(1-31) /获得年份天数(1-366)getDayOfWeek()获得星期几(返回一个 DayOfWeek 枚举值)getMonth()获得月份, 返回一个 Month 枚举值getMonthValue() / getYear()获得月份(1-12) /获得年份getHours()/getMinute()/getSecond()获得当前对象对应的小时、分钟、秒withDayOfMonth()/withDayOfYear()/withMonth()/withYear()将月份天数、年份天数、月份、年份修改为指定的值并返回新的对象with(TemporalAdjuster t)将当前日期时间设置为校对器指定的日期时间plusDays(), plusWeeks(), plusMonths(), plusYears(),plusHours()向当前对象添加几天、几周、几个月、几年、几小时minusMonths() / minusWeeks()/minusDays()/minusYears()/minusHours()从当前对象减去几月、几周、几天、几年、几小时plus(TemporalAmount t)/minus(TemporalAmount t)添加或减少一个 Duration 或 PeriodisBefore()/isAfter()比较两个 LocalDateisLeapYear()判断是否是闰年在LocalDate类中声明format(DateTimeFormatter t)格式化本地日期、时间返回一个字符串parse(Charsequence text)将指定格式的字符串解析为日期、时间 import org.junit.Test;import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime;public class TestLocalDateTime {Testpublic void test7(){LocalDate now LocalDate.now();LocalDate before now.minusDays(100);System.out.println(before);//2019-02-26}Testpublic void test06(){LocalDate lai LocalDate.of(2019, 5, 13);LocalDate go lai.plusDays(160);System.out.println(go);//2019-10-20}Testpublic void test05(){LocalDate lai LocalDate.of(2019, 5, 13);System.out.println(lai.getDayOfYear());}Testpublic void test04(){LocalDate lai LocalDate.of(2019, 5, 13);System.out.println(lai);}Testpublic void test03(){LocalDateTime now LocalDateTime.now();System.out.println(now);}Testpublic void test02(){LocalTime now LocalTime.now();System.out.println(now);}Testpublic void test01(){LocalDate now LocalDate.now();System.out.println(now);} }4.2 瞬时Instant Instant时间线上的一个瞬时点。 这可能被用来记录应用程序中的事件时间戳。 在处理时间和日期的时候我们通常会想到年、月、日、时、分、秒。然而这只是时间的一个模型是面向人类的。第二种通用模型是面向机器的或者说是连续的。在此模型中时间线中的一个点表示为一个很大的数这有利于计算机处理。在UNIX中这个数从1970年开始以秒为的单位同样的在Java中也是从1970年开始但以毫秒为单位。 java.time包通过值类型Instant提供机器视图不提供处理人类意义上的时间单位。Instant表示时间线上的一点而不需要任何上下文信息例如时区。概念上讲它只是简单的表示自1970年1月1日0时0分0秒UTC开始的秒数。因为java.time包是基于纳秒计算的所以Instant的精度可以达到纳秒级。 (1 ns 10-9 s) 1秒 1000毫秒 106微秒109纳秒 方法描述now()静态方法返回默认UTC时区的Instant类的对象ofEpochMilli(long epochMilli)静态方法返回在1970-01-01 00:00:00基础上加上指定毫秒数之后的Instant类的对象atOffset(ZoneOffset offset)结合即时的偏移来创建一个 OffsetDateTimetoEpochMilli()返回1970-01-01 00:00:00到当前时间的毫秒数即为时间戳 时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数。 中国大陆、中国香港、中国澳门、中国台湾、蒙古国、新加坡、马来西亚、菲律宾、西澳大利亚州的时间与UTC的时差均为8也就是UTC8。 instant.atOffset(ZoneOffset.ofHours(8)); 整个地球分为二十四时区每个时区都有自己的本地时间。北京时区是东八区领先UTC八个小时在电子邮件信头的Date域记为0800。如果在电子邮件的信头中有这么一行 Date: Fri, 08 Nov 2002 09:42:22 0800 说明信件的发送地的地方时间是二○○二年十一月八号星期五早上九点四十二分二十二秒这个地方的本地时领先UTC八个小时(0800 就是东八区时间)。电子邮件信头的Date域使用二十四小时的时钟而不使用AM和PM来标记上下午。 以这个电子邮件的发送时间为例如果要把这个时间转化为UTC可以使用一下公式 UTC 时区差 本地时间 时区差东为正西为负。在此把东八区时区差记为 0800 UTC (0800) 本地北京时间 (1) 那么UTC 本地时间北京时间- 0800 (2) 0942 - 0800 0142 即UTC是当天凌晨一点四十二分二十二秒。 4.3 日期时间格式化DateTimeFormatter 该类提供了三种格式化方法 预定义的标准格式。如ISO_LOCAL_DATE_TIME、ISO_LOCAL_DATE、ISO_LOCAL_TIME 本地化相关的格式。如ofLocalizedDate(FormatStyle.LONG) // 本地化相关的格式。如ofLocalizedDateTime() // FormatStyle.MEDIUM / FormatStyle.SHORT :适用于LocalDateTime// 本地化相关的格式。如ofLocalizedDate() // FormatStyle.FULL / FormatStyle.LONG / FormatStyle.MEDIUM / FormatStyle.SHORT : 适用于LocalDate自定义的格式。如ofPattern(“yyyy-MM-dd hh:mm:ss”) 方 法描 述ofPattern(String pattern)静态方法返回一个指定字符串格式的DateTimeFormatterformat(TemporalAccessor t)格式化一个日期、时间返回字符串parse(CharSequence text)将指定格式的字符序列解析为一个日期、时间 举例 import org.junit.Test;import java.time.LocalDateTime; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.time.format.FormatStyle;public class TestDatetimeFormatter {Testpublic void test1(){// 方式一预定义的标准格式。如ISO_LOCAL_DATE_TIME;ISO_LOCAL_DATE;ISO_LOCAL_TIMEDateTimeFormatter formatter DateTimeFormatter.ISO_LOCAL_DATE_TIME;// 格式化:日期--字符串LocalDateTime localDateTime LocalDateTime.now();String str1 formatter.format(localDateTime);System.out.println(localDateTime);System.out.println(str1);// 2019-02-18T15:42:18.797// 解析字符串 --日期TemporalAccessor parse formatter.parse(2019-02-18T15:42:18.797);LocalDateTime dateTime LocalDateTime.from(parse);System.out.println(dateTime);}Testpublic void test2(){LocalDateTime localDateTime LocalDateTime.now();// 方式二// 本地化相关的格式。如ofLocalizedDateTime()// FormatStyle.MEDIUM / FormatStyle.SHORT :适用于LocalDateTimeDateTimeFormatter formatter1 DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM);// 格式化String str2 formatter1.format(localDateTime);System.out.println(str2);// 2019年2月18日 下午03时47分16秒// 本地化相关的格式。如ofLocalizedDate()// FormatStyle.FULL / FormatStyle.LONG / FormatStyle.MEDIUM / FormatStyle.SHORT : 适用于LocalDateDateTimeFormatter formatter2 DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL);// 格式化String str3 formatter2.format(LocalDate.now());System.out.println(str3);// 2020年3月14日 星期六}Testpublic void test3(){//方式三自定义的方式关注、重点DateTimeFormatter dateTimeFormatter DateTimeFormatter.ofPattern(yyyy/MM/dd HH:mm:ss);//格式化String strDateTime dateTimeFormatter.format(LocalDateTime.now());System.out.println(strDateTime); //2022-10-28 10:32:12//解析TemporalAccessor accessor dateTimeFormatter.parse(2020/03/14 10:45:24);LocalDateTime localDateTime LocalDateTime.from(accessor);System.out.println(localDateTime);} }4.4 其它API 1、指定时区日期时间ZondId和ZonedDateTime ZoneId该类中包含了所有的时区信息一个时区的ID如 Europe/Paris ZonedDateTime一个在ISO-8601日历系统时区的日期时间如 2007-12-03T10:15:3001:00 Europe/Paris。 其中每个时区都对应着ID地区ID都为“{区域}/{城市}”的格式例如Asia/Shanghai等 常见时区ID Asia/Shanghai UTC America/New_York可以通过ZondId获取所有可用的时区ID import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.Set;public class TestZone {Testpublic void test01() {//需要知道一些时区的id//SetString是一个集合容器SetString availableZoneIds ZoneId.getAvailableZoneIds();//快捷模板iterfor (String availableZoneId : availableZoneIds) {System.out.println(availableZoneId);}}Testpublic void test02(){ZonedDateTime t1 ZonedDateTime.now();System.out.println(t1);ZonedDateTime t2 ZonedDateTime.now(ZoneId.of(America/New_York));System.out.println(t2);} } 2、持续日期/时间Period和Duration 持续时间Duration用于计算两个“时间”间隔日期间隔Period用于计算两个“日期”间隔 import org.junit.Test;import java.time.Duration; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.Period;public class TestPeriodDuration {Testpublic void test01(){LocalDate t1 LocalDate.now();LocalDate t2 LocalDate.of(2018, 12, 31);Period between Period.between(t1, t2);System.out.println(between);System.out.println(相差的年数between.getYears());System.out.println(相差的月数between.getMonths());System.out.println(相差的天数between.getDays());System.out.println(相差的总数between.toTotalMonths());}Testpublic void test02(){LocalDateTime t1 LocalDateTime.now();LocalDateTime t2 LocalDateTime.of(2017, 8, 29, 0, 0, 0, 0);Duration between Duration.between(t1, t2);System.out.println(between);System.out.println(相差的总天数between.toDays());System.out.println(相差的总小时数between.toHours());System.out.println(相差的总分钟数between.toMinutes());System.out.println(相差的总秒数between.getSeconds());System.out.println(相差的总毫秒数between.toMillis());System.out.println(相差的总纳秒数between.toNanos());System.out.println(不够一秒的纳秒数between.getNano());}Testpublic void test03(){//Duration:用于计算两个“时间”间隔以秒和纳秒为基准LocalTime localTime LocalTime.now();LocalTime localTime1 LocalTime.of(15, 23, 32);//between():静态方法返回Duration对象表示两个时间的间隔Duration duration Duration.between(localTime1, localTime);System.out.println(duration);System.out.println(duration.getSeconds());System.out.println(duration.getNano());LocalDateTime localDateTime LocalDateTime.of(2016, 6, 12, 15, 23, 32);LocalDateTime localDateTime1 LocalDateTime.of(2017, 6, 12, 15, 23, 32);Duration duration1 Duration.between(localDateTime1, localDateTime);System.out.println(duration1.toDays());}Testpublic void test4(){//Period:用于计算两个“日期”间隔以年、月、日衡量LocalDate localDate LocalDate.now();LocalDate localDate1 LocalDate.of(2028, 3, 18);Period period Period.between(localDate, localDate1);System.out.println(period);System.out.println(period.getYears());System.out.println(period.getMonths());System.out.println(period.getDays());Period period1 period.withYears(2);System.out.println(period1);} } 3、Clock使用时区提供对当前即时、日期和时间的访问的时钟。 4、 TemporalAdjuster : 时间校正器。有时我们可能需要获取例如将日期调整到“下一个工作日”等操作。 TemporalAdjusters : 该类通过静态方法(firstDayOfXxx()/lastDayOfXxx()/nextXxx())提供了大量的常用 TemporalAdjuster 的实现。 Test public void test1(){// TemporalAdjuster:时间校正器// 获取当前日期的下一个周日是哪天TemporalAdjuster temporalAdjuster TemporalAdjusters.next(DayOfWeek.SUNDAY);LocalDateTime localDateTime LocalDateTime.now().with(temporalAdjuster);System.out.println(localDateTime);// 获取下一个工作日是哪天LocalDate localDate LocalDate.now().with(new TemporalAdjuster() {Overridepublic Temporal adjustInto(Temporal temporal) {LocalDate date (LocalDate) temporal;if (date.getDayOfWeek().equals(DayOfWeek.FRIDAY)) {return date.plusDays(3);} else if (date.getDayOfWeek().equals(DayOfWeek.SATURDAY)) {return date.plusDays(2);} else {return date.plusDays(1);}}});System.out.println(下一个工作日是 localDate);}4.5 与传统日期处理的转换 类To 遗留类From 遗留类java.time.Instant与java.util.DateDate.from(instant)date.toInstant()java.time.Instant与java.sql.TimestampTimestamp.from(instant)timestamp.toInstant()java.time.ZonedDateTime与java.util.GregorianCalendarGregorianCalendar.from(zonedDateTime)cal.toZonedDateTime()java.time.LocalDate与java.sql.TimeDate.valueOf(localDate)date.toLocalDate()java.time.LocalTime与java.sql.TimeDate.valueOf(localDate)date.toLocalTime()java.time.LocalDateTime与java.sql.TimestampTimestamp.valueOf(localDateTime)timestamp.toLocalDateTime()java.time.ZoneId与java.util.TimeZoneTimezone.getTimeZone(id)timeZone.toZoneId()java.time.format.DateTimeFormatter与java.text.DateFormatformatter.toFormat()无 5. Java比较器 我们知道基本数据类型的数据除boolean类型外需要比较大小的话之间使用比较运算符即可但是引用数据类型是不能直接使用比较运算符来比较大小的。那么如何解决这个问题呢 在Java中经常会涉及到对象数组的排序问题那么就涉及到对象之间的比较问题。 Java实现对象排序的方式有两种 自然排序java.lang.Comparable定制排序java.util.Comparator 5.1 自然排序java.lang.Comparable Comparable接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序。实现 Comparable 的类必须实现 compareTo(Object obj) 方法两个对象即通过 compareTo(Object obj) 方法的返回值来比较大小。如果当前对象this大于形参对象obj则返回正整数如果当前对象this小于形参对象obj则返回负整数如果当前对象this等于形参对象obj则返回零。 package java.lang;public interface Comparable{int compareTo(Object obj); }实现Comparable接口的对象列表和数组可以通过 Collections.sort 或 Arrays.sort进行自动排序。实现此接口的对象可以用作有序映射中的键或有序集合中的元素无需指定比较器。 对于类 C 的每一个 e1 和 e2 来说当且仅当 e1.compareTo(e2) 0 与 e1.equals(e2) 具有相同的 boolean 值时类 C 的自然排序才叫做与 equals 一致。建议虽然不是必需的最好使自然排序与 equals 一致。 Comparable 的典型实现(默认都是从小到大排列的) String按照字符串中字符的Unicode值进行比较Character按照字符的Unicode值来进行比较数值类型对应的包装类以及BigInteger、BigDecimal按照它们对应的数值大小进行比较Booleantrue 对应的包装类实例大于 false 对应的包装类实例Date、Time等后面的日期时间比前面的日期时间大 代码示例 package com.atguigu.api;public class Student implements Comparable {private int id;private String name;private int score;private int age;public Student(int id, String name, int score, int age) {this.id id;this.name name;this.score score;this.age age;}public int getId() {return id;}public void setId(int id) {this.id id;}public String getName() {return name;}public void setName(String name) {this.name name;}public int getScore() {return score;}public void setScore(int score) {this.score score;}public int getAge() {return age;}public void setAge(int age) {this.age age;}Overridepublic String toString() {return Student{ id id , name name \ , score score , age age };}Overridepublic int compareTo(Object o) {//这些需要强制将o对象向下转型为Student类型的变量才能调用Student类中的属性//默认按照学号比较大小Student stu (Student) o;return this.id - stu.id;} }测试类 package com.atguigu.api;public class TestStudent {public static void main(String[] args) {Student[] arr new Student[5];arr[0] new Student(3,张三,90,23);arr[1] new Student(1,熊大,100,22);arr[2] new Student(5,王五,75,25);arr[3] new Student(4,李四,85,24);arr[4] new Student(2,熊二,85,18);//单独比较两个对象System.out.println(arr[0].compareTo(arr[1]));System.out.println(arr[1].compareTo(arr[2]));System.out.println(arr[2].compareTo(arr[2]));System.out.println(所有学生);for (int i 0; i arr.length; i) {System.out.println(arr[i]);}System.out.println(按照学号排序);for (int i 1; i arr.length; i) {for (int j 0; j arr.length-i; j) {if(arr[j].compareTo(arr[j1])0){Student temp arr[j];arr[j] arr[j1];arr[j1] temp;}}}for (int i 0; i arr.length; i) {System.out.println(arr[i]);}} } 再举例 public class Student implements Comparable {private String name;private int score;public Student(String name, int score) {this.name name;this.score score;}public String getName() {return name;}public void setName(String name) {this.name name;}public int getScore() {return score;}public void setScore(int score) {this.score score;}Overridepublic String toString() {return Student{ name name \ , score score };}Overridepublic int compareTo(Object o) {return this.score - ((Student)o).score;} }测试 Test public void test02() {Student[] students new Student[3];students[0] new Student(张三, 96);students[1] new Student(李四, 85);students[2] new Student(王五, 98);System.out.println(Arrays.toString(students));Arrays.sort(students);System.out.println(Arrays.toString(students)); }再举例 class Goods implements Comparable {private String name;private double price;//按照价格比较商品的大小Overridepublic int compareTo(Object o) {if(o instanceof Goods) {Goods other (Goods) o;if (this.price other.price) {return 1;} else if (this.price other.price) {return -1;}return 0;}throw new RuntimeException(输入的数据类型不一致);}//构造器、getter、setter、toString()方法略 } 测试 public class ComparableTest{public static void main(String[] args) {Goods[] all new Goods[4];all[0] new Goods(《红楼梦》, 100);all[1] new Goods(《西游记》, 80);all[2] new Goods(《三国演义》, 140);all[3] new Goods(《水浒传》, 120);Arrays.sort(all);System.out.println(Arrays.toString(all));}} 5.2 定制排序java.util.Comparator 思考 当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码例如一些第三方的类你只有.class文件没有源文件如果一个类实现了Comparable接口也指定了两个对象的比较大小的规则但是此时此刻我不想按照它预定义的方法比较大小但是我又不能随意修改因为会影响其他地方的使用怎么办JDK在设计类库之初也考虑到这种情况了所以又增加了一个java.util.Comparator接口。强行对多个对象进行整体排序的比较。 重写compare(Object o1,Object o2)方法比较o1和o2的大小如果方法返回正整数则表示o1大于o2如果返回0表示相等返回负整数表示o1小于o2。 可以将 Comparator 传递给 sort 方法如 Collections.sort 或 Arrays.sort从而允许在排序顺序上实现精确控制。 package java.util;public interface Comparator{int compare(Object o1,Object o2); }还可以使用 Comparator 来控制某些数据结构如有序 set或有序映射的顺序或者为那些没有自然顺序的对象 collection 提供排序。 举例 package com.atguigu.api;import java.util.Comparator; //定义定制比较器类 public class StudentScoreComparator implements Comparator { Overridepublic int compare(Object o1, Object o2) {Student s1 (Student) o1;Student s2 (Student) o2;int result s1.getScore() - s2.getScore();return result ! 0 ? result : s1.getId() - s2.getId();} }测试类 package com.atguigu.api;public class TestStudent {public static void main(String[] args) {Student[] arr new Student[5];arr[0] new Student(3,张三,90,23);arr[1] new Student(1,熊大,100,22);arr[2] new Student(5,王五,75,25);arr[3] new Student(4,李四,85,24);arr[4] new Student(2,熊二,85,18);//单独比较两个对象System.out.println(arr[0].compareTo(arr[1]));System.out.println(arr[1].compareTo(arr[2]));System.out.println(arr[2].compareTo(arr[2]));System.out.println(所有学生);for (int i 0; i arr.length; i) {System.out.println(arr[i]);}System.out.println(按照学号排序);for (int i 1; i arr.length; i) {for (int j 0; j arr.length-i; j) {if(arr[j].compareTo(arr[j1])0){Student temp arr[j];arr[j] arr[j1];arr[j1] temp;}}}for (int i 0; i arr.length; i) {System.out.println(arr[i]);}System.out.println(按照成绩排序);StudentScoreComparator sc new StudentScoreComparator();for (int i 1; i arr.length; i) {for (int j 0; j arr.length-i; j) {if(sc.compare(arr[j],arr[j1])0){Student temp arr[j];arr[j] arr[j1];arr[j1] temp;}}}for (int i 0; i arr.length; i) {System.out.println(arr[i]);}} }再举例 Test public void test02() {Student[] students new Student[3];students[0] new Student(张三, 96);students[1] new Student(李四, 85);students[2] new Student(王五, 98);System.out.println(Arrays.toString(students));//定制排序Arrays.sort(students, new Comparator() {Overridepublic int compare(Object o1, Object o2) {return Collator.getInstance(Locale.CHINA).compare(((Student) o1).getName(), ((Student) o2).getName());}});System.out.println(Arrays.toString(students)); }再举例 Goods[] all new Goods[4]; all[0] new Goods(War and Peace, 100); all[1] new Goods(Childhood, 80); all[2] new Goods(Scarlet and Black, 140); all[3] new Goods(Notre Dame de Paris, 120);Arrays.sort(all, new Comparator() {Overridepublic int compare(Object o1, Object o2) {Goods g1 (Goods) o1;Goods g2 (Goods) o2;return g1.getName().compareTo(g2.getName());} });System.out.println(Arrays.toString(all)); 6. 系统相关类 6.1 java.lang.System类 System类代表系统系统级的很多属性和控制方法都放置在该类的内部。该类位于java.lang包。 由于该类的构造器是private的所以无法创建该类的对象也就是无法实例化该类。其内部的成员变量和成员方法都是static的所以也可以很方便的进行调用。 成员变量 Scanner scan new Scanner(System.in); System类内部包含in、out和err三个成员变量分别代表标准输入流(键盘输入)标准输出流(显示器)和标准错误输出流(显示器)。 成员方法 native long currentTimeMillis() 该方法的作用是返回当前的计算机时间时间的表达格式为当前计算机时间和GMT时间(格林威治时间)1970年1月1号0时0分0秒所差的毫秒数。 void exit(int status) 该方法的作用是退出程序。其中status的值为0代表正常退出非零代表异常退出。使用该方法可以在图形界面编程中实现程序的退出功能等。 void gc() 该方法的作用是请求系统进行垃圾回收。至于系统是否立刻回收则取决于系统中垃圾回收算法的实现以及系统执行时的情况。 String getProperty(String key) 该方法的作用是获得系统中属性名为key的属性对应的值。系统中常见的属性名以及属性的作用如下表所示 举例 import org.junit.Test;public class TestSystem {Testpublic void test01(){long time System.currentTimeMillis();System.out.println(现在的系统时间距离1970年1月1日凌晨 time 毫秒);System.exit(0);System.out.println(over);//不会执行}Testpublic void test02(){String javaVersion System.getProperty(java.version);System.out.println(java的version: javaVersion);String javaHome System.getProperty(java.home);System.out.println(java的home: javaHome);String osName System.getProperty(os.name);System.out.println(os的name: osName);String osVersion System.getProperty(os.version);System.out.println(os的version: osVersion);String userName System.getProperty(user.name);System.out.println(user的name: userName);String userHome System.getProperty(user.home);System.out.println(user的home: userHome);String userDir System.getProperty(user.dir);System.out.println(user的dir: userDir);}Testpublic void test03() throws InterruptedException {for (int i1; i 10; i){MyDemo my new MyDemo(i);//每一次循环my就会指向新的对象那么上次的对象就没有变量引用它了就成垃圾对象}//为了看到垃圾回收器工作我要加下面的代码让main方法不那么快结束因为main结束就会导致JVM退出GC也会跟着结束。System.gc();//如果不调用这句代码GC可能不工作因为当前内存很充足GC就觉得不着急回收垃圾对象。//调用这句代码会让GC尽快来工作。Thread.sleep(5000);} }class MyDemo{private int value;public MyDemo(int value) {this.value value;}Overridepublic String toString() {return MyDemo{ value value };}//重写finalize方法让大家看一下它的调用效果Overrideprotected void finalize() throws Throwable { // 正常重写这里是编写清理系统内存的代码 // 这里写输出语句是为了看到finalize()方法被调用的效果System.out.println(this 轻轻的我走了不带走一段代码....);} }static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) 从指定源数组中复制一个数组复制从指定的位置开始到目标数组的指定位置结束。常用于数组的插入和删除 import org.junit.Test;import java.util.Arrays;public class TestSystemArrayCopy {Testpublic void test01(){int[] arr1 {1,2,3,4,5};int[] arr2 new int[10];System.arraycopy(arr1,0,arr2,3,arr1.length);System.out.println(Arrays.toString(arr1));System.out.println(Arrays.toString(arr2));}Testpublic void test02(){int[] arr {1,2,3,4,5};System.arraycopy(arr,0,arr,1,arr.length-1);System.out.println(Arrays.toString(arr));}Testpublic void test03(){int[] arr {1,2,3,4,5};System.arraycopy(arr,1,arr,0,arr.length-1);System.out.println(Arrays.toString(arr));} }6.2 java.lang.Runtime类 每个 Java 应用程序都有一个 Runtime 类实例使应用程序能够与其运行的环境相连接。可以通过 getRuntime 方法获取当前运行时。 应用程序不能创建自己的 Runtime 类实例。 public static Runtime getRuntime() 返回与当前 Java 应用程序相关的运行时对象。 public long totalMemory()返回 Java 虚拟机中初始化时的内存总量。此方法返回的值可能随时间的推移而变化这取决于主机环境。默认为物理电脑内存的1/64。 public long maxMemory()返回 Java 虚拟机中最大程度能使用的内存总量。默认为物理电脑内存的1/4。 public long freeMemory()回 Java 虚拟机中的空闲内存量。调用 gc 方法可能导致 freeMemory 返回值的增加。 package com.atguigu.system;public class TestRuntime {public static void main(String[] args) {Runtime runtime Runtime.getRuntime();long initialMemory runtime.totalMemory(); //获取虚拟机初始化时堆内存总量long maxMemory runtime.maxMemory(); //获取虚拟机最大堆内存总量String str ;//模拟占用内存for (int i 0; i 10000; i) {str i;}long freeMemory runtime.freeMemory(); //获取空闲堆内存总量System.out.println(总内存 initialMemory / 1024 / 1024 * 64 MB);System.out.println(总内存 maxMemory / 1024 / 1024 * 4 MB);System.out.println(空闲内存 freeMemory / 1024 / 1024 MB) ;System.out.println(已用内存 (initialMemory-freeMemory) / 1024 / 1024 MB);} }7. 和数学相关的类 7.1 java.lang.Math java.lang.Math 类包含用于执行基本数学运算的方法如初等指数、对数、平方根和三角函数。类似这样的工具类其所有方法均为静态方法并且不会创建对象调用起来非常简单。 public static double abs(double a) 返回 double 值的绝对值。 double d1 Math.abs(-5); //d1的值为5 double d2 Math.abs(5); //d2的值为5public static double ceil(double a) 返回大于等于参数的最小的整数。 double d1 Math.ceil(3.3); //d1的值为 4.0 double d2 Math.ceil(-3.3); //d2的值为 -3.0 double d3 Math.ceil(5.1); //d3的值为 6.0public static double floor(double a) 返回小于等于参数最大的整数。 double d1 Math.floor(3.3); //d1的值为3.0 double d2 Math.floor(-3.3); //d2的值为-4.0 double d3 Math.floor(5.1); //d3的值为 5.0public static long round(double a) 返回最接近参数的 long。(相当于四舍五入方法) long d1 Math.round(5.5); //d1的值为6 long d2 Math.round(5.4); //d2的值为5 long d3 Math.round(-3.3); //d3的值为-3 long d4 Math.round(-3.8); //d4的值为-4public static double pow(double a,double b)返回a的b幂次方法public static double sqrt(double a)返回a的平方根public static double random()返回[0,1)的随机值public static final double PI返回圆周率public static double max(double x, double y)返回x,y中的最大值public static double min(double x, double y)返回x,y中的最小值其它acos,asin,atan,cos,sin,tan 三角函数 double result Math.pow(2,31); double sqrt Math.sqrt(256); double rand Math.random(); double pi Math.PI;7.2 java.math包 7.2.1 BigInteger Integer类作为int的包装类能存储的最大整型值为231-1Long类也是有限的最大为263-1。如果要表示再大的整数不管是基本数据类型还是他们的包装类都无能为力更不用说进行运算了。 java.math包的BigInteger可以表示不可变的任意精度的整数。BigInteger 提供所有 Java 的基本整数操作符的对应物并提供 java.lang.Math 的所有相关方法。另外BigInteger 还提供以下运算模算术、GCD 计算、质数测试、素数生成、位操作以及一些其他操作。 构造器 BigInteger(String val)根据字符串构建BigInteger对象 方法 public BigInteger abs()返回此 BigInteger 的绝对值的 BigInteger。BigInteger add(BigInteger val) 返回其值为 (this val) 的 BigIntegerBigInteger subtract(BigInteger val) 返回其值为 (this - val) 的 BigIntegerBigInteger multiply(BigInteger val) 返回其值为 (this * val) 的 BigIntegerBigInteger divide(BigInteger val) 返回其值为 (this / val) 的 BigInteger。整数相除只保留整数部分。BigInteger remainder(BigInteger val) 返回其值为 (this % val) 的 BigInteger。BigInteger[] divideAndRemainder(BigInteger val)返回包含 (this / val) 后跟 (this % val) 的两个 BigInteger 的数组。BigInteger pow(int exponent) 返回其值为 (this^exponent) 的 BigInteger。 Test public void test01(){//long bigNum 123456789123456789123456789L;BigInteger b1 new BigInteger(123456789123456789123456789);BigInteger b2 new BigInteger(78923456789123456789123456789);//System.out.println(和 (b1b2));//错误的无法直接使用进行求和System.out.println(和 b1.add(b2));System.out.println(减 b1.subtract(b2));System.out.println(乘 b1.multiply(b2));System.out.println(除 b2.divide(b1));System.out.println(余 b2.remainder(b1)); }7.2.2 BigDecimal 一般的Float类和Double类可以用来做科学计算或工程计算但在商业计算中要求数字精度比较高故用到java.math.BigDecimal类。 BigDecimal类支持不可变的、任意精度的有符号十进制定点数。 构造器 public BigDecimal(double val)public BigDecimal(String val) -- 推荐 常用方法 public BigDecimal add(BigDecimal augend)public BigDecimal subtract(BigDecimal subtrahend)public BigDecimal multiply(BigDecimal multiplicand)public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode)divisor是除数scale指明保留几位小数roundingMode指明舍入模式ROUND_UP :向上加1、ROUND_DOWN :直接舍去、ROUND_HALF_UP:四舍五入 举例 Test public void test02(){/*double big 12.123456789123456789123456789;System.out.println(big big);*/BigDecimal b1 new BigDecimal(123.45678912345678912345678912345678);BigDecimal b2 new BigDecimal(7.8923456789123456789123456789998898888);// System.out.println(和 (b1b2));//错误的无法直接使用进行求和System.out.println(和 b1.add(b2));System.out.println(减 b1.subtract(b2));System.out.println(乘 b1.multiply(b2));System.out.println(除 b1.divide(b2,20,RoundingMode.UP));//divide(BigDecimal divisor, int scale, int roundingMode)System.out.println(除 b1.divide(b2,20,RoundingMode.DOWN));//divide(BigDecimal divisor, int scale, int roundingMode)System.out.println(余 b1.remainder(b2)); }举例 Test public void test03(){BigInteger bi new BigInteger(12433241123);BigDecimal bd new BigDecimal(12435.351);BigDecimal bd2 new BigDecimal(11);System.out.println(bi);// System.out.println(bd.divide(bd2));System.out.println(bd.divide(bd2, BigDecimal.ROUND_HALF_UP));System.out.println(bd.divide(bd2, 15, BigDecimal.ROUND_HALF_UP)); } 7.2.3 RoundingMode枚举类 CEILING 向正无限大方向舍入的舍入模式。 FLOOR向负无限大方向舍入的舍入模式。 DOWN 向零方向舍入的舍入模式。 UP远离零方向舍入的舍入模式。 HALF_DOWN 向最接近数字方向舍入的舍入模式如果与两个相邻数字的距离相等则向下舍入。 HALF_UP向最接近数字方向舍入的舍入模式如果与两个相邻数字的距离相等则向上舍入。 HALF_EVEN向最接近数字方向舍入的舍入模式如果与两个相邻数字的距离相等则向相邻的偶数舍入。 7.3 java.util.Random 用于产生随机数 boolean nextBoolean():返回下一个伪随机数它是取自此随机数生成器序列的均匀分布的 boolean 值。 void nextBytes(byte[] bytes):生成随机字节并将其置于用户提供的 byte 数组中。 double nextDouble():返回下一个伪随机数它是取自此随机数生成器序列的、在 0.0 和 1.0 之间均匀分布的 double 值。 float nextFloat():返回下一个伪随机数它是取自此随机数生成器序列的、在 0.0 和 1.0 之间均匀分布的 float 值。 double nextGaussian():返回下一个伪随机数它是取自此随机数生成器序列的、呈高斯“正态”分布的 double 值其平均值是 0.0标准差是 1.0。 int nextInt():返回下一个伪随机数它是此随机数生成器的序列中均匀分布的 int 值。 int nextInt(int n):返回一个伪随机数它是取自此随机数生成器序列的、在 0包括和指定值不包括之间均匀分布的 int 值。 long nextLong():返回下一个伪随机数它是取自此随机数生成器序列的均匀分布的 long 值。 Test public void test04(){Random r new Random();System.out.println(随机整数 r.nextInt());System.out.println(随机小数 r.nextDouble());System.out.println(随机布尔值 r.nextBoolean()); }
http://www.zqtcl.cn/news/386855/

相关文章:

  • 成都网站推广公司排名淘宝商家网站建设
  • 平台网站建设报价网站建设企业蛋糕
  • 上海创意网站建设电子商务毕业设计网站建设
  • 如何让网站打不开 解析wordpress pdf检索
  • 网站建设大作业感想台州企业网站模板建站
  • 淄博网站的优化上海营销网站建站公司
  • 长春网站建设硕成传媒长春电商网站建设哪家好
  • 舟山建设管理网站手表交易网站
  • 如何电话推销客户做网站沉浸式展厅搭建商
  • 重庆网站建设开发e福州官方网站
  • 网站怎么可以被收录广州网站建设全包
  • 网站备案期间如何采购需求网站建设
  • 东莞seo网站优化运营南通网站排名外包
  • 新能源网站建设唐山专业网站建设公司
  • 石基网站建设临沂网站优化哪家好
  • 用node.js可以做网站吗上海做网站 公司有哪些
  • 淄博网站建设详细策划一个域名解析多个网站
  • 无锡网站建设首选捷搜网站优化大赛
  • 部门网站建设多少钱百度关键词挖掘查询工具
  • 做游戏直播那个网站asp做网站教程
  • 网站建设小程序开发情侣头像制作素材图片
  • spoc课程网站建设专业彩票网站建设
  • 创建网站需要注意什么忻州市城乡建设管理局网站
  • 万江做网站wordpress 动静
  • 北京自助模板建站遂宁企业网络推广方案
  • 湖南建设科技节能协会网站武夷山景区网站建设特点
  • 那些网站建设的好百度搜索风云排行榜
  • 网站开发 模板 c沈阳市建设工程质量检测中心网站
  • 企业网站设计专业好吗做钓鱼网站要具备什么
  • 广西备案工信部网站用asp.net做后台网站