1. Collections用法

Collections: 集合的工具类
public static <T> void sort(List<T> list) 排序,升序
public static <T> int binarySearch(List<?> list,T key) 二分查找,不存在返回负数,只能针对升序集合
public static <T> T max(Collection<?> coll) 最大值
public static void reverse(List<?> list) 反转

public static void shuffle(List<?> list) 随机打乱
public static <T> void sort(List<T> list, Comparator<? super T> c)

Collection 和Collections 区别:
  Collection: 是单列集合的根接口
  Collections: 集合的工具类

2. 比较器***

2.0 前提

通过Collections.sort()方法已经可以对一些集合实现排序功能,如下对List<Integer> list进行了排序

public class ComparableDemo {
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
list.add(100);
list.add(124);
list.add(99);
list.add(300);
Collections.sort(list);
System.out.println(list);//[99, 100, 124, 300]
}
}

此时若将集合改为List<Person>会直接报错,如下(The method sort(List<T>) in the type Collections is not applicable for the arguments (List<Person>))

排序是通过Collections.sort()方法,那么,为什么List<Integer>可以进行排序呢?我们可以去看下Collections下sort方法以及Integer源码

sort()源码部分

由此处可看出,sort内的参数类型必须是Comparable<? super T>本身或者其父类,接下来看下Integer的源码部分

可见其继承类Comparable<Integer>接口,那么如何让List<Person>类型的list也为comparable类型呢,首先想到的是继承,让Person类继承Integer类,Person就自然符合sort()方法中的参数类型了,但是有上面Integer源码可知,Integer有final修饰,其是不能被继承的,没办法,只能自己去继承并实现Comparable接口了。查看Comparable接口的源码,发现发现接口内部有个抽象方法待实现(compareTo()),而这个方法便是定义排序规则的,以便sort可以按此规则对list进行排序。这里我们先看下Integer类中是怎么实现comparable接口的,查看起源码,如下:

可见实现compareTo的方法最终返回值有三种(0,-1,1),但sort()是怎么实现这个排序的呢?(以后再去看详细的源码)

大致调用过程如下:

Collections.sort()----->list.sort()------->Arrays.sort()------>Arrays.legacyMergeSort()----->Arrays.mergeSort()   ,可见,最终是用归并排序来实现的

所以,要利用Collections.sort()对List<Person>集合进行排序,只需让Person实现Comparable接口即可(可参照Integer类)

2.1 Comparable用法

(1)

  要想让一个List可以使用Collections.sort进行排序,需要要求集合中的元素所在的类实现Comparable(java.lang)接口,实现了该接口就具备了排序的能力,才能进行排序,实现该接口我们需要重写里面的compareTo方法,该方法的主要目的就是定义排序的规则(即告诉接口按照上面规则比较大小),重写该方法时要注意,该方法返回值是int类型

  返回值为正数,表明this中的数据大于参数中的数据,排序时将大的数移至后面

  返回值为0,表明this中的数据等于参数中的数据

  返回值为负数,表明this中的数据小于参数中的id

其实就是this对象和参数对象做一个比较,this对象在前,就是升序,参数对象在前就是降序。

以下将Person去实现Comparable接口(只写出重写方法部分代码):

@Override
public int compareTo(Person o) {
return (this.age<o.age)?-1:(this.age==o.age)?0:1;
}

这样的话Collections.sort()就可以对List<Person>集合进行排序,具体如下(此处是按年龄排序)

public class ComparableDemo {
public static void main(String[] args) {
List<Person> person = new ArrayList<Person>();
person.add(new Person("zs",26,'男'));
person.add(new Person("ls",36,'男'));
person.add(new Person("xh",26,'女'));
person.add(new Person("mz",16,'女'));
Collections.sort(person);
System.out.println(person);
}
}
// 运行结果:[Person [name=mz, age=16, gender=女], Person [name=zs, age=26, gender=男], Person [name=xh, age=26, gender=女], Person [name=ls, age=36, gender=男]]

若要按姓名来排序,并且降序则compareTo方法如下:

public int compareTo(Person o) {
return o.name.compareTo(this.name);// 此处的compareTo为字符串内实现的compareTo方法
}

同样是上面的 ComparableDemo测试类,得到的结果为

[Person [name=zs, age=26, gender=男], Person [name=xh, age=26, gender=女], Person [name=mz, age=16, gender=女], Person [name=ls, age=36, gender=男]]

练习:创建一个Student类型的List:姓名,年龄,分数,排序要求:按照年龄做升序,如果年龄相同,则按照分数做降序

public class Student implements Comparable<Student>{
  String name;
  int age;
  double score;
  public Student() {

  }
  public Student(String name, int age, double score) {
    super();
    this.name = name;
    this.age = age;
    this.score = score;
  }
  @Override
  public String toString() {
    return "Student [name=" + name + ", age=" + age + ", score=" + score + "]";
  }
  //需求: 默认按照年龄的升序,如果年龄相同,按照分数的降序
  @Override
  public int compareTo(Student o) {
    if(this.age == o.age) {
  //return (int)(o.score - this.score);//这么写不好,98.6 98.7得到的结果是0
    //  会认为分数相同,就会按照添加的顺序排序,和预期不符
   return o.score - this.score>0?1:-1; } return this.age - o.age; } }

2.2  comparator用法

  1.  好了,目前我们已经掌握了如何对一个List<Person>做排序,那么我们知道了为什么List<Integer>默认实现的是升序,就是因为Integer在实现Comparable接口的时候用的就是升序的方式,如果我们想要实现降序应该怎么做呢?其实只需要将Integer中的compareTo方法中的两个参数调换一下位置就可以了,但是由于是class文件,我们是不能修改的,所以java为我们提供了一个外部比较器Comparator(java.util),这是个接口

public class ComparableDemo {
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
list.add(100);
list.add(124);
list.add(99);
list.add(300);
Collections.sort(list,new IntegerComparator());//注意此处的sort方法跟升序不是一个方法,这是提供给 comparator的重载方法,接收2个参数
System.out.println(list);//[99, 100, 124, 300]
}
}
class IntegerComparator implements Comparator<Integer>{
@Override
public int compare(Integer o1, Integer o2) {
return o2.compareTo(o1);
}
}
// 运行结果:[300, 124, 100, 99]

2. 为了简便,可进行如下改写:

  (1)使用匿名函数来实现comparator接口

Collections.sort(list, new Comparator<Integer>() {
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
});

(2)在java1.8后,可以直接调用list.sort(),不需要Collections(更加方便),如下

list.sort(new Comparator<Integer>() {
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
});

(3)使用lambda方法

list.sort((a,b)->b-a);

 3. 此处可以不用Collections.sort(),直接使用带参数的构造方法,具体如下

2  总结

 Comparator:用法:

    Collections.sort(List<List>, Comparator<>); 

 由于Comparator是一个接口,需要传入Comparator子类的对象(匿名内部类),需要重写compare,从而定义新的排序规则

    用前面的和后面的比较:升序

    用后面的和前面的比较:降序

 Comparable  和 Comparator的区别:

    Comparable:内部比较器,位于java.lang,如果一个集合想要使用Collections.sort进行排序,需要里面的元素所在类实现Comparable接口,并且重写compareTo方法实现排序

3.  TreeSet和TreeMap的用法

3.1TreeSet

  Collections.sort()只能作用于list,并不能作用于Set。Set要排序的话可以通过其子类TreeSet,TreeSet会自动对集合中的元素进行排序,同List一样,其对Person这种类型的元素做排序时,需要在这种类中实现Comparable接口,否则会出现转型异常:com._51doit.javase04.day15.tree.Person cannot be cast to java.lang.Comparable。

案例1

public class TreeSetDemo {
public static void main(String[] args) {
Set<Integer> set = new TreeSet<Integer>();
set.add(12);
set.add(15);
set.add(20);
set.add(9);
System.out.println(set);
}
}
// 运行结果:[9, 12, 15, 20]

由结果可知,TreeSet可实现自动排序

Set实现comparable接口的方式就是直接重载compareTo方法就行了,其内部是自动调用了排序方法的,但comparator则有点不一样,重写完comparator中的compare方法,直接将这个子类对象传进集合构造方法,具体如下:

public class TreeSetDemo1 {
public static void main(String[] args) {
//实现TreeSet中Integer降序
Set<Integer> set3 = new TreeSet<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
set3.add(123);
set3.add(45);
set3.add(1);
set3.add(100);
System.out.println(set3);
}
}
// 运行结果:[123, 100, 45, 1]

注意  Set里面的元素不能重复,其判断元素是否重复的原理是:根据compareTo(对comparable)/compare(对comparator)方法来验证元素是否重复,compareTo/compare返回结果是0,就认为是相同的元素,否则就不同。我们在重写compareTo/compare方法的时候,尽量不要只比较一个属性

案例2

public class TreeSetDemo {
public static void main(String[] args) { Set<Teacher> teacher = new TreeSet<Teacher>();
teacher.add(new Teacher("zs",26));
teacher.add(new Teacher("ls",36));
teacher.add(new Teacher("xh",26));
teacher.add(new Teacher("xf",26));
teacher.add(new Teacher("mz",16));
System.out.println(teacher); //并没有调用排序方法,重写compareTo方法直接打印此set集合,就会按照compareTo定义的规则排序,其内部怎么实现排序的暂不清楚
}
}
class Teacher implements Comparable<Teacher>{
String name;
int age;
public Teacher(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public int compareTo(Teacher o) {
return o.age - this.age; //按年龄降序
}
@Override
public String toString() {
return "Teacher [name=" + name + ", age=" + age + "]";
}
}
// 运行结果:[Teacher [name=ls, age=36], Teacher [name=zs, age=26], Teacher [name=mz, age=16]]

有结果可知,TreeSet直接按年龄是否相同去重了,若要不被去重,可以在compareTo中多写几个属性,如下

@Override
public int compareTo(Teacher o) {
if(o.age == this.age) {
return o.name.compareTo(this.name);//降序
}
else {
return o.age - this.age;// 降序
}
}
// 运行结果: [Teacher [name=ls, age=36], Teacher [name=zs, age=26], Teacher [name=xh, age=26], Teacher [name=xf, age=26], Teacher [name=mz, age=16]]

3.2 TreeMap

1. 概述:

TreeMap:可以对key这一列实现排序,key不能为nul(key会调用compare/compareTo方法进行排序,若为null,则会出现空指针异常),TreeMap中的key所在的类必须要实现Comparable接口,如果不想实现,则必须在构造方法中传入一个外部比较器。

key:   不能重复,其原理也是由compare/compareTo方法决定的

public class TreeMapDemo {
public static void main(String[] args) {
TreeMap<Integer,String> map = new TreeMap<>();
map.put(1,"热河");
map.put(2,"你好");
map.put(3,"再见");
//map.put(null,"热河"); 报空指针异常
System.out.println(map);
}
}
运行结果:{1=热河, 2=你好, 3=再见}

2.TreeMap实现降序

  使用外部选择器:Comparator(此处能不能通过重写comparable中的compareTo方法来实现降序呢?)

public class TreeMapDemo {
public static void main(String[] args) {
TreeMap<Integer,String> map = new TreeMap<>(new Comparator<>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
});
map.put(1,"热河");
map.put(2,"你好");
map.put(3,"再见");
System.out.println(map);
}
}

运行结果:{3=再见, 2=你好, 1=热河}

  

4. 异常

4.0 概述:  

  异常就是java程序在运行过程中出现的错误,现实生活中遇到的问题也是一个具体的事务,可以通过java类的形式进行描述,并封装成对象。其实就是java对不正常情况进行描述后的对象体现。前面见过的异常有角标越界异常,空指针异常等。

4.1 异常的层次结构:

Throwable:

  Error:程序出现的错误,不能使用程序处理,一般无需程序员关注,如内存溢出,网络连接异常

  Exception(异常):

        运行时异常:RuntimeException及其子类,可以对其进行处理,也可以不处理,往往是由于代码书写不正确或不规范造成,程序员自己去检查问题,并修改代码。

        编译时异常:除了运行时异常以外的所有异常,必须对异常进行处理,否则无法通过编译,程序无法执行往往是由于无法预估的用户操作造成的

产生异常后:代码无法向下执行

我们处理异常的目的是什么?   为了让程序能够执行下去

下面是编译时异常

4.2 异常的处理方式:

JVN处理异常的方式:

    打印异常信息并终止程序,其并不会对异常进行处理

当出现异常时,在eclipse找异常的顺序是由上往下,上面的异常一般为异常产生处,如下(先是test出现异常,再是main,而main方法出现异常是因为调用了test方法)

4.2.1  捕获:

  1.try...catch( ){  }

    格式:

       try{

         //可能出现的异常

          }catch(异常类名   对象名){

           //对异常的处理

       }

  2.try...catch...finally

    格式:   

      try{

         //可能出现的异常

          }catch(异常类名   对象名){

           //对异常的处理

       }finally{

           //一定会执行的代码

       }

注意事项:

1. catch 块中可以存在多个,并且可以有子父类的关系:
   一旦存在子父类的关系,要把子类异常放上面,因为放下面,就再也执行不到了
      catch 块中应该写的是一种备选方案
2. jdk7:一个catch 块中可以处理多个异常,多个异常之间使用 | 隔开
3. try 块中的局部变量和catch 块中的局部变量(包括异常变量),以及finally 中的局部变量,他们之间不可共享使用。
4. 每一个catch 块用于处理一个异常。异常匹配是按照catch 块的顺序从上往下寻找的,只有第一个匹配的catch 会得到执行。匹配时,不仅运行精确匹配,也支持父类匹配,因此,如果同一个try 块下的多个catch 异常类型有父子关系,应该将子类异常放在前面,父类异常放在后面,这样保证每个catch 块都有存在的意义。
5. 当一个函数的某条语句发生异常时,这条语句的后面的语句不会再执行,它失去了焦点。执行流跳转到最近的匹配的异常处理catch 代码块去执行,异常被处理完后,执行流会接着在“处理了这个异常的catch 代码块”后面接着执行。
6. finally 块不管异常是否发生,只要对应的try 执行了,则它一定也执行。只有一种方法让finally 块不执行:System.exit()。因此finally 块通常用来做资源释放操作:关闭文件,关闭数据库连接等等

public class ExceptionDemo {
public static void main(String[] args) {
Date d = null;
try {
System.out.println(1/0); // 运行时异常
}catch(Exception e1){
System.out.println("哈哈");
}
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
d = sdf.parse("1232012-09-18"); // 编译时异常
String s = null;
System.out.println(s.length()); // 空指针异常
System.out.println(1/0);
}catch(ArithmeticException | NullPointerException e) { // 1个catch块处理多个异常
System.out.println("1");
}catch(Exception e) { //此异常不能放前面,不然前面catch就不能执行了
d = new Date();
}
}
}

面试题:

  final           finalize            finally:区别:  

final:     修饰类、方法、变量,被修饰的类不能被继承,被修饰的方法不能重写,被修饰的变量值不变
finalize: 用于垃圾回收

finally:   用于异常处理,代表一定会执行的代码

4.2.2  抛出(throws)

格式:

 在方法头上:throws  异常类名{  // 类名可以有多个,多个类之间使用“,”隔开

  } 

注意:异常最终被抛给了异常的调用者

public class ExceptionDemo1 {
public static void main(String[] args) throws ParseException {// 抛给其调用者JVM
test();
}
public static void test() throws ParseException { // 抛给其调用者main方法
new SimpleDateFormat().parse("");
}
}

一般内层抛出,在最外层做统一处理(不然每调用一次出现异常的方法就要处理一次异常)

 4.3  异常中常用的方法

 4.3.1  Trowable中的方法

(1)getMessage(): 获取异常信息,返回字符串。

public class ExceptionDemo2 {
public static void main(String[] args) {
try {
new SimpleDateFormat().parse("");
}catch(ParseException e){
System.out.println(e.getMessage());
}
}
}
// 运行结果:Unparseable date: ""

(2)toString():获取异常类名和异常信息,返回字符串

System.out.println(e.toString());  // java.text.ParseException: Unparseable date: ""

(3)printStackTrace():获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void(不需要System.out.print(),自身就有打印功能)

e.printStackTrace(); // 打印异常信息,打印到控制台

运行结果:如下图

4)printStackTrace(PrintStream s):通常用该方法将异常内容保存在日志文件中,以便查阅

public class ExceptionDemo2 {
public static void main(String[] args) {
try {
new SimpleDateFormat().parse("");
}catch(ParseException e){
e.printStackTrace();
try {
e.printStackTrace(new PrintStream("f:/a/error.txt"));
}catch(FileNotFoundException e1) {
e1.printStackTrace();
}
}
}
}

4.4 throw用法

throw 不是用来处理异常的,相反是触发一个异常,或者理解成一个异常

格式:

  用在方法体中,throw异常的对象,这个对象只能有一个

throw的异常一定会发生

public class ExceptionDemo3 {
public static void main(String[] args) {
test();
}
public static void test() {
throw new NullPointerException(""); // 若加参数,在报错异常类后会出现该参数
}
}

运行结果:

若创建的是编译异常,则要抛出或者处理异常

public class ExceptionDemo3 {
public static void main(String[] args) {
try {
test();
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void test() throws ParseException {
throw new ParseException("天空之城",30); //此处的inr参数表示当编译时,错误会在那个位置发生(不大理解)
}
}

 4.5 throws和throw区别

throws:

  用在方法声明后面,跟的是异常类名;可以跟多个异常类名,用逗号隔开,表示抛出异常,由该方法的调用者来处理;throws表示出现异常的一种可能性,并不一定会发生这些异常

throw:

  用在方法体内,跟的是异常对象名;只能抛出一个异常对象名;表示抛出异常,由方法体内的语句处理;throw则是抛出了异常,执行throw则一定抛出了某种异常

 4.6 自定义异常

  定义编译时异常:继承Exception

  定义运行时异常:继承RunException

案例:人的年龄必须在1-260,显然java没有对应的异常,需要我们自己来定义一个异常,如下:

(1)定义运行时异常: 

定义一个继承自RuntimeException的异常,即运行时异常

public class MyException extends RuntimeException {
public MyException() {};
public MyException(String desc) {
super(desc);
}
}

定义测试类,以及抛出异常

public class AgeTest {
public static void main(String[] args) {
AgeException ae = new AgeException();
ae.setAge(300);
}
}
class AgeException {
int age; public int getAge() {
return age;
}
public void setAge(int age) {
if(age>=1 && age<=260) {
this.age = age;
}else {
throw new MyException("您的年龄有问题");
}
}
}

运行结果

(2)定义编译时异常:

将MyException继承自Exception即可,改完后,测试类中的年龄部分就要抛出异常或者处理异常了

 4.7  异常的注意事项

(1)子类重写父类方法时,子类的方法必须要抛出相同的异常或父类异常的子类

class FatherClass{
public void test() throws Exception{ }
}
class SonClass extends FatherClass{
public void test() throws ParseException{ }
}
若将ParseException与Exception调换则会报错:Exception Exception is not compatible with throws clause in FatherClass.test()

(2)如果父类抛出了多个异常,子类重写父类时,只能抛出相同的异常或者是它的子集,子类不能抛出父类没有的异常

(3)如果被重写的方法没有异常抛出,那么子类方法绝对不可以抛出异常,如果子类方法内有异常发生,那么子类只能try,不能throws

(4)以上异常指的都是编译时异常 

零基础学习java------day15--------collections用法,比较器,Set(TreeSet,TreeMap),异常的更多相关文章

  1. 音乐出身的妹纸,零基础学习JAVA靠谱么

    问:表示音乐出身的妹纸一枚  某一天突然觉得身边认识的是一群程序员   突然想 要不要也去试试... 众好友都觉得我该去做个老师,可是我怕我会误人子弟,祸害祖国下一代..... 要不要 要不要 学Ja ...

  2. 总结了零基础学习Java编程语言的几个基础知识要点

    很多Java编程初学者在刚接触Java语言程序的时候,不知道该学习掌握哪些必要的基础知识.本文总结了零基础学习Java编程语言的几个基础知识要点. 1先了解什么是Java的四个方面   初学者先弄清这 ...

  3. 【转】【Salesforce】salesforce 零基础学习(十七)Trigger用法

    看本篇之前可以相应阅读以下Trigger相关文章: 1.https://developer.salesforce.com/page/Trigger_Frameworks_and_Apex_Trigge ...

  4. salesforce 零基础学习(五十二)Trigger使用篇(二)

    第十七篇的Trigger用法为通过Handler方式实现Trigger的封装,此种好处是一个Handler对应一个sObject,使本该在Trigger中写的代码分到Handler中,代码更加清晰. ...

  5. 【零基础学习iOS开发】【转载】

    原文地址:http://www.cnblogs.com/mjios/archive/2013/04/24/3039357.html 本文目录 一.什么是iOS 二.主流手机操作系统 三.什么是iOS开 ...

  6. 李洪强iOS开发之【零基础学习iOS开发】【01-前言】01-开篇

    从今天开始,我就开始更新[零基础学习iOS开发]这个专题.不管你是否涉足过IT领域,也不管你是理科生还是文科生,只要你对iOS开发感兴趣,都可以来阅读此专题.我尽量以通俗易懂的语言,让每个人都能够看懂 ...

  7. 零基础学习hadoop到上手工作线路指导

    零基础学习hadoop,没有想象的那么困难,也没有想象的那么容易.在刚接触云计算,曾经想过培训,但是培训机构的选择就让我很纠结.所以索性就自己学习了.整个过程整理一下,给大家参考,欢迎讨论,共同学习. ...

  8. 【零基础学习iOS开发】【01-前言】01-开篇

    本文目录 一.什么是iOS 二.主流手机操作系统 三.什么是iOS开发 四.学习iOS开发的目的 五.学习iOS开发的前提 从今天开始,我就开始更新[零基础学习iOS开发]这个专题.不管你是否涉足过I ...

  9. salesforce 零基础学习(六十八)http callout test class写法

    此篇可以参考: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_restfu ...

  10. 零基础学习Hadoop

    零基础学习hadoop,没有想象的那么困难,也没有想象的那么容易.在刚接触云计算,曾经想过培训,但是培训机构的选择就让我很纠结.所以索性就自己学习了.整个过程整理一下,给大家参考,欢迎讨论,共同学习. ...

随机推荐

  1. Pycharm的安装简介

    Pycharm 1. Pycharm简介 PyCharm是由JetBrains打造的一款Python IDE,VS2010的重构插件Resharper就是出自JetBrains之手.同时支持Googl ...

  2. Linux cat文件正常,vim文件乱码

    cat: vim: 1.临时解决 vim 文件后,命令模式下执行: :set encoding=utf-8 2.永久解决 vi    配置文件路径:/etc/virc vim 配置文件路径:/etc/ ...

  3. Python里字符串Format时的一个易错“点”

    这是一篇很小的笔记,原因是我做学习通的时候见到了这个题: 当时看了一会儿发现没有符合自己想法的答案,然后就脑袋一热选了C,结果当然是错了... 看了一眼这个format的字符串对象,发现有个 {:7. ...

  4. pycharm基本使用与破解

    一.pycharm基本使用 pycharm这款ide软件虽然功能强大,但正因为他的强大,所以小白在刚使用这款软件时上手会有点难度,今天我们就来介绍一下ptcharm的基本使用. 1.基本配置 我们安装 ...

  5. 开发属于自己的包,并上传到npm上

    1.DIY开发包 1.1符合标准的包结构 一个规范的包,它的组成结构,必须符合以下3点要求: 包必须以单独的目录而存在 包的顶级目录下,必须包含package.json这个包管理文件 package. ...

  6. 八. Go并发编程--errGroup

    一. 前言 了解 sync.WaitGroup的用法都知道 一个 goroutine 需要等待多个 goroutine 完成和多个 goroutine 等待一个 goroutine 干活时都可以解决问 ...

  7. Cannot load module file xxx.iml的两种解决方法

    一. 一种是点击左上角File,然后点击Invalidate Caches / Restart...,弹出对话框再点击Invalidate and Restart等待工程重新加载,问题就解决了. 二. ...

  8. sql sever 约束

    SQLServer中有五种约束,Primary Key约束.Foreign Key约束.Unique约束.Default约束和Check约束 1.Primary Key约束在表中常有一列或多列的组合, ...

  9. element ui tree回显 setCheckedNodes,setCheckedKeys,setChecked等函数报undefined问题

    在写项目的时候,需要用到tree组件进行回显来进行权限控制: 在回显过程中使用回显函数会报报undefined, 这时只需要给该函数包裹一层nextTick方法就行了, 在回显过程中我们有可能使用半选 ...

  10. Elasticsearch写入数据的过程是什么样的?以及是如何快速更新索引数据的?

    前言 最近面试过程中遇到问Elasticsearch的问题不少,这次总结一下,然后顺便也了解一下Elasticsearch内部是一个什么样的结构,毕竟总不能就只了解个倒排索引吧.本文标题就是我遇到过的 ...