GVKun编程网logo

为什么shortValue()方法是具体的,而intValue()是抽象到java.lang.Number中的呢?

16

在本文中,您将会了解到关于为什么shortValue的新资讯,同时我们还将为您解释方法是具体的,而intValue的相关在本文中,我们将带你探索为什么shortValue的奥秘,分析方法是具体的,而i

在本文中,您将会了解到关于为什么shortValue的新资讯,同时我们还将为您解释方法是具体的,而intValue的相关在本文中,我们将带你探索为什么shortValue的奥秘,分析方法是具体的,而intValue的特点,并给出一些关于Angular 4.x Forms patchValue and setValue、c# – GetValue,GetConstantValue和GetRawConstantValue之间的区别、go中的reflect.ValueOf()和Value.Elem()有什么区别?、HashMap—— values() remove方法 containsKey()方法 containsValue()方法的实用技巧。

本文目录一览:

为什么shortValue()方法是具体的,而intValue()是抽象到java.lang.Number中的呢?

为什么shortValue()方法是具体的,而intValue()是抽象到java.lang.Number中的呢?

我已阅读的源代码,java.lang.Number并且想知道为什么

  1. intValue()
  2. longValue()
  3. floatValue()
  4. doubleValue()

是抽象的,但是

  1. shortValue()
  2. byteValue()

混凝土。

源代码:

public abstract class Number implements java.io.Serializable {      public abstract int intValue();      public abstract long longValue();      public abstract float floatValue();      public abstract double doubleValue();      public byte byteValue() {        return (byte)intValue();      }     public short shortValue() {        return (short)intValue();      }    private static final long serialVersionUID = -8742448824652078965L;}

为什么Java创始人做到了这一点?

我看不到这些方法之间的巨大差异。它似乎相关。

聚苯乙烯

从长类:

  public byte byteValue() {        return (byte)value;    }    public short shortValue() {        return (short)value;    }    public int intValue() {        return (int)value;    }    public long longValue() {        return (long)value;    }    public float floatValue() {        return (float)value;    }    public double doubleValue() {        return (double)value;    }

从整数类

public byte byteValue() {        return (byte)value;    }    public short shortValue() {        return (short)value;    }    public int intValue() {        return value;    }    public long longValue() {        return (long)value;    }    public float floatValue() {        return (float)value;    }    public double doubleValue() {        return (double)value;    }

因此,我们看到了很多相同的代码。我认为copy paste开发是不好的,但我认为Java创始人有这样做的理由。

答案1

小编典典

根据Number类的文档,方法byteValueshortValue在JDK1.1中首先添加。这与第一个JDK版本中已经提供的其他“
Value”方法不同。我的假设是将这两种方法具体化,以保持与的现有(也是非标准)子类的兼容性,Number否则,这些子类可能会由于在超类中添加新的抽象方法而被破坏。

Angular 4.x Forms patchValue and setValue

Angular 4.x Forms patchValue and setValue

在 Angular 4.x 中有多种方式可以更新表单的值,对于使用响应式表单的场景,我们可以通过框架内部提供的 API ,(如 patchValue 和 setValue )方便地更新表单的值。这篇文章我们将介绍如何使用 patchValue 和 setValue 方法更新表单的值,此外还会进一步介绍它们之间的差异。

Reactive Form Setup

app.module.ts

import { NgModule,CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { browserModule } from '@angular/platform-browser';
import { ReactiveFormsModule } from '@angular/forms';

import { AppComponent } from './app.component';
import { EventFormComponent } from './event-form.component';

@NgModule({
  imports: [browserModule,ReactiveFormsModule],declarations: [AppComponent,EventFormComponent],bootstrap: [AppComponent],schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class AppModule { }

app.component.ts

import { Component,OnInit } from '@angular/core';

@Component({
  selector: 'exe-app',template: `
   <event-form></event-form>
  `,})
export class AppComponent {}

event-form.component.ts

import { Component,OnInit } from '@angular/core';
import { FormBuilder,FormGroup } from '@angular/forms';

@Component({
    selector: 'event-form',template: `
    <form novalidate (ngSubmit)="onSubmit(form)" [formGroup]="form">
      <div>
        <label>
          <span>Full name</span>
          <input type="text"formControlName="name">
        </label>
        <div formGroupName="event">
          <label>
            <span>Event title</span>
            <input type="text"formControlName="title">
          </label>
          <label>
            <span>Event location</span>
            <input type="text"formControlName="location">
          </label>
        </div>
      </div>
      <div>
        <button type="submit" [disabled]="form.invalid">
          Submit
        </button>
      </div>
    </form>
  `,})
export class EventFormComponent implements OnInit {
    form: FormGroup;

    constructor(public fb: FormBuilder) { }

    ngOnInit() {
        this.form = this.fb.group({
            name: ['',Validators.required],event: this.fb.group({
                title: ['',location: ['',Validators.required]
            })
        });
    }

    onSubmit({ value,valid }: { value: any,valid: boolean }) { }
}

patchValue

我们先来介绍 patchValue() 方法,然后在介绍 setValue() 方法。使用 patchValue() 方法会比使用 setValue() 方法更好,为什么这么说呢?我们来看一下源码就知道答案了。

// angular2/packages/forms/src/model.ts
export class FormGroup extends AbstractControl {
   ...
   patchValue(
     value: {[key: string]: any},{onlySelf,emitEvent}: 
                 {onlySelf?: boolean,emitEvent?: boolean} = {}): void {
      Object.keys(value).forEach(name => {
        if (this.controls[name]) {
          this.controls[name].patchValue(value[name],{onlySelf: true,emitEvent});
        }
      });
      this.updateValueAndValidity({onlySelf,emitEvent});
   }
}

// 使用示例
const form = new FormGroup({
   first: new FormControl(),last: new FormControl()
});

console.log(form.value);   // {first: null,last: null}

form.patchValue({first: 'Nancy'});
console.log(form.value);   // {first: 'Nancy',last: null}

从源码中我们可以看出,patchValue() 方法会获取输入参数对象的所有 key 值,然后循环调用内部控件的 patchValue() 方法,具体代码如下:

Object.keys(value).forEach(name => {
  if (this.controls[name]) {
     this.controls[name].patchValue(value[name],emitEvent});
  }
});

首先,Object.keys() 会返回对象 key 值的数组,例如:

const man = {name : 'Semlinker',age: 30};
Object.keys(man); // ['name','age']

此外 this.controls 包含了 FormGroup 对象中的所有 FormControl 控件,我们可以通过 this.controls[name] 方式,访问到 name 对应的控件对象。

现在让我们来回顾一下上面的示例中创建 FormGroup 对象的相关代码:

this.form = this.fb.group({
  name: ['',event: this.fb.group({
    title: ['',Validators.required]
  })
});

与之相对应的对象模型如下:

{
  name: '',event: {
    title: '',location: ''
  }
}

因此要更新该模型的值,我们可以利用 FormGroup 对象的 patchValue() 方法:

this.form.patchValue({
  name: 'Semlinker',event: {
    title: 'Angular 4.x\'s Road',location: 'Xiamen'
  }
});

以上代码将会通过循环的方式,更新每个 FormControl 控件。接下来我们看一下 FormControl 中 patchValue() 方法的具体实现:

patchValue(value: any,options: {
    onlySelf?: boolean,emitEvent?: boolean,emitModelToViewChange?: boolean,emitViewToModelChange?: boolean
  } = {}): void {
    this.setValue(value,options);
}

忽略所有的函数参数和类型,它所做的就是调用 setValue() 方法,设置控件的值。另外使用 patchValue() 方法有什么好处呢?假设我们使用 firebase,那么当我们从 API 接口获取数据对象时,对象内部可能会包含 $exists$key 属性。而当我们直接使用返回的数据对象作为参数,直接调用 patchValue() 方法时,不会抛出任何异常:

this.form.patchValue({
  $exists: function () {},$key: '-KWihhw-f1kw-ULPG1ei',name: 'Semlinker',location: 'Xiamen'
  }
});

其实没有抛出异常的原因,是因为在 patchValue() 内部循环时,我们有使用 if 语句进行条件判断。那好,现在我们开始来介绍 setValue() 方法。

setValue

首先,我们来看一下 FormGroup 类中的 setValue() 方法的具体实现:

setValue(
  value: {[key: string]: any},emitEvent}: {onlySelf?: boolean,emitEvent?: boolean} = {}): void {
      this._checkAllValuesPresent(value);
      Object.keys(value).forEach(name => {
        this._throwIfControlMissing(name);
        this.controls[name].setValue(value[name],emitEvent});
      });
      this.updateValueAndValidity({onlySelf,emitEvent});
}

// 使用示例
const form = new FormGroup({
    first: new FormControl(),last: new FormControl()
});
console.log(form.value);   // {first: null,last: null}

form.setValue({first: 'Nancy',last: 'Drew'});
console.log(form.value);   // {first: 'Nancy',last: 'Drew'}

跟 patchValue() 方法一样,我们内部也是包含一个 Object.keys() 的循环,但在循环开始之前,我们会先调用 _checkAllValuesPresent() 方法,对输入值进行校验。 另外 _checkAllValuesPresent() 方法的具体实现如下:

_checkAllValuesPresent(value: any): void {
    this._forEachChild((control: AbstractControl,name: string) => {
      if (value[name] === undefined) {
        throw new Error(`Must supply a value for form control with name: '${name}'.`);
      }
    });
}

该方法内部通过 _forEachChild() 遍历内部的 FormControl 控件,来确保我们在调用 setValue() 方法时,设置的参数对象中,会包含所有控件的配置信息。如果 name 对应的配置信息不存在,则会抛出异常。

_checkAllValuesPresent() 验证通过后,Angular 会进入 Object.keys() 循环,此外在调用 setValue() 方法前,还会优先调用 _throwIfControlMissing() 判断控件是否存在,该方法的实现如下:

_throwIfControlMissing(name: string): void {
    if (!Object.keys(this.controls).length) {
      throw new Error(`
        There are no form controls registered with this group yet.  
        If you're using ngModel,you may want to check next tick (e.g. use setTimeout).
      `);
    }
    if (!this.controls[name]) {
      throw new Error(`Cannot find form control with name: ${name}.`);
    }
}

上面代码首先判断 this.controls 是否存在,如果存在进一步判断 name 对应的 FormControl 控件是否存在。当 _throwIfControlMissing() 验证通过后,才会最终调用 FormControl 控件的 setValue() 方法:

this.controls[name].setValue(value[name],emitEvent});

我们来看一下 FormControl 类中,setValue() 方法的具体实现:

setValue(value: any,emitEvent,emitModelToViewChange,emitViewToModelChange}: {
         onlySelf?: boolean,emitViewToModelChange?: boolean
  } = {}): void {
    this._value = value;
    if (this._onChange.length && emitModelToViewChange !== false) {
      this._onChange.forEach((changeFn) => 
            changeFn(this._value,emitViewToModelChange !== false));
    }
    this.updateValueAndValidity({onlySelf,emitEvent});
}

该方法的第一个参数,就是我们要设置的值,第二个参数是一个对象:

  • onlySelf:若该值为 true,当控件的值发生变化后,只会影响当前控件的验证状态,而不会影响到它的父组件。默认值是 false。

  • emitEvent:若该值为 true,当控件的值发生变化后,将会触发 valueChanges 事件。默认值是 true

  • emitModelToViewChange:若该值为 true,当控件的值发生变化时,将会把新值通过 onChange 事件通知视图层。若未指定 emitModelToViewChange 的值,这是默认的行为。

  • emitViewToModelChange:若该值为 true,ngModelChange 事件将会被触发,用于更新模型。若未指定 emitViewToModelChange 的值,这是默认的行为。

其实仅仅通过上面的代码,我们还是没完全搞清楚 setValue() 方法内部真正执行流程。如我们不知道如何注册 changeFn 函数和 updateValueAndValidity() 方法的内部处理逻辑,接下来我们先来看一下如何注册 changeFn 函数:

export class FormControl extends AbstractControl {
  /** @internal */
  _onChange: Function[] = [];
 ...
 /**
  * Register a listener for change events.
  */
 registerOnChange(fn: Function): void { this._onChange.push(fn); }
}

现在我们来回顾一下 setValue() 的相关知识点。对于 FormGroup 对象,我们可以通过 setValue() 方法更新表单的值,具体使用示例如下:

this.form.setValue({
  name: 'Semlinker',location: 'Xiamen'
  }
});

以上代码成功运行后,我们就能成功更新表单的值。但如果我们使用下面的方式,就会抛出异常:

this.form.setValue({
  $exists: function () {},location: 'Xiamen'
  }
});

最后我们来总结一下 FormGroupFormControl 类中 patchValue() 与 setValue() 的区别。

patchValue vs setValue

FormControl

patchValue

patchValue(value: any,options);
}

setValue

setValue(value: any,emitViewToModelChange}: {
    onlySelf?: boolean,emitViewToModelChange?: boolean
  } = {}): void {
    this._value = value;
    if (this._onChange.length && emitModelToViewChange !== false) {
      this._onChange.forEach((changeFn) => changeFn(this._value,emitEvent});
}

通过源码我们发现对于 FormControl 对象来说,patchValue() 和 setValue() 这两个方法是等价的。此外 setValue() 方法中做了三件事:

  • 更新控件当前值

  • 判断是否注册 onChange 事件,若有则循环调用已注册的 changeFn 函数。

  • 重新计算控件的值和验证状态

FormGroup

patchValue

patchValue(
  value: {[key: string]: any},emitEvent?: boolean} = {}): void {
    Object.keys(value).forEach(name => {
      if (this.controls[name]) {
        this.controls[name].patchValue(value[name],emitEvent});
      }
    });
    this.updateValueAndValidity({onlySelf,emitEvent});
}

setValue

setValue(
  value: {[key: string]: any},emitEvent?: boolean} = {}): void {
    this._checkAllValuesPresent(value); // 判断的是否为所有控件都设置更新值
    Object.keys(value).forEach(name => {
      this._throwIfControlMissing(name); // 判断控件是否存在
      this.controls[name].setValue(value[name],emitEvent});
    });
    this.updateValueAndValidity({onlySelf,emitEvent}); // 重新计算控件的值和验证状态
}

通过查看源码,我们发现 setValue() 方法相比 patchValue() 会更严格,会执行多个判断:

  • 判断的是否为所有控件都设置更新值

  • 判断控件是否存在

而 patchValue() 方法,会先使用 this.controls[name] 进行过滤,只更新参数 value 中设定控件的值。

我有话说

为什么 FormControl 中 patchValue() 和 setValue() 是等价的,还需要两个方法?

因为 FormControl 继承于 AbstractControl 抽象类:

export class FormControl extends AbstractControl { }

AbstractControl 抽象类中定义了 patchValue() 和 setValue() 两个抽象方法,需要由子类实现:

/**
 * Sets the value of the control. Abstract method (implemented in sub-classes).
*/
abstract setValue(value: any,options?: Object): void;

/**
 * Patches the value of the control. Abstract method (implemented in sub-classes).
 */
abstract patchValue(value: any,options?: Object): void;

创建 FormControl 控件有哪些常见的方式?

方式一

const ctrl = new FormControl('some value');
console.log(ctrl.value); // 'some value'

方式二

const ctrl = new FormControl({ value: 'n/a',disabled: true });
console.log(ctrl.value); // 'n/a'
console.log(ctrl.status); // disABLED

若没有设置 disabled 属性,即:

const ctrl = new FormControl({ value: 'n/a'});
console.log(ctrl.value); // Object {value: "n/a"}
console.log(ctrl.status); // VALID

为什么呢?因为内部在初始设置控件状态时,会对传入的 formState 参数进行判断:

FormControl 构造函数

constructor(
      formState: any = null,validator: ValidatorFn|ValidatorFn[] = null,asyncValidator: AsyncValidatorFn|AsyncValidatorFn[] = null) {
    ...
    this._applyFormState(formState);
    ...
}

_applyFormState() 方法

private _applyFormState(formState: any) {
    if (this._isBoxedValue(formState)) {
      this._value = formState.value;
      formState.disabled ? this.disable({onlySelf: true,emitEvent: false}) :
                           this.enable({onlySelf: true,emitEvent: false});
    } else {
      this._value = formState;
    }
}

_isBoxedValue() 方法

_isBoxedValue(formState: any): boolean {
    return typeof formState === 'object' && formState !== null &&
        Object.keys(formState).length === 2 && 'value' in formState && 
              'disabled' in formState;
}

方式三

const ctrl = new FormControl('',Validators.required);
console.log(ctrl.value); // ''
console.log(ctrl.status); //INVALID

创建 FormGroup 对象有哪些常见的方式?

方式一

const form = new FormGroup({
  first: new FormControl('Nancy',Validators.minLength(2)),last: new FormControl('Drew'),});

console.log(form.value);   // Object {first: "Nancy",last: "Drew"}
console.log(form.status);  // 'VALID'

方式二

const form = new FormGroup({
  password: new FormControl('',passwordConfirm: new FormControl('',},passwordMatchValidator);

function passwordMatchValidator(g: FormGroup) {
  return g.get('password').value === g.get('passwordConfirm').value
     ? null : { 'mismatch': true };
}

上面代码中,我们在创建 FormGroup 对象时,同时设置了同步验证器 (validator),用于校验 password (密码) 和 passwordConfirm (确认密码) 的值是否匹配。

参考资源

  • https://toddmotto.com/angular...

c# – GetValue,GetConstantValue和GetRawConstantValue之间的区别

c# – GetValue,GetConstantValue和GetRawConstantValue之间的区别

PropertyInfo类上的GetValue,GetConstantValue和GetRawConstantValue方法有什么区别?不幸的是,MSDN文档不是很清楚.

解决方法

GetConstantValue和GetRawConstantValue都适用于文字(在字段的情况下为const,但在语义上它可以应用于不仅仅是字段) – 不同于GetValue,它将在运行时获取某些东西的实际值,通过GetConstantValue或GetRawConstantValue)不依赖于运行时 – 它是直接从元数据.

那么我们得到GetConstantValue和GetRawConstantValue之间的区别.基本上,后者是更直接和原始的形式.这主要针对枚举成员;例如 – 如果我有一个:

enum Foo { A = 1,B = 2 }
...
const Foo SomeValue = Foo.B;

那么SomeValue的GetConstantValue是Foo.B;但是,SomeValue的GetRawConstantValue值为2.特别地,如果您使用的是仅反射上下文,则不能使用GetConstantValue,因为这将需要将值绑定到Foo,这在使用仅反射时不能执行.

go中的reflect.ValueOf()和Value.Elem()有什么区别?

go中的reflect.ValueOf()和Value.Elem()有什么区别?

如何解决go中的reflect.ValueOf()和Value.Elem()有什么区别??

reflect.ValueOf()是一个 函数 ,请将其视为反射的切入点。当您具有“非反射”值(例如string或)时int,可以reflect.ValueOf()用来获取其reflect.Value描述符。

Value.Elem()是一个 方法reflect.Value。因此,只有在您已有时,才可以使用它reflect.Value。您可以Value.Elem()用来获取reflect.Value由原始包装的值所指向的值()reflect.Value。请注意,您也可以使用reflect.Indirect()它。还有一个“用例”Value.Elem(),但是它更“高级”,我们在答案的最后返回。

要“离开”反射,可以使用常规Value.Interface()方法,该方法将包装的值作为返回interface{}

例如:

var i int = 3
var p *int = &i
fmt.Println(p, i)

v := reflect.ValueOf(p)
fmt.Println(v.Interface()) // This is the p pointer

v2 := v.Elem()
fmt.Println(v2.Interface()) // This is i''s value: 3

这将输出(在Go Playground上尝试):

0x414020 3
0x414020
3

有关Go反射的重要介绍,请阅读The Go Blog:反射法则。尽管如果您只是从Go开始,我会专注于其他事情,并为以后的冒险留神。

另一个用例 Value.Elem()

这是一个高级主题,所以如果您不了解它,请不要惊慌。 不用了

我们看到了Value.Elem()当指针包装在时如何用于“导航” reflect.Value。的医生Value.Elem()说:

Elem返回接口v包含的值或指针v指向的值。

因此,如果reflect.Value包装一个接口值,Value.Elem()也可以用来获取包装在该接口值中的具体值。

Go中的接口是它自己的主题,对于内部结构而言,您可以阅读Russ Cox的Go数据结构:接口。再次重申,不一定是Go入门者的主题。

基本上,无论您传递给什么值reflect.ValueOf(),如果它还不是接口值,它将被interface{}隐式包装。如果传递的值已经是接口值,则存储在其中的具体值将作为传递interface{}。如果您将指针传递给接口,则会出现第二个“用例”(否则,在Go!中非常罕见)。

因此,如果将指针传递给接口,则该指针将包装在一个interface{}值中。您可以使用Value.Elem()来获得目标值,该目标值将是接口值(而不是具体值),Value.Elem()再次 使用它可以得到具体值。

这个例子说明了这一点:

var r io.Reader = os.Stdin // os.Stdin is of type *os.File which implements io.Reader

v := reflect.ValueOf(r) // r is interface wrapping *os.File value
fmt.Println(v.Type())   // *os.File

v2 := reflect.ValueOf(&r)            // pointer passed, will be wrapped in interface{}
fmt.Println(v2.Type())               // *io.Reader
fmt.Println(v2.Elem().Type())        // navigate to pointed: io.Reader (interface type)
fmt.Println(v2.Elem().Elem().Type()) // 2nd Elem(): get concrete value in interface: *os.File

在Go Playground上尝试一下。

解决方法

我几天前开始学习golang,发现reflect.Valueof()和Value.Elem()非常令人困惑。这两种功能/方法有什么区别,以及如何正确使用它们?

这两个函数/方法都返回一个值,并根据go doc

ValueOf返回一个新的Value,初始化为存储在接口i中的具体值。ValueOf(nil)返回零值。

Elem返回接口v包含的值或指针v指向的值。如果v的种类不是Interface或Ptr,它会感到恐慌。如果v为零,它将返回零值。

我从帖子中找到了此代码,但仍然不知道何时使用.Elem()

func SetField(obj interface{},name string,value interface{}) error {

    // won''t work if I remove .Elem()
    structValue := reflect.ValueOf(obj).Elem()

    structFieldValue := structValue.FieldByName(name)

    if !structFieldValue.IsValid() {
        return fmt.Errorf("No such field: %s in obj",name)
    }

    if !structFieldValue.CanSet() {
        return fmt.Errorf("Cannot set %s field value",name)
    }

    structFieldType := structFieldValue.Type()

    // won''t work either if I add .Elem() to the end
    val := reflect.ValueOf(value)
    if structFieldType != val.Type() {

        return fmt.Errorf("Provided value %v type %v didn''t match obj field type %v",val,val.Type(),structFieldType)
    }

    structFieldValue.Set(val)
    return nil
}

HashMap—— values() remove方法 containsKey()方法 containsValue()方法

HashMap—— values() remove方法 containsKey()方法 containsValue()方法

values()方法:看下面的实例,就是把所有的value值封装成一个connection型的数组

Map<Integer,Student> students=new HashMap<>();
        students.put(1, new Student("111"));
        students.put(2, new Student("111"));
        Collection stuValues = students.values();
        for (Object stuValue : stuValues) {
            System.out.println(stuValue);
        }

输出结果

com.xt.map.Student@52e922
com.xt.map.Student@25154f

remove()方法

final Node<K,V> removeNode(int hash, Object key, Object value,
                               boolean matchValue, boolean movable) {
        Node<K,V>[] tab; Node<K,V> p; int n, index;
        if ((tab = table) != null && (n = tab.length) > 0 &&
            (p = tab[index = (n - 1) & hash]) != null) {
            Node<K,V> node = null, e; K k; V v;
            if (p.hash == hash &&
                ((k = p.key) == key || (key != null && key.equals(k))))
                node = p;
            else if ((e = p.next) != null) {
                if (p instanceof TreeNode)
                    node = ((TreeNode<K,V>)p).getTreeNode(hash, key);
                else {
                    do {
                        if (e.hash == hash &&
                            ((k = e.key) == key ||
                             (key != null && key.equals(k)))) {
                            node = e;
                            break;
                        }
                        p = e;
                    } while ((e = e.next) != null);
                }
            }
            if (node != null && (!matchValue || (v = node.value) == value ||
                                 (value != null && value.equals(v)))) {
                if (node instanceof TreeNode)
                    ((TreeNode<K,V>)node).removeTreeNode(this, tab, movable);
                else if (node == p)
                    tab[index] = node.next;
                else
                    p.next = node.next;
                ++modCount;
                --size;
                afterNodeRemoval(node);
                return node;
            }
        }
        return null;
    }

看上面的红色代码,这个事底层代码,就是判定remove的是谁,,,怎么去判断的依据,下面就是依据

    1:判定HashCode值是否相同       e.hash == hash

    2:判定地址是否相同  k = e.key) == key

    3:equals方法  key.equals(k))

                 if (e.hash == hash &&
                            ((k = e.key) == key ||
                             (key != null && key.equals(k)))) {

 如果为真就删除了这个对象

containsKey()方法

*/
    final Node<K,V> getNode(int hash, Object key) {
        Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
        if ((tab = table) != null && (n = tab.length) > 0 &&
            (first = tab[(n - 1) & hash]) != null) {
            if (first.hash == hash && // always check first node
                ((k = first.key) == key || (key != null && key.equals(k))))
                return first;
            if ((e = first.next) != null) {
                if (first instanceof TreeNode)
                    return ((TreeNode<K,V>)first).getTreeNode(hash, key);
                do {
                    if (e.hash == hash &&
                        ((k = e.key) == key || (key != null && key.equals(k))))
                        return e;
                } while ((e = e.next) != null);
            }
        }
        return null;
    }

我们发现红色的字体和remove方法道理相同,这里就不过多解释了

containsValues()方法

public boolean containsValue(Object value) {
        Node<K,V>[] tab; V v;
        if ((tab = table) != null && size > 0) {
            for (int i = 0; i < tab.length; ++i) {
                for (Node<K,V> e = tab[i]; e != null; e = e.next) {
                    if ((v = e.value) == value ||
                        (value != null && value.equals(v)))
                        return true;
                }
            }
        }
        return false;
    }
(v = e.value) == value || (value != null && value.equals(v))
这个意思就是:如果value地址相同,或者本身的值相同,然后equals方法
如果是基本类型:例如2==2 直接就为TRUE
如果是引用类型:new Student(111)==new Student(222) 为FALSE 但是value.equals(v)为真 最后还是返回TRUE

OK~

关于为什么shortValue方法是具体的,而intValue的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于Angular 4.x Forms patchValue and setValue、c# – GetValue,GetConstantValue和GetRawConstantValue之间的区别、go中的reflect.ValueOf()和Value.Elem()有什么区别?、HashMap—— values() remove方法 containsKey()方法 containsValue()方法等相关内容,可以在本站寻找。

本文标签: