1、常用时间函数
a、获取当前的时间
public class Person {
public static void main(String[] args) throws ParseException {
Date date = new Date();
System.out.println(date.getTime()); //获取当前的时间截
DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String str = format.format(date.getTime());//把当前的时间截转成固定的时间格式
System.out.println(str);
Date d1 = format.parse(str);//把固定格式的时间转成系统时间格式
System.out.println(d1);
}
}
b、获取当前日期
public class Person {
public static void main(String[] args) throws ParseException {
DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d1 = format.parse("2014-05-20 20:50:12");
Calendar cal = Calendar.getInstance(); //日历类的单例模式
cal.setTime(d1); //设置日期时间
System.out.println(cal.get(Calendar.YEAR)); //获取日期的年
System.out.println(cal.get(Calendar.MONTH) + 1);//获取日期的月
System.out.println(cal.get(Calendar.DATE)); //获取日期的日期
...
}
}
注意: Calendar cal = GregorianCalendar.getInstance(); 这个是获取格林尼治的时间 是Calendar的一个子类
在求每个月的最后一天时,可以把日期设置为0,那么就可以求出每个月的最后一天了
package site.ieven;
import java.util.Calendar;
public class FirstJava {
public static void main(String[] args) {
Calendar c1 = Calendar.getInstance();
c1.set(2017, Calendar.MARCH, 1);
System.out.println(c1.get(Calendar.YEAR));
System.out.println(c1.get(Calendar.MONTH));
System.out.println(c1.get(Calendar.DATE));
// 往前加年
c1.add(Calendar.YEAR, 4);
System.out.println(c1.get(Calendar.YEAR));
// 往后减年
c1.add(Calendar.YEAR, -2);
System.out.println(c1.get(Calendar.YEAR));
}
}
c、java8中LocalDate的使用
public static void main(String[] args) {
LocalDate ld = LocalDate.now(); //如果有指定日期,那么就用 LocalDate.of(2019, 3, 15);来指定
String str = "当前时间是%d-%d-%d";
String reStr = String.format(str, ld.getYear(), ld.getMonthValue(), ld.getDayOfMonth());
System.out.println(reStr); // 输出 当前时间是2020-7-21
System.out.println(ld.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))); // 输出 2020-07-21
System.out.println(ld.format(DateTimeFormatter.BASIC_ISO_DATE)); //输出 20200721
System.out.println("默认输出的时间" + ld.toString()); //输出 默认输出的时间2020-07-21
LocalDate td = LocalDate.of(2011, 10,12);
LocalDate bd = ld.with(td); //返回复制的时间
System.out.println("月份的单词" + ld.getMonth()); //输出 月份的单词JULY
System.out.println("返回此日期表示的月份长度:" + ld.lengthOfMonth()); //输出 返回此日期表示的月份长度:31
System.out.println("返回此日期表示的年份的长度:" + ld.lengthOfYear()); //输出 返回此日期表示的年份的长度:366
System.out.println("这个一年中的第几天:" + ld.getDayOfYear()); //输出 这个一年中的第几天:203
System.out.println("今年是否是闰年" + ld.isLeapYear()); //输出 今年是否是闰年true
System.out.println("今天是否在2011年10月12日之前:" + ld.isBefore(bd)); //输出 今天是否在2011年10月12日之前:false
System.out.println("今天是否在2011年10月12日之后:" + ld.isAfter(bd)); //输出 今天是否在2011年10月12日之后:true
System.out.println("今天是否是2011年10月12日:" + ld.isEqual(bd)); //输出 今天是否是2011年10月12日:false
DayOfWeek dayOfWeek = ld.getDayOfWeek();
System.out.println("输出今年是星期几: " + dayOfWeek); //输出 输出今年是星期几: TUESDAY
System.out.println("输出数字的星期几: " + dayOfWeek.getValue()); //输出 输出数字的星期几: 2
}
d、LocalTime的使用
public static void main(String[] args) {
LocalTime lt = LocalTime.now();
System.out.println("手动格式化的时间是" + lt.format(DateTimeFormatter.ofPattern("HH:mm:ss")));
System.out.println(lt.toString());
System.out.println(lt.format(DateTimeFormatter.ISO_LOCAL_TIME));
System.out.println("当前的小时数:" + lt.getHour());
System.out.println("当前的分钟数:" + lt.getMinute());
System.out.println("当前的秒数是:" + lt.getSecond());
}
输出
手动格式化的时间是07:46:37
07:46:37.877324400
07:46:37.8773244
当前的小时数:7
当前的分钟数:46
当前的秒数是:37
e、LocalDateTime的使用
LocalDateTime ,是 LocalDate 和 LocalTime 的合体。它同时表示了日期
和时间,但不带有时区信息,你可以直接创建,也可以通过合并日期和时间对象构造,如下所示:
/**
* LocalDateTime ,LocalDate ,LocalTime 互相转换
*/
@Test
public void test5(){
String date = "2017-11-23";
String time = "15:51:30";
LocalDate localDate = LocalDate.parse(date);
LocalTime localTime = LocalTime.parse(time);
LocalDateTime localDateTime = LocalDateTime.of(2017, 11, 23, 16, 01, 30, 888);
LocalDateTime localDateTime1 = LocalDateTime.of(localDate, localTime);
//localDateTime-->LocalDate,LocalTime
LocalDate localDate1 = localDateTime.toLocalDate();
LocalTime localTime1 = localDateTime.toLocalTime();
// LocalDate,LocalTime --> LocalDateTime
LocalDateTime localDateTime2 = localDate.atTime(16, 02, 30);
LocalDateTime localDateTime3 = localTime.atDate(localDate);
}
f、日期的其他一些操作
@Test
public void test7(){
LocalDate date = LocalDate.of(2014, 12, 18);
LocalDate date2 = date.withYear(2017);
System.out.println(date2);//2017-12-18
LocalDate date3 = date2.withDayOfMonth(25);
System.out.println(date3);//2017-12-25
LocalDate date4 = date3.with(ChronoField.MONTH_OF_YEAR, 9);
System.out.println(date4);//2017-09-25
}
@Test
public void test8(){
LocalDate date1 = LocalDate.of(2014, 3, 18);
LocalDate date2 = date1.plusWeeks(1);
System.out.println(date2);//2014-03-25
LocalDate date3 = date2.plusYears(3);
System.out.println(date3);//2017-03-25
LocalDate date4 = date3.plus(6, ChronoUnit.MONTHS);
System.out.println(date4);//2017-09-25
}
g、使用 TemporalAdjuster 调整时间对象的策略
以使用重载版本的 with 方法,向其传递一个提供了更多定制化选择的 TemporalAdjuster 对象,
更加灵活地处理日期。对于最常见的用例,日期和时间API已经提供了大量预定义的
TemporalAdjuster 。你可以通过 TemporalAdjuster 类的静态工厂方法访问它们,如下所示:
@Test
public void test9(){
LocalDate date = LocalDate.of(2017, 11, 23);
//调整日期到本周日
LocalDate localDate = date.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
System.out.println(localDate);//2017-11-26
//调整日期到本月最后一天
LocalDate localDate1 = localDate.with(TemporalAdjusters.lastDayOfMonth());
System.out.println(localDate1);//2017-11-30
}
进行自定义函数
@Test
public void test10() {
LocalDate date = LocalDate.of(2017, 11, 23);
TemporalAdjuster nextWorkingDay = TemporalAdjusters.ofDateAdjuster(
temporal -> {
//读取当前天数
DayOfWeek dow = DayOfWeek.of(temporal.get(ChronoField.DAY_OF_WEEK));
//正常情况增加1天
int dayToAdd = 1;
//如果当天是周五,增加三天
if (dow == DayOfWeek.FRIDAY) {
dayToAdd = 3;
}
//如果当天是周六增加两天
if (dow == DayOfWeek.SATURDAY) {
dayToAdd = 2;
}
//增加恰当的天数后,返回修改的日期
return temporal.plus(dayToAdd, ChronoUnit.DAYS);
});
date = date.with(nextWorkingDay);
}
告知指定类型进行日期解析
LocalDate localDate = LocalDate.parse("20171123", DateTimeFormatter.BASIC_ISO_DATE);
System.out.println(localDate);//2017-11-23
LocalDate localDate1 = LocalDate.parse("2017-11-23", DateTimeFormatter.ISO_LOCAL_DATE);
System.out.println(localDate1);//2017-11-23
LocalDate ld = LocalDate.parse("2020年10月12日", DateTimeFormatter.ofPattern("yyyy年MM月dd日"));
System.out.println(ld); //2020-10-12
2、枚举类的简单使用
package com.yfbill.test;
public enum EnumEvent {
FIRST("red", 1),
SECOND("blue", 2),
THIRD("yellow", 3); //注意这里的最后一个是分号
private String color;
private int number;
public String ask = "are you ok???";
//注意这里的构造方法是私有的 private
private EnumEvent(String color, int number) {
this.color = color;
this.number = number;
}
public String getColor() {
return this.color;
}
public int getNumber() {
return this.number;
}
}
调用
System.out.println(EnumEvent.FIRST.getColor()); //输出 red
System.out.println(EnumEvent.FIRST.getNumber()); //输出 1
System.out.println(EnumEvent.FIRST.ask); //输出 are you ok???
System.out.println(EnumEvent.FIRST.name()); //输出FIRST
enum类也是可以实现接口
package com.yfbill.test;
interface IEnumEvent {
public String getColor();
}
public enum EnumEvent implements IEnumEvent {
...
}
3、java的集合框架 ---List
a、ArrayList类的常用api
ArrayList 类型中只能放入引用类型,而不能放入int的基础类型,如果需要放入int,那么可以作用包装类,如果Integer
public static void main(String[] args) {
//ArrayList的添加功能
ArrayList arr = new ArrayList();
arr.add("first");
arr.add(0, "zero");
ArrayList list = new ArrayList();
list.add("second");
arr.addAll(list);
arr.addAll(0, list);
//ArrayList 的删除功能
arr.removeAll(list);
arr.removeIf(item -> item == "second");
arr.remove(1);
arr.remove("second");
arr.clear();
// 查找指定的索引
arr.indexOf("first")
//ArrayList的修改操作, set只能修改现有的,而不能做为新增的存在
arr.set(0, "unknow");
//ArrayList 的查询功能
System.out.println(arr.size());
System.out.println(arr.isE mpty());
System.out.println(arr.contains("first"));
System.out.println(arr.containsAll(list));
System.out.println(arr.get(1));
System.out.println(arr.indexOf("first"));
System.out.println(arr.lastIndexOf("first"));
System.out.println(arr.subList(2,4)); //截取指定下标范围的项
//ArrayList的遍历
arr.forEach(item -> System.out.println(item));
}
public class CountDate {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(10, 3, 7, 4, 2, 6, 5, 9, 1, 8);
// 也可以使用 new ArrayList(){{add(1); add(2)...}}来实例化
ArrayList<Integer> arr = new ArrayList<Integer>(list);
//匿名内部类
list.sort(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
return (Integer)o1 - (Integer)o2 ;
}
});
System.out.println(list);
System.out.println(arr);
}
}
ArrayList<Integer> arr = new ArrayList<>(Arrays.asList(2,4,5,3,1,7,6,9,8));
arr.sort(Comparator.comparingInt((Integer a) -> a));
b、LinkedList的常用API
public class Test {
public static void main(String[] args) {
LinkedList<Integer> list = new LinkedList<>(Arrays.asList(1,2,3,4,5));
ArrayList<Integer> arr = new ArrayList<>(Arrays.asList(7,8,9,10));
//添加的功能
list.add(6);
list.add(0, 0);
list.addAll(arr);
list.addAll(0, arr);
list.addFirst(11);
list.addLast(12);
list.offer(520);
list.offerFirst(110);
list.offerLast(220);
list.push(888);
//删除的功能
// list.clear();
list.remove(12);
list.removeFirst();
list.removeLast();
list.removeAll(arr);
list.remove(0);
list.removeIf(val -> val< 3);
System.out.println(list.poll());
System.out.println(list.pollFirst());
System.out.println(list.pollLast());
System.out.println(list.pop());
//修改功能
list.set(0, 1213);
//查询功能
System.out.println(list.peek());
System.out.println(list.peekFirst());
System.out.println(list.peekLast());
System.out.println(list.size());
System.out.println(list.subList(0,1));
System.out.println(list.indexOf(12));
System.out.println(list.lastIndexOf(12));
System.out.println(list.get(0));
System.out.println(list.getFirst());
System.out.println(list.getLast());
//排序功能
list.sort(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 -o2;
}
});
System.out.println(list);
}
}
ArrayList与LinkedList的区别:
ArrayLis实现了长度可变的数组,在内存中分配连续的空间。
优点:遍历元素和随机访问元素的效率比较高
缺点:添加和删除需要大量移动元素效率低,按照内容查询效率底
LinkedList采用的是链表的存储方式
优点:插入,删除元素时效率高(LinkedList无需扩容, 只要内存足够)
缺点:遍历和随机访问效率低
c、Vector的常见API(具体的API与上面的相近)
1、Vector也是List接口的子类实现
2、Vector跟ArrayList一样,底层都是使用数组进行实现的
3、Vector与ArrayList的区别:
ArrayList是线程不安全的,效率高,Vector是线程安全的,但是效率低
ArrayList进行扩容的时候,是扩容1.5倍, Vector扩容的时候扩容原来的2倍
Vector可设置每次扩容的容量
d、集合的迭代器
所有的集合类都默认实现了Iterator的接口,实现此接口意味着具备了增强for循环的功能, 增强for循环本质上使用的是iterator的功能
方法:iterator()
foreach()
在Iterator的方法中,要求返回一个Iterator的接口子类实例对象
此接口中包含了
hasNext()
next()
public class Test {
public static void main(String[] args) {
ArrayList<Integer> arr = new ArrayList<>(Arrays.asList(2,4,5,3,1,7,6,9,8));
Iterator iter = arr.iterator();
//方法一
while(iter.hasNext()) {
System.out.println(iter.next());
}
//方法二
for(Integer item: arr) {
System.out.println(item);
}
//方法三
arr.forEach((Integer itemx) -> {
System.out.println(itemx);
});
}
}
ListIterator的相关操作, 注意,在遍历删除的时候不能直接用数组进行remove这个会报错误的,必须按官方给出的方法进行遍历删除,注意Iterator的指针指向, 因此推荐使用下面的那第二个方法
public class Test {
public static void main(String[] args) {
ArrayList<Integer> arr = new ArrayList<>(Arrays.asList(2,4,5,3,1,7,6,9,8));
ListIterator iter = arr.listIterator();
while(iter.hasNext()) {
if((int)iter.next() > 5) {
iter.remove();
}
}
System.out.println(arr);
}
}
因为在不同的作用域里面,因此可以不考虑指针的问题
public class Test {
public static void main(String[] args) {
Set<Integer> list = new HashSet<>(Arrays.asList(1,2,3,4,5,6,7));
System.out.println(list);
for(Iterator<Integer> iter = list.iterator(); iter.hasNext();) {
System.out.println(iter.next());
}
for (Integer integer : list) {
System.out.println(integer);
}
}
}
注意:在两个对象比对值的时候需要重写equals这个方法,从而达到只比较里面的属性的预期
public class Dog {
private final String name;
private final int age;
public Dog(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Dog dog = (Dog) o;
return age == dog.age &&
Objects.equals(name, dog.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
4、java的集合框架 ---Set
HashSet:采用Hashtable哈希表存储结构
--优点:添加速度快,查询速度快,删除速度快
--缺点:无序
--LinkedHashSet
--采用哈希表存储结构 ,同时使用链表维护次序
--有序(添加顺序)
TreeSet:采用二叉树(红黑树)的存储结构
--优点:有序(排序后的升序)查询速度比List快
--缺点:查询速度没有HashSet快
hashSet 对应的API
public class Test {
public static void main(String[] args) {
HashSet<Integer> list = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5, 6));
HashSet<Integer> arr = new HashSet<>(Arrays.asList(10, 11, 12, 13));
HashSet<Integer> third = new HashSet<>(Arrays.asList(1, 2, 4, 6, 8, 10));
//添加数据
list.add(7);
list.addAll(arr);
//删除数据
list.remove(4);
list.removeAll(arr);
list.removeIf((Integer item) -> item > 5);
//查询数据
System.out.println(list.size());
System.out.println(list.contains(5));
System.out.println(list.containsAll(arr));
System.out.println(list.isEmpty());
System.out.println(list.retainAll(third)); //取交集,并且赋值给list
//迭代器
for(Integer item: list) {
System.out.println(item);
}
list.forEach((Integer item) -> System.out.println(item));
System.out.println(list);
}
}
LinkedHashSet对应的API与HashSet相似
TreeSet对应的API
public static void main(String[] args) {
TreeSet<Integer> list = new TreeSet<>(Arrays.asList(1, 20, 3, 4, 5));
HashSet<Integer> arr = new HashSet<>(Arrays.asList(10, 11, 12));
//添加数据
list.add(6);
list.addAll(arr);
//删除数据
list.remove(4);
list.removeAll(arr);
list.pollFirst();
list.pollLast();
list.clear();
//查询数据
System.out.println(list.first());
System.out.println(list.last());
System.out.println("长度是:" + list.size());
System.out.println(list.ceiling(4)); //比指定数字大的最小值 包含指定的数字
System.out.println(list.floor(3)); //比指定数字小的最大值 包含指定的数字
System.out.println(list.lower(3)); //不包含指定的数据
System.out.println(list.higher(3)); //不包含指定的数据
System.out.println(list.isEmpty());
System.out.println(list.headSet(5)); //返回比指定数字小的所有序列
System.out.println(list.headSet(5, true)); //返回比指定数字小的所有序列包含指定的数
}
}
TreeSet树中的元素是要默认进行排序操作的,如果是基本数据类型,自动比较,但如果是引用类型的情况,那么该引用类型必须实现comparable的接口或者通过外部比较器来实现,这样系统就会根据自定义的方法进行排序, 否则程序会报错
比较器分类:
内部比较器:定义在元素的类中,通过实现comparabler接口实现
package com.yfbill.test;
public class Bill<E> implements Comparable<E> {
private final String name;
private final int age;
public Bill(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Bill{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
/**
* 重写comparable接口里的方法
* @param o
* @return
*/
@Override
public int compareTo(Object o) {
return this.age - ((Bill)o).age;
}
}
调用
public class Test {
public static void main(String[] args) {
TreeSet<Bill> tree = new TreeSet<>();
tree.add(new Bill("aaa", 12));
tree.add(new Bill("bbb", 13));
tree.add(new Bill("ccc", 10));
System.out.println(tree);
}
}
外部比较器:定义在当前调用的类中,通过comparator接口来实现,但是要将该比较器传递到集合中
public class Test implements Comparator<Bill> {
public static void main(String[] args) {
TreeSet<Bill> tree = new TreeSet<>(new Test());
tree.add(new Bill("aaa", 12));
tree.add(new Bill("bbb", 13));
tree.add(new Bill("ccc", 10));
System.out.println(tree);
}
@Override
public int compare(Bill o1, Bill o2) {
return o1.getAge() - o2.getAge();
}
}
public class Test{
public static void main(String[] args) {
TreeSet<Bill> tree = new TreeSet<>(new Comparator<Bill>() {
@Override
public int compare(Bill o1, Bill o2) {
return o1.getAge() - o2.getAge();
}
});
tree.add(new Bill("aaa", 12));
tree.add(new Bill("bbb", 13));
tree.add(new Bill("ccc", 10));
System.out.println(tree);
}
}
public class Test{
public static void main(String[] args) {
TreeSet<Bill> tree = new TreeSet<>((Bill a, Bill b) -> a.getAge() - b.getAge());
tree.add(new Bill("aaa", 12));
tree.add(new Bill("bbb", 13));
tree.add(new Bill("ccc", 10));
System.out.println(tree);
}
}
注意:外部比较器可以定义成一个工具类,此时如果需要比较的规则一致的话,可以利用,而内部比较器只有在存储当前对象的时候才可以使用, 如果内部比较器和外部比较器同时存在的情况,那么系统会默认使用外部比较器
Hashset操作之如何保证元素的唯一性
通过元素的两个方法, hashCode和equals方法来完成,如果元素的HashCode值相同,才会判断equals是否为true,如果元素的hashCode值不同,不会调用equals方法,
如果需要使不同对象只比对值,那么需要重写 equal方法与hashCode方法Object.hash(name, age), 注意:只要重写了equal方法,就需要重写hashcode方法