赞
踩
原来的HashMap采用的数据结构是哈希表(数组+链表),HashMap默认大小是16,一个下标0-15的数组,往里面存储元素时,首先调用元素的hashcode()方法,计算出哈希值,经过哈希算法找到对应的数组的索引,如果对应索引没有存放元素则直接存放,如果已经有元素了,(发生碰撞,equals方法就是碰撞时才会执行的方法)–那么调用它们的equals方法比较内容(key),如果内容一样,则后面的value值代替前者的value值;如果内容不同,则后加的放在前面,(挂在下面),形成一个链表。
这种情况下,如果链表无限下去,效率极低,碰撞避免不了
1.8之后,在数组+链表+红黑树来实现hashMap,当碰撞的元素个数大于8时或总容量大于64,会有红黑树的引入。
函数式接口不同于普通接口,接口中只有一个抽象方法是需要我们去实现的,Lambda表达式正好是针对这个唯一的抽象方法使用
public class TreeSetTest { public static void main(String[] args) { //创建实现Comparator接口的匿名类对象,对象方法的参数和返回值类型均为Integer类型 Comparator<Integer> cpt1 = new Comparator<Integer>() { //接口里有唯一方法,可以用匿名内部类来创建实现接口的类 @Override public int compare(Integer o1, Integer o2) { //Integer中封装了比较大小的方法compare return Integer.compare(o1, o2); } }; /**使用lambda表达式 *创建实现Comparator接口的类的对象,重写接口的方法 *(x,y)实现方法参数,Integer.compare(x,y)方法实现 * 只需要写参数名和方法实现。因为方法名唯一已经知道了 */ Comparator<Integer> cpt2 = (x, y) -> Integer.compare(x, y); //每插入一条数据,就用比较器来比较一次 //TreeSet内部元素有序、不可重复 TreeSet<Integer> set = new TreeSet<>(cpt1); set.add(1); set.add(3); set.add(2); set.add(6); System.out.println(set); System.out.println("========================="); } }
//自己重写Comparator中的compare方法,变成比较学生成绩的比较器
Comparator<Student>cs = (s1,s2)-> ((s1.grade < s2.grade) ? -1 : (s1.grade == s2.grade) ? 0 : 1);
TreeSet<Student>treeSet = new TreeSet<>((Comparator) cs);
treeSet.add(new Student(78));
treeSet.add(new Student(68));
treeSet.add(new Student(58));
treeSet.add(new Student(88));
for (Student student:treeSet
) {
System.out.println(student);
}
interface TestInterface { //此处默认会是public static final修饰的,如果你修改,会有错误提示 String test= "test"; static void test1(){//此处有方法体 System.out.println("我是interface中的static修饰的方法体"); } default void test2(){ //此处有方法体 System.out.println("我是interface中的default修饰的方法体"); } } public class TestInterface8 implements TestInterface{//一个类实现接口,相当于继承这个方法里的default方法 public static void main(String[] args) { //接口中的方法不一定都是abstract TestInterface8 a=new TestInterface8(); //继承接口中的default方法test2 a.test2(); //接口里的static方法可以直接类名.方法来调用 TestInterface.test1(); } }
如上代码,jdk1.8之后,接口中的方法不再都是抽象方法,接口中的方法可以通过 static或者defalut修饰,并且可以拥有方法体。通过static修饰的方法,可以有方法体,实现接口的类,可以直接通过接口类.方法来调用 ;通default修饰的方法,可以有方法体,实现接口的类,可通过创建接口类的对象,通过对象调用default方法
这是JDK8中为了加强接口的能力,使得接口可以存在具体的方法,前提是方法需要被default或static 关键字所修饰。这样做的好处是接口的每个实现类如果都想要相同的功能,就不需要重复代码,而是在接口进行定义即可 。默认方法在子类也可以被重写。
interface 的设计初衷是面向抽象,提高扩展性。这也留有一点遗憾,Interface 修改的时候,实现它的类也必须跟着改。于是1.8之后,interface中修改方法,可以加static或default修饰,这样子类不用一定要实现,并且可以直接调用
Stream的创建
//通过集合创建 List<String> list = Arrays.asList("a", "b", "c"); // 创建一个顺序流 Stream<String> stream = list.stream(); //通过数组创建 int[] array={1,3,5,6,8}; IntStream stream = Arrays.stream(array); //通过Stream的静态方法: of(),iterate(),generate() Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6); Stream<Integer> stream2 = Stream.iterate(0, (x) -> x + 3).limit(4); stream2.forEach(System.out::println); Stream<Double> stream3 = Stream.generate(Math::random).limit(3); stream3.forEach(System.out::println);
遍历/匹配
List<Integer> list = Arrays.asList(7, 6, 9, 3, 8, 2, 1);
// 遍历输出符合条件的元素。 遍历输出x>6的元素
list.stream().filter(x -> x > 6).forEach(System.out::println);
// 匹配第一个
Optional<Integer> findFirst = list.stream().filter(x -> x > 6).findFirst();
// 是否包含符合特定条件的元素
boolean anyMatch = list.stream().anyMatch(x -> x > 6);
筛选filter
List<Integer> list = Arrays.asList(6, 7, 3, 8, 1, 2, 9);
//筛选大于6的元素并打印出来
list.stream()
.filter(x->x>6)
.forEach(System.out::println);
/** * 函数式接口:只包含一个抽象方法的接口,称为函数式接口 * 通过 Lambda 表达式来创建该接口的对象 * 可以通过@FunctionalInterface注解检查它是否是一个函数式接口,也可以省略 */ @FunctionalInterface interface Haha { public int test(int a, int b); } public class FunInter { public static void main(String[] args) { /** 1.调用Haha接口的test方法 2.该方法用lambda表达式实现test方法 3.在lambda表达式中(a,b)表示方法的参数,a+b为方法的实现 */ Haha haha = (a, b) -> a + b; System.out.println(haha.test(2, 5)); //System.out.println(((Haha)(a, b) -> a + b).test(2, 5)); } }
//Integer类 public final class Integer { public static int parseInt(String s) throws NumberFormatException { return parseInt(s,10); } } //User类 public class User { private String username; private Integer age; public User() { } public User(String username, Integer age) { this.username = username; this.age = age; } @Override public String toString() { return "User{" + "username='" + username + '\'' + ", age=" + age + '}'; } // Getter&Setter } /* 三种::引用方式 */ public static void main(String[] args) { // 使用双冒号::来构造静态函数引用 。创建实现Function接口的对象 //通过类名::静态方法名 Function<String, Integer> fun = Integer::parseInt; Integer value = fun.apply("123"); System.out.println(value); // 使用双冒号::来构造非静态函数引用 //通过 实例对象名::实例方法名 创建实现Function接口的对象 String content = "Hello JDK8"; Function<Integer, String> func = content::substring; String result = func.apply(1); System.out.println(result); // 构造函数引用 //通过 类名::new 创建实现 BiFunction接口的对象 BiFunction<String, Integer, User> biFunction = User::new; User user = biFunction.apply("mengday", 28); System.out.println(user.toString()); // 函数引用也是一种函数式接口,所以也可以将函数引用作为方法的参数 sayHello(String::toUpperCase, "hello"); } // 方法有两个参数,一个是 private static void sayHello(Function<String, String> func, String parameter){ String result = func.apply(parameter); System.out.println(result); }
package day01; class Person { String firstName; String lastName; Person() { System.out.println("Person()被调用"); } Person(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; System.out.println("Person(String firstName, String lastName)被调用"); System.out.println("firstName =" + firstName); System.out.println("lastName =" + lastName); } } /** * PersonFactory接口的方法形参类型为String类型,返回值为Person类型 */ interface PersonFactory<String, Person> { public Person create(String firstName, String lastName); } public class PerFa { public static void main(String[] args) { System.out.println("使用匿名类创建接口的对象"); PersonFactory<String, Person> personFactory1 = new PersonFactory<String, Person>() { @Override public Person create(String firstName, String lastName) { return new Person(firstName, lastName); } }; Person person1 = personFactory1.create("li", "sa"); System.out.println(person1); System.out.println("*****************************"); System.out.println("使用lambda表达式创建接口的对象"); PersonFactory<String, Person> personFactory2 = (firstName, lastName) -> new Person(firstName, lastName); Person person2 = personFactory2.create("zhang", "san"); System.out.println(person2); System.out.println("*****************************"); /** 使用构造方法引用创建接口的对象 使用 Person::new 来获取Person类构造函数的引用,(new Person) Java编译器会自动根据PersonFactory.create方法的签名来选择合适的构造函数 */ System.out.println("使用构造方法引用创建接口的对象"); //根据接口的方法的参数类型来自动选择合适的构造函数 PersonFactory<String, Person> personFactory3 = Person::new; Person person3 = personFactory3.create("Peter", "Parker"); System.out.println(person3); } }
非线程安全
时区处理麻烦
各种格式化、和时间计算繁琐
设计有缺陷,Date类同时包含日期和时间;还有一个java.sql.Date,容易混淆
LocalDateTime.class //日期+时间 format: yyyy-MM-ddTHH:mm:ss.SSS
LocalDate.class //日期 format: yyyy-MM-dd
LocalTime.class //时间 format: HH:mm:ss
public void newFormat(){ //format yyyy-MM-dd 日期 LocalDate date = LocalDate.now(); System.out.println(String.format("date format : %s", date)); //format HH:mm:ss 时间 LocalTime time = LocalTime.now().withNano(0); System.out.println(String.format("time format : %s", time)); //format yyyy-MM-dd HH:mm:ss 时间+日期 LocalDateTime dateTime = LocalDateTime.now(); DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); String dateTimeStr = dateTime.format(dateTimeFormatter); System.out.println(String.format("dateTime format : %s", dateTimeStr)); }
LocalDate date = LocalDate.of(2021, 1, 26);
LocalDate.parse("2021-01-26");
LocalDateTime dateTime = LocalDateTime.of(2021, 1, 26, 12, 12, 22);
LocalDateTime.parse("2021-01-26 12:12:22");
LocalTime time = LocalTime.of(12, 12, 22);
LocalTime.parse("12:12:22");
public void getDayNew() {
LocalDate today = LocalDate.now();
//获取当前月第一天:
LocalDate firstDayOfThisMonth = today.with(TemporalAdjusters.firstDayOfMonth());
// 取本月最后一天
LocalDate lastDayOfThisMonth = today.with(TemporalAdjusters.lastDayOfMonth());
//取下一天:
LocalDate nextDay = lastDayOfThisMonth.plusDays(1);
//当年最后一天
LocalDate lastday = today.with(TemporalAdjusters.lastDayOfYear());
//2021年最后一个周日
LocalDate lastMondayOf2021 = LocalDate.parse("2021-12-31").with(TemporalAdjusters.lastInMonth(DayOfWeek.SUNDAY));
}
Date----> LocalDate
Time----> LocalTime
Timestamp---->LocalDateTime
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。