创建型模式-抽象工厂

维基百科 抽象工厂 抽象工厂模式(英语:Abstract factory pattern)是一种软件开发设计模式。抽象工厂模式提供了一种方式,可以将一组具有同一主题的单独的工厂封装起来。在正常使用中,客户端程序需要创建抽象工厂的具体实现,然后使用抽象工厂作为接口来创建这一主题的具体对象。客户端程序不需要知道(或关心)它从这些内部的工厂方法中获得对象的具体类型,因为客户端程序仅使用这些对象的通用接口。抽象工厂模式将一组对象的实现细节与他们的一般使用分离开来。 举个例子来说,比如一个抽象工厂类叫做DocumentCreator(文档创建器),此类提供创建若干种产品的接口,包括createLetter()(创建信件)和createResume()(创建简历)。其中,createLetter()返回一个Letter(信件),createResume()返回一个Resume(简历)。系统中还有一些DocumentCreator的具体实现类,包括FancyDocumentCreator和ModernDocumentCreator。这两个类对DocumentCreator的两个方法分别有不同的实现,用来创建不同的“信件”和“简历”(用FancyDocumentCreator的实例可以创建FancyLetter和FancyResume,用ModernDocumentCreator的实例可以创建ModernLetter和ModernResume)。这些具体的“信件”和“简历”类均继承自抽象类,即Letter和Resume类。客户端需要创建“信件”或“简历”时,先要得到一个合适的DocumentCreator实例,然后调用它的方法。一个工厂中创建的每个对象都是同一个主题的(“fancy”或者“modern”)。客户端程序只需要知道得到的对象是“信件”或者“简历”,而不需要知道具体的主题,因此客户端程序从抽象工厂DocumentCreator中得到了Letter或Resume类的引用,而不是具体类的对象引用。 “工厂”是创建产品(对象)的地方,其目的是将产品的创建与产品的使用分离。抽象工厂模式的目的,是将若干抽象产品的接口与不同主题产品的具体实现分离开。这样就能在增加新的具体工厂的时候,不用修改引用抽象工厂的客户端代码。 使用抽象工厂模式,能够在具体工厂变化的时候,不用修改使用工厂的客户端代码,甚至是在运行时。然而,使用这种模式或者相似的设计模式,可能给编写代码带来不必要的复杂性和额外的工作。正确使用设计模式能够抵消这样的“额外工作” 定义 抽象工厂模式的实质是“提供接口,创建一系列相关或独立的对象,而不指定这些对象的具体类。 使用 具体的工厂决定了创建对象的具体类型,而且工厂就是对象实际创建的地方(比如在C++中,用“new”操作符创建对象)。然而,抽象工厂只返回一个指向创建的对象的抽象引用(或指针)。 这样,客户端程序调用抽象工厂引用的方法,由具体工厂完成对象创建,然后客户端程序得到的是抽象产品的引用。如此使客户端代码与对象的创建分离开来。 因为工厂仅仅返回一个抽象产品的引用(或指针),所以客户端程序不知道(也不会牵绊于)工厂创建对象的具体类型。然而,工厂知道具体对象的类型;例如,工厂可能从配置文件中读取某种类型。这时,客户端没有必要指定具体类型,因为已经在配置文件中指定了。通常,这意味着: 客户端代码不知道任何具体类型,也就没必要引入任何相关的头文件或类定义。客户端代码仅仅处理抽象类型。工厂确实创建了具体类型的对象,但是客户端代码仅使用这些对象的抽象接口来访问它们。 如果要增加一个具体类型,只需要修改客户端代码使用另一个工厂即可,而且这个修改通常只是一个文件中的一行代码。不同的工厂创建不同的具体类型的对象,但是和以前一样返回一个抽象类型的引用(或指针),因此客户端代码的其他部分不需要任何改动。这样比修改客户端代码创建新类型的对象简单多了。如果是后者的话,需要修改代码中每一个创建这种对象的地方(而且需要注意的是,这些地方都知道对象的具体类型,而且需要引入具体类型的头文件或类定义)。如果所有的工厂对象都存储在全局的单例对象中,所有的客户端代码到这个单例中访问需要的工厂,那么,更换工厂就非常简单了,仅仅需要更改这个单例对象即可。 代码举例 假设我们有两种产品接口 Button 和 Border ,每一种产品都支持多种系列,比如 Mac 系列和 Windows 系列。这样每个系列的产品分别是 MacButton, WinButton, MacBorder, WinBorder 。为了可以在运行时刻创建一个系列的产品族,我们可以为每个系列的产品族创建一个工厂 MacFactory 和 WinFactory 。每个工厂都有两个方法 CreateButton 和 CreateBorder 并返回对应的产品,可以将这两个方法抽象成一个接口 AbstractFactory 。这样在运行时刻我们可以选择创建需要的产品系列。 public interface Button {} public interface Border {} //实现抽象类 public class MacButton implements Button {} public class MacBorder implements Border {} public class WinButton implements Button {} public class WinBorder implements Border {} //接着实现工厂 public class MacFactory { public static Button createButton() { return new MacButton(); } public static Border createBorder() { return new MacBorder(); } } public class WinFactory { public static Button createButton() { return new WinButton(); } public static Border createBorder() { return new WinBorder(); } } 适用性 在以下情况可以考虑使用抽象工厂模式: ...

August 19, 2019 · 2 min · zhangxiaofeng05

创建型模式-工厂方法

维基百科 工厂方法 工厂方法模式(英语:Factory method pattern)是一种实现了“工厂”概念的面向对象设计模式。就像其他创建型模式一样,它也是处理在不指定对象具体类型的情况下创建对象的问题。工厂方法模式的实质是“定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类。工厂方法让类的实例化推迟到子类中进行。” 创建一个对象常常需要复杂的过程,所以不适合包含在一个复合对象中。创建对象可能会导致大量的重复代码,可能会需要复合对象访问不到的信息,也可能提供不了足够级别的抽象,还可能并不是复合对象概念的一部分。工厂方法模式通过定义一个单独的创建对象的方法来解决这些问题。由子类实现这个方法来创建具体类型的对象。 对象创建中的有些过程包括决定创建哪个对象、管理对象的生命周期,以及管理特定对象的创建和销毁的概念。 工厂 在面向对象程序设计中,工厂通常是一个用来创建其他对象的对象。工厂是构造方法的抽象,用来实现不同的分配方案。 工厂对象通常包含一个或多个方法,用来创建这个工厂所能创建的各种类型的对象。这些方法可能接收参数,用来指定对象创建的方式,最后返回创建的对象。 有时,特定类型对象的控制过程比简单地创建一个对象更复杂。在这种情况下,工厂对象就派上用场了。工厂对象可能会动态地创建产品类的对象,或者从对象池中返回一个对象,或者对所创建的对象进行复杂的配置,或者应用其他的操作。 这些类型的对象很有用。几个不同的设计模式都应用了工厂的概念,并可以使用在很多语言中。例如,在《设计模式》一书中,像工厂方法模式、抽象工厂模式、生成器模式,甚至是单例模式都应用了工厂的概念。 代码举例 例如,有一个Button类表示按钮,另有它的两个子类WinButton和MacButton分别代表Windows和Mac风格的按钮,那么这几个类和用于创建它们的工厂类在Java中可以如下实现 //Button class Button{/* ...*/} class WinButton extends Button{/* ...*/} class MacButton extends Button{/* ...*/} //他们的工厂类 interface ButtonFactory{ abstract Button createButton(); } class WinButtonFactory implements ButtonFactory{ Button createButton(){ return new WinButton(); } } class MacButtonFactory implements ButtonFactory{ Button createButton(){ return new MacButton(); } } 简单工厂 普通的工厂方法模式通常伴随着对象的具体类型与工厂具体类型的一一对应,客户端代码根据需要选择合适的具体类型工厂使用。然而,这种选择可能包含复杂的逻辑。这时,可以创建一个单一的工厂类,用以包含这种选择逻辑,根据参数的不同选择实现不同的具体对象。这个工厂类不需要由每个具体产品实现一个自己的具体的工厂类,所以可以将工厂方法设置为静态方法。 而且,工厂方法封装了对象的创建过程。如果创建过程非常复杂(比如依赖于配置文件或用户输入),工厂方法就非常有用了。 比如,一个程序要读取图像文件。程序支持多种图像格式,每种格式都有一个对应的ImageReader类用来读取图像。程序每次读取图像时,需要基于文件信息创建合适类型的ImageReader。这个选择逻辑可以包装在一个简单工厂中: public class ImageReaderFactory { public static ImageReader imageReaderFactoryMethod(InputStream is) { ImageReader product = null; int imageType = determineImageType(is); switch (imageType) { case ImageReaderFactory.GIF: product = new GifReader(is); case ImageReaderFactory.JPEG: product = new JpegReader(is); //... } return product; } } 适用性 下列情况可以考虑使用工厂方法模式: ...

August 19, 2019 · 2 min · zhangxiaofeng05

java接口回调

回调一般用于层间协作,上层将本层函数安装在下层,这个函数就是回调,而下层在一定条件下触发回调。例如作为一个驱动,是一个底层,他在收到一个数据时,除了完成本层的处理工作外,还将进行回调,将这个数据交给上层应用层来做进一步处理,这在分层的数据通信中很普遍。 例如老板A对员工B说,我现在交给你一个任务,并且我把我的电话号码给你,你一旦完成任务就给我打电话。 1.创建一个回调接口 /** * 一个回调接口 */ public interface CallBack { public void doEvent(); } 2.创建回调接口的实现类,此例中,员工干完活后还要干什么事情是老板说了算的。 /** * 回调接口的实现类 */ public class Boss implements CallBack{ @Override public void doEvent() { System.out.println("打电话给老板,告知已完成工作了"); } } 3.创建控制类,也就是本例中的员工对象,他要持有老板的地址(即回调接口) /** * 控制类,也就是本例中的员工对象,他要持有老板的地址(即回调接口) */ public class Employee { CallBack callBack; public Employee(CallBack callBack){ this.callBack=callBack; } public void doWork(){ System.out.println("玩命干活中"); callBack.doEvent(); } } 4.测试类 /** * 测试类 */ public class TestMain { public static void main(String[] args) { Employee employee = new Employee(new Boss()); employee.doWork(); } } 运行结果: ...

August 17, 2019 · 1 min · zhangxiaofeng05

mysql高级排序

表和数据 CREATE TABLE `sqltest` ( `id` int(11) NOT NULL, `name` varchar(45) NOT NULL, `age` int(11) NOT NULL, `score` int(11) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `id_UNIQUE` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `sqltest` VALUES (1,'土豆',18,100),(2,'地瓜',18,100),(3,'李斯',20,60),(4,'韩非',20,60),(5,'荀子',50,90),(6,'君莫笑',22,80),(7,'寒烟柔',21,80),(8,'包子',26,30),(9,'剑圣',30,0); 排名(row_number) 按分数排序,拿到名次(成绩相同排名不并列) SQL: use sqltest; select st.*,(@rownum:=@rownum+1) as rownum from sqltest st,(select @rownum:=0) potato order by score; 结果: 解释:设置一个伪列@rownum,从1开始计数,依次加1;(select @rownum:=0) potato ,一定要起别名 注意:这是从小到大排;如果需要从大到小的话,order by score desc。 排名(Rank) 按分数排序,拿到名次(成绩相同排名并列,有跳数,比如2个100,1个99,排名就是1,1,3) SQL: use sqltest; select st.*,@rownum:=@rownum+1 as rownum, @curnum:=(case when @prescore=st.score then @curnum else @rownum end) as ScoreRank, @prescore:=st.score as prescore from sqltest st,(select @rownum:=0,@curnum:=0,@prescore:=null) potato order by st.score desc; 结果: ...

August 17, 2019 · 1 min · zhangxiaofeng05

TCP、UDP简单聊天

TCP 客户端套接字:Socket 服务端套接字:ServerSocket TCP(传输控制协议)一种基于连接的通信协议。可靠传输 Server package com.tcp; import java.io.*; import java.net.ServerSocket; import java.net.Socket; /** * 服务器端 */ public class Server { public static void main(String[] args) { ServerSocket serverSocket = null; try { serverSocket = new ServerSocket(12345); System.out.println("服务启动:"+serverSocket.getInetAddress().getHostAddress()+":"+serverSocket.getLocalPort()); Socket accept = serverSocket.accept(); System.out.println("客户端:"+accept.getInetAddress().getHostAddress()+":"+accept.getLocalPort()); BufferedReader sis = new BufferedReader(new InputStreamReader(System.in)); BufferedReader is = new BufferedReader(new InputStreamReader(accept.getInputStream())); PrintWriter os = new PrintWriter(new OutputStreamWriter(accept.getOutputStream())); while (true){ String line; if ((line=is.readLine())!=null){ System.out.println("收到客户端:"+line); if (line.equals("bye")){ break; }else { os.println(sis.readLine()); os.flush(); } } } is.close(); os.close(); accept.close(); } catch (IOException e) { e.printStackTrace(); }finally { try { serverSocket.close(); } catch (IOException e) { e.printStackTrace(); } } } } Client package com.tcp; import java.io.*; import java.net.Socket; /** * 客户端 */ public class Client { public static void main(String[] args) { try { Socket socket = new Socket("127.0.0.1",12345); BufferedReader sis = new BufferedReader(new InputStreamReader(System.in)); BufferedReader is = new BufferedReader(new InputStreamReader(socket.getInputStream())); PrintWriter os = new PrintWriter(new OutputStreamWriter(socket.getOutputStream())); String line; while (true){ if ((line=sis.readLine())!=null){ if ("bye".equals(line)){ System.exit(0); } os.println(line); os.flush(); } String readLine = is.readLine(); System.out.println("收到服务端:"+readLine); } } catch (IOException e) { e.printStackTrace(); } } } UDP UDP采用Datagram(数据报)传输,数据包是一种尽力而为的传送数据的方式,它只是 把数据的目的地记录在数据包中,然后就直接放在网络上,系统不保证数据是否能安全到达,或者什么时候可以送到,它并不保证传送质量。 ...

July 30, 2019 · 2 min · zhangxiaofeng05

反射

java.lang.Class 创建一个类,通过编译(javac.exe),生成对应的.class文件。之后使用java.exe加载(JVM的类加载器完成), 此.class文件加载到内存以后,就是一个运行时类,存在缓冲区。那么这个运行时类本身就是一个Class的实例! 一个运行时类只加载一次。 举例 import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class RelfectTest{ public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException { Class<Person> personClass = Person.class; //通过反射创建对象 Person person = personClass.newInstance(); System.out.println(person); //通过反射赋值-------public属性 Field name = personClass.getField("name"); name.set(person,"土豆"); System.out.println(person); //通过反射赋值------private或者默认(不写)属性 Field age = personClass.getDeclaredField("age"); age.setAccessible(true); age.set(person,18); System.out.println(person); //通过反射调用指定方法--没有参数 Method show = personClass.getMethod("show"); show.invoke(person); //通过反射调用指定方法--有参数 Method say = personClass.getMethod("say", String.class); say.invoke(person,"welcome"); } } class Person{ public String name; private int age; public Person() { } public Person(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return name+"----"+age; } public void show(){ System.out.println("Person类的show..."); } public void say(String word){ System.out.println(name+" "+word); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } 拓展 Person类 ...

July 28, 2019 · 5 min · zhangxiaofeng05

==和equals和hashCode

==和equals == 基本类型:比较的是值是否相同; 引用类型:比较的是内存地址是否相同(是否是同一对象); equals Object类中的equals方法 public boolean equals(Object obj) { return (this == obj); } String类重写了equals方法 public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } return false; } 举例: ...

July 28, 2019 · 4 min · zhangxiaofeng05

java IO流

从控制台输入输出 import java.util.Scanner; public class IoTest { public static void main(String args[]){ Scanner sc = new Scanner(System.in); int n = sc.nextInt(); System.out.println(n); String s = sc.next(); System.out.println(s); String line = sc.nextLine(); System.out.println(line);//从控制台输出 } } 字节流 FileOutputStream import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.OutputStream; public class IoTest { public static void main(String args[]){ File file = new File("aa.txt"); try { //FileOutputStream(File,boolean) 是否把内容追加 OutputStream out = new FileOutputStream(file); String str = "Hello World"; byte[] b=str.getBytes(); out.write(b); out.close(); } catch (FileNotFoundException e) { e.printStackTrace(); }catch (Exception e){ e.printStackTrace(); } } } FileInputStream import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; public class IoTest { public static void main(String args[]){ try { File file = new File("E:"+File.separator+"tt.txt"); InputStream is = new FileInputStream(file); // byte[] bytes = new byte[1024]; //也可以这样 byte[] bytes = new byte[(int) file.length()]; is.read(bytes); System.out.println(new String(bytes)); //关闭流 is.close(); } catch (FileNotFoundException e) { e.printStackTrace(); }catch (Exception e){ e.printStackTrace(); } } } BufferedOutputStream import java.io.*; public class IoTest { public static void main(String args[]){ File file = new File("aa.txt"); try { OutputStream out = new FileOutputStream(file); BufferedOutputStream bos = new BufferedOutputStream(out); byte[] bytes = "土豆,土豆,呼叫土豆".getBytes(); bos.write(bytes); //刷新缓存 bos.flush(); bos.close(); out.close(); } catch (FileNotFoundException e) { e.printStackTrace(); }catch (Exception e){ e.printStackTrace(); } } } BufferedInputStream import java.io.*; public class IoTest { public static void main(String args[]){ try { File file = new File("E:"+File.separator+"tt.txt"); InputStream is = new FileInputStream(file); BufferedInputStream bis = new BufferedInputStream(is); byte[] bytes = new byte[(int) file.length()]; bis.read(bytes); System.out.println(new String(bytes)); bis.close(); is.close(); } catch (FileNotFoundException e) { e.printStackTrace(); }catch (Exception e){ e.printStackTrace(); } } } 字符流 FileWriter import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.Writer; public class IoTest { public static void main(String args[]){ try { File file = new File("aa.txt"); Writer writer = new FileWriter(file); writer.write("土豆。。。\n"); writer.write("地瓜,对不起"); writer.close(); } catch (IOException e) { e.printStackTrace(); } } } FileReader import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.Reader; public class IoTest { public static void main(String args[]){ try { File file = new File("aa.txt"); Reader reader = new FileReader(file); char[] chars = new char[1024]; reader.read(chars); System.out.println(new String(chars)); reader.close(); } catch (IOException e) { e.printStackTrace(); } } } 转换流(字节流转字符流) OutputStreamWriter import java.io.*; public class IoTest { public static void main(String args[]){ File file = new File("aa.txt"); try { OutputStream out = new FileOutputStream(file); OutputStreamWriter osw = new OutputStreamWriter(out); osw.write("这是字节流转成了字符流"); String encoding = osw.getEncoding(); System.out.println("文件的编码:"+encoding); //文件的编码:UTF8 osw.close(); out.close(); } catch (FileNotFoundException e) { e.printStackTrace(); }catch (Exception e){ e.printStackTrace(); } } } InputStreamReader import java.io.*; public class IoTest { public static void main(String args[]){ try { File file = new File("aa.txt"); InputStream is = new FileInputStream(file); InputStreamReader isr = new InputStreamReader(is,"utf-8");//指定编码 char[] chars = new char[1024]; isr.read(chars); System.out.println(chars); System.out.println("编码:"+isr.getEncoding()); isr.close(); isr.close(); } catch (FileNotFoundException e) { e.printStackTrace(); }catch (Exception e){ e.printStackTrace(); } } } 字符缓冲流(高效流) BufferedWriter import java.io.*; public class IoTest { public static void main(String args[]){ File file = new File("aa.txt"); try { OutputStream out = new FileOutputStream(file); OutputStreamWriter osw = new OutputStreamWriter(out); BufferedWriter bw = new BufferedWriter(osw); bw.write("hello 这是字符缓冲流"); bw.newLine(); bw.write("下一行"); bw.close(); osw.close(); out.close(); } catch (FileNotFoundException e) { e.printStackTrace(); }catch (Exception e){ e.printStackTrace(); } } } BufferedReader import java.io.*; public class IoTest { public static void main(String args[]){ try { File file = new File("aa.txt"); InputStream is = new FileInputStream(file); InputStreamReader isr = new InputStreamReader(is,"utf-8"); BufferedReader br = new BufferedReader(isr); String str; while ((str=br.readLine())!=null){ System.out.println(str); } br.close(); isr.close(); is.close(); } catch (FileNotFoundException e) { e.printStackTrace(); }catch (Exception e){ e.printStackTrace(); } } } 字节流与字符流的区别 字节流在操作的时候本身是不会用到缓冲区(内存)的,是与文件本身直接操作的,而字符流在操作的时候是使用到缓冲区的 ...

July 25, 2019 · 3 min · zhangxiaofeng05

java异常

异常类型 检查性异常 最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。 运行时异常 运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略(Throw)。 错误 错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的。 异常类Exception 构造方法 public Exception() 构建一个新的异常,以 null作为其详细信息。 public Exception(String message) 使用指定的详细消息构造新的异常。 public Exception(String message, Throwable cause) 构造一个新的异常与指定的详细信息和原因。 public Exception(Throwable cause) 构造一个新的异常与指定原因。 protected Exception(String message, Throwable cause,boolean enableSuppression,boolean writableStackTrace) 构造一个新的异常,其中包含指定的详细消息,启用或禁用抑制功能,启用或禁用可写栈跟踪。 常用方法 public String getMessage() 返回关于发生的异常的详细信息。这个消息在Throwable 类的构造函数中初始化了。 public Throwable getCause() 返回一个Throwable 对象代表异常原因。 public String toString() 使用getMessage()的结果返回类的串级名字。 public void printStackTrace() 打印toString()结果和栈层次到System.err,即错误输出流。 public StackTraceElement [] getStackTrace() 返回一个包含堆栈层次的数组。下标为0的元素代表栈顶,最后一个元素代表方法调用堆栈的栈底。 public Throwable fillInStackTrace() 用当前的调用栈层次填充Throwable 对象栈层次,添加到栈层次任何先前信息中。 处理异常 try-catch public class MyException extends Exception{ public static void main(String[] args) { try { int i=1/0; }catch (ArithmeticException e){ e.printStackTrace(); } catch (Exception e){ e.printStackTrace(); System.out.println("这是总异常"); }finally { System.out.println("无论有没有异常,都会执行。比如用于关闭数据库的连接"); } } } throws public class MyException extends Exception{ public static void main(String[] args) { MyException myException = new MyException(); try { myException.show(); } catch (Exception e) { e.printStackTrace(); } } public void show() throws Exception{//抛出去,谁调用谁处理 int i=1/0; } } 注意事项 throws在方法名后边 catch 不能独立于 try 存在。 在 try/catch 后面添加 finally 块并非强制性要求的。 try 代码后不能既没 catch 块也没 finally 块。 try, catch, finally 块之间不能添加任何代码。 ...

July 25, 2019 · 1 min · zhangxiaofeng05

Java中Date、SimpleDateFormat、Calendar

jdk1.8 import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; /** * Java 语言的Date(日期),Calendar(日历),DateFormat(日期格式)组成了Java标准的一个基本但是非常重要的部分。 */ public class StringTest { public static void main(String[] args) throws ParseException { Date currentTime = new Date(); System.out.println(currentTime); //设置时间格式 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println(simpleDateFormat.format(currentTime)); SimpleDateFormat year = new SimpleDateFormat("yyyy");//获取年----其它类似 System.out.println(year.format(currentTime)); Date date = simpleDateFormat.parse("2019-1-23 12:00:00");//把字符串转换成日期 System.out.println(simpleDateFormat.format(date)); //计算时间差currentTime-date相差多少天 Long days = (currentTime.getTime()-date.getTime())/(1000*60*60*24);//参数--毫秒 System.out.println(days); System.out.println("---------------------------利用Calendar获取时间值比较方便"); // Calendar转化为Date Calendar cal=Calendar.getInstance(); Date date1=cal.getTime(); // Date转化为Calendar Calendar cal2=Calendar.getInstance(); cal2.setTime(date); //计算某个日期是那一年的第几天 int d = cal2.get(Calendar.DAY_OF_YEAR); System.out.println(d); //一年的第几周等。。 } }

July 24, 2019 · 1 min · zhangxiaofeng05