Java中的“规范形式”或“规范表示”是什么意思?


90

我经常听到这个词被使用,但是我从来没有真正理解过。

这是什么意思,有人可以举一些例子/为我指出一些链接吗?

编辑:谢谢大家的答复。您还可以告诉我,如有效Java中所述,规范表示形式对equals()性能有何帮助?

Answers:


56

维基百科指向术语规范化

一种将具有多个可能表示的数据转换为“标准”规范表示的过程。可以这样做以比较不同表示形式的等效性,计算不同数据结构的数量,通过消除重复计算来提高各种算法的效率,或者可以强加有意义的排序顺序。

Unicode的例子才是最有意义的对我说:

Unicode标准中的可变长度编码,尤其是UTF-8,对于大多数常见字符具有多种可能的编码。由于必须考虑每个字符串字符的每种可能的编码,因此这会使字符串验证更加复杂。并非所有字符编码都考虑在内的软件实现都有接受接受在应用程序设计中视为无效的字符串的风险,这可能会导致错误或允许攻击。解决方案是允许对每个字符进行单一编码。然后规范化是将每个字符串字符转换为其唯一允许的编码的过程。另一种选择是软件确定字符串是否规范化,然后将其拒绝。在这种情况下,在客户端/服务器上下文中,规范化将是客户端的责任。

总之,是数据表示的标准形式。然后,您可以从此表格转换为您可能需要的任何表示形式。


64

我相信规范有两种相关用法:形式和实例。

规范形式的装置的特定类型的资源的值可以描述或以多种方式来表示,并且这些方式中的一种被选择作为有利规范形式。(即形式推崇,如书籍,使得它进入圣经,和其它形式都没有。)规范形式的一个典型的例子是在一个分级文件系统,其中,单个文件可以以多种方式来引用路径:

myFile.txt                                   # in current working dir
../conf/myFile.txt                           # relative to the CWD
/apps/tomcat/conf/myFile.txt                 # absolute path using symbolic links
/u1/local/apps/tomcat-5.5.1/conf/myFile.txt  # absolute path with no symlinks

该文件的规范表示形式的经典定义是最后一个路径。如果没有上下文信息,就无法使用本地或相对路径来全局标识资源。使用绝对路径,您可以标识资源,但是无法确定两个路径是否引用同一实体。将两个或多个路径转换为标准格式后,您可以执行上述所有操作,并确定两个资源是否相同(如果这对您的应用程序很重要)(解决别名问题)。

请注意,资源的规范形式不是该特定形式本身的质量;对于给定类型,可能有多种可能的规范形式,例如文件路径(例如,按字典顺序,首先列出所有可能的绝对路径)。出于特定的应用原因,只是选择一种形式作为规范形式,或者可以任意选择,以便每个人都说相同的语言。

强制对象进入其规范实例是相同的基本思想,但不是确定资源的一种“最佳”表示,而是随意选择与规范引用具有相同“内容”的一类实例的一个实例,然后转换所有引用等效对象以使用一个规范实例。

这可用作优化时间和空间的技术。如果应用程序中有多个等效对象的实例,则通过强制将它们全部解析为特定值的单个规范实例,可以消除每个值中的一个(除一个)之外的所有值,从而节省空间和时间,因为您现在可以比较那些具有引用标识(==)的值,而不是对象等效项(equals()方法)。

使用规范实例优化性能的经典示例是折叠具有相同内容的字符串。String.intern()确保以相同的字符序列调用两个字符串可以为该文本返回相同的规范String对象。如果通过该规范化程序传递所有字符串,则知道等效字符串实际上是相同的对象引用,即别名

Java 5.0+中的枚举类型强制特定枚举值的所有实例在VM中使用相同的规范实例,即使该值已序列化和反序列化也是如此。因此if (day == Days.SUNDAY),如果Days枚举类型可以在Java中不受惩罚地使用。当然可以在自己的课堂上这样做,但是要小心。阅读Josh Bloch撰写的Effective Java,了解详细信息和建议。


31

理解“规范形式/表示形式”的一个好例子是查看XML模式数据类型定义“ boolean”:

  • 布尔的“词汇表示”可以是以下之一:{true, false, 1, 0}
  • “规范表示”只能是以下一种 {true, false}

从本质上讲,这意味着

  • "true""1"映射到规范代表。"true"
  • "false""0"映射到规范代表。"false"

请参阅w3 XML模式数据类型定义的布尔值


28

“规范”一词只是“标准”或“常规”的同义词。它没有任何Java特定的含义。


3
规范具有比标准或常规IMO更丰富的含义。
鱿鱼2015年

20

简化为最简单,最重要的形式而又不失一般性


5

记住它的一种简单方法是在神学界使用“规范”的方法,规范真理是真实的真理,因此,如果两个人找到它,他们就会发现相同的真理。与规范实例相同。如果您认为自己找到了两个(即a.equals(b)),则实际上只有一个(即a == b)。因此,在规范对象的情况下,平等意味着同一性。

现在进行比较。现在,您可以选择使用a==b or a.equals(b),因为在规范实例的情况下它们将产生相同的答案,但是a == b是对引用的比较(JVM可以非常快速地比较两个数字,因为它们只是比较的两个32位模式到a.equals(b)这是一个方法调用,并涉及更多的开销。


2

另一个很好的例子可能是:您有一个类支持使用笛卡尔(x,y,z),球面(r,theta,phi)和圆柱坐标(r,phi,z)。为了建立相等性(等于方法),您可能希望将所有表示形式转换为所选的一种“规范”表示形式,例如球坐标。(或者也许您一般都希望这样做-即使用一个内部表示。)我不是专家,但这确实是我的一个很好的具体例子。


0

规范表示表示以不同的样式查看字符,例如,如果我写字母A表示另一个人可以以不同的样式写字母A :)

这是根据光学字符识别字段



0

OP 可以通过扩展有效Java中提供的示例来回答有关规范形式及其如何提高equals方法性能的问题。

考虑以下类别:

public final class CaseInsensitiveString {

  private final String s;

  public CaseInsensitiveString(String s) {
    this.s = Objects.requireNonNull(s);
  }

  @Override 
  public boolean equals(Object o) {
    return o instanceof CaseInsensitiveString && ((CaseInsensitiveString) o).s.equalsIgnoreCase(s);
  }
}

所述equals在该实施例中方法,通过使用增加的成本StringequalsIgnoreCase方法。如文中所述

您可能需要存储字段的规范形式,以便equals方法可以对规范形式进行便宜的精确比较,而不是进行更昂贵的非标准比较。

约书亚·布洛赫(Joshua Bloch)说规范形式是什么意思?好吧,我认为Dónal的简洁答案非常合适。我们可以以标准方式(可能是的大写形式)存储示例中的基础String字段。现在,您可以引用的规范形式(其大写形式),并在和方法中执行廉价的评估。CaseInsensitiveStringStringCaseInsensitiveStringequalshashcode


0

RDBMS中的规范数据,图形数据;
可以认为是RDBMS中数据的“规范化”或“规范形式”。相同的数据存在于不同的表中,用唯一的标识符表示并将其映射到不同的表中。

认为图形数据库中的数据具有多种形式,以多种形式表示。

它的主要好处是可以提高Dml(数据操作)的效率,因为您只能对一个值(而不是多个值)进行高位插入(插入/更新)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.