首页
归档
留言
友链
广告合作
壁纸
更多
美女主播
Search
1
博瑞GE车机升级/降级
5,649 阅读
2
Mac打印机设置黑白打印
5,043 阅读
3
修改elementUI中el-table树形结构图标
4,946 阅读
4
Mac客户端添加腾讯企业邮箱方法
4,705 阅读
5
intelliJ Idea 2022.2.X破解
4,459 阅读
后端开发
HarmonyOS Next
Web前端
微信开发
开发辅助
App开发
数据库
随笔日记
登录
/
注册
Search
标签搜索
Spring Boot
Java
Vue
Mac
Spring Cloud
MyBatis
WordPress
MacOS
asp.net
Element UI
Nacos
MySQL
.Net
Spring Cloud Alibaba
Mybatis-Plus
Typecho
jQuery
Java Script
IntelliJ IDEA
微信小程序
Laughing
累计撰写
629
篇文章
累计收到
1,421
条评论
首页
栏目
后端开发
HarmonyOS Next
Web前端
微信开发
开发辅助
App开发
数据库
随笔日记
页面
归档
留言
友链
广告合作
壁纸
美女主播
搜索到
629
篇与
的结果
2021-09-11
Mac 安装 brew(最新教程,绝对可行,一行代码搞定,不报错)
自动脚本(全部国内地址)(在Mac os终端中复制粘贴回车下面这句话),无需梯子/bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"
2021年09月11日
1,123 阅读
0 评论
0 点赞
2021-09-10
简约精致苹果风格 LINUX 系统:CUTEFISHOS
近又新出了一个 Linux 桌面发行版「CutefishOS」基于 Ubuntu,桌面风格非常苹果味,根据官方的介绍,做更好的桌面操作系统、注重简洁、美观和实用性。访问{cloud title="" type="bd" url="https://pan.baidu.com/s/1KjdN-C2Vdf5OTVwKYXYh5Q" password="7dx2"/}天翼网盘:{cloud title="" type="ty" url="https://cloud.189.cn/web/share?code=Qzi6biUFfi2q" password="sbi6"/}官方:https://cn.cutefishos.com2021年09月12日昨天趁着周六在家里电脑安装了一下,简单说一下体会吧,因为我上午安装的,晚上就把电脑搞崩了 ̄□ ̄||系统安装上之后,虽然是测试版,但是还是挺流畅的。整体界面比较简洁,类似Mac风格,但是感觉没那么精致。基于Ubuntu,所以Ubuntu的那套逻辑都能正常用。
2021年09月10日
1,040 阅读
0 评论
1 点赞
2021-09-08
angular监听表单变化及双向数据绑定
监听表单变化FormGroup及FormControl都带有EventEmitter(事件发射器)用于监控表单控件的变化。要监听控件的变化,我们通过以下步骤:通过调用control.valueChanges访问这个EventEmitter然后调用.subscribe方法添加一个监听器。html代码如下<nz-card style="width:300px;"> <form [formGroup]="myForm" nz-form (ngSubmit)="onSubmit(myForm.value)"> <nz-form-item> <nz-form-label [nzSpan]="6" nzFor="sku">sku</nz-form-label> <nz-form-control [nzSpan]="14"> <input nz-input name="sku" type="text" id="sku" [formControl]="myForm.controls['sku']"> <nz-tag *ngIf="myForm.controls['sku'].hasError('required') && myForm.controls['sku'].touched" [nzColor]="'magenta'">请输入SKU</nz-tag> <nz-tag nzColor="error" *ngIf="myForm.controls['sku'].hasError('invalidSku')"> <i nz-icon nzType="close-circle"></i> <span>error</span> </nz-tag> </nz-form-control> </nz-form-item> <nz-form-item> <button type="submit" nz-button class="primary">Submit</button> </nz-form-item> </form> </nz-card>ts代码如下import { Component, OnInit } from '@angular/core'; import { FormGroup, FormControl, FormBuilder, Validators } from '@angular/forms'; @Component({ selector: 'app-demo-form-sku-form-builder', templateUrl: './demo-form-sku-form-builder.component.html', styleUrls: ['./demo-form-sku-form-builder.component.css'] }) export class DemoFormSkuFormBuilderComponent implements OnInit { myForm: FormGroup constructor(formBuilder: FormBuilder) { this.myForm = formBuilder.group({}) let formControl: FormControl = new FormControl("", Validators.compose( [Validators.required, this.skuValidator] )) this.myForm.addControl("sku", formControl) formControl.valueChanges.subscribe((value: string) => { console.warn('值改变' + value) }) this.myForm.valueChanges.subscribe((form: any) => { console.warn('表单改变:' + JSON.stringify(form)) }) } ngOnInit(): void { } onSubmit(form: any): void { debugger this.myForm.controls['sku'] console.log(form) } skuValidator(formControl: FormControl): { [s: string]: boolean } { if (!formControl.value.match(/^123/)) { return { invalidSku: true } } return { invalidSku: false } } } 双向数据绑定ngModel是一个特殊的指令,它将模型绑定到表单中。ngModel的特殊之处在于它实现了双向绑定。相对于单向绑定来说,双向绑定更加复杂和难以推断。Angular通常的数据流向是单向的:自顶向下。但对于表单来说,双向绑定有时会更加容易。我们在ts文件添加一个sku属性,修改后如下import { Component, OnInit } from '@angular/core'; import { FormGroup, FormControl, FormBuilder, Validators } from '@angular/forms'; @Component({ selector: 'app-demo-form-sku-form-builder', templateUrl: './demo-form-sku-form-builder.component.html', styleUrls: ['./demo-form-sku-form-builder.component.css'] }) export class DemoFormSkuFormBuilderComponent implements OnInit { myForm: FormGroup sku: string constructor(formBuilder: FormBuilder) { this.sku = '' this.myForm = formBuilder.group({}) let formControl: FormControl = new FormControl("", Validators.compose( [Validators.required, this.skuValidator] )) this.myForm.addControl("sku", formControl) formControl.valueChanges.subscribe((value: string) => { console.warn('值改变' + value) }) this.myForm.valueChanges.subscribe((form: any) => { console.warn('表单改变:' + JSON.stringify(form)) }) } ngOnInit(): void { } onSubmit(form: any): void { debugger this.myForm.controls['sku'] console.log(form) } skuValidator(formControl: FormControl): { [s: string]: boolean } { if (!formControl.value.match(/^123/)) { return { invalidSku: true } } return { invalidSku: false } } } html模板中通过[(ngModel)]绑定我们添加的属性<nz-card style="width:300px;"> <form [formGroup]="myForm" nz-form (ngSubmit)="onSubmit(myForm.value)"> <nz-form-item> <nz-form-label [nzSpan]="6" nzFor="sku">sku</nz-form-label> <nz-form-control [nzSpan]="14"> <input nz-input name="sku" type="text" id="sku" [formControl]="myForm.controls['sku']" [(ngModel)]="sku"> <nz-tag *ngIf="myForm.controls['sku'].hasError('required') && myForm.controls['sku'].touched" [nzColor]="'magenta'">请输入SKU</nz-tag> <nz-tag nzColor="error" *ngIf="myForm.controls['sku'].hasError('invalidSku')" > <i nz-icon nzType="close-circle"></i> <span>error</span> </nz-tag> </nz-form-control> </nz-form-item> <nz-form-item> <button type="submit" nz-button class="primary">Submit</button> </nz-form-item> </form> <div> sku:{{sku}} </div> </nz-card>
2021年09月08日
1,960 阅读
0 评论
2 点赞
2021-09-06
angular验证器Validators及自定义验证器方法
angular预置验证器angular在Validators类中预置了部分验证器。可以通过如下代码导入import { FormGroup, FormControl, FormBuilder, Validators } from '@angular/forms';比如,我们使用一下必填验证required。首先看下ts代码,在ts文件中,我们通过注入FormBuilder,创建一个FormGroup,在FormGroup中添加一个名称为sku的FormControl,然后我们校验sku,要求用户必须输入。import { Component, OnInit } from '@angular/core'; import { FormGroup, FormControl, FormBuilder, Validators } from '@angular/forms'; @Component({ selector: 'app-demo-form-sku-form-builder', templateUrl: './demo-form-sku-form-builder.component.html', styleUrls: ['./demo-form-sku-form-builder.component.css'] }) export class DemoFormSkuFormBuilderComponent implements OnInit { myForm: FormGroup constructor(formBuilder: FormBuilder) { this.myForm = formBuilder.group({}) let formControl: FormControl = new FormControl("", Validators.required) this.myForm.addControl("sku", formControl) } ngOnInit(): void { } onSubmit(form: any): void { console.log(form) } }html代码如下<nz-card style="width:300px;"> <form [formGroup]="myForm" nz-form (ngSubmit)="onSubmit(myForm.value)"> <nz-form-item> <nz-form-label [nzSpan]="6" nzFor="sku">sku</nz-form-label> <nz-form-control [nzSpan]="14"> <input nz-input name="sku" type="text" id="sku" [formControl]="myForm.controls['sku']"> <nz-tag *ngIf="!myForm.controls['sku'].valid && myForm.controls['sku'].touched" [nzColor]="'magenta'">请输入SKU</nz-tag> </nz-form-control> </nz-form-item> <nz-form-item> <button type="submit" nz-button class="primary">Submit</button> </nz-form-item> </form> </nz-card>myForm.controls['sku'].valid用于校验用户是否输出,myForm.controls['sku'].touched判断用户是否点击了控件。如果用户点击控件后,没有输入内容。自定义验证器自定义验证器其实就是一个方法,这个方法有如下特点:接收一个FormControl作为参数验证失败时,返回一个StringMap<string,boolean>对象,键是错误代码、值是truets文件如下import { Component, OnInit } from '@angular/core'; import { FormGroup, FormControl, FormBuilder, Validators } from '@angular/forms'; @Component({ selector: 'app-demo-form-sku-form-builder', templateUrl: './demo-form-sku-form-builder.component.html', styleUrls: ['./demo-form-sku-form-builder.component.css'] }) export class DemoFormSkuFormBuilderComponent implements OnInit { myForm: FormGroup constructor(formBuilder: FormBuilder) { this.myForm = formBuilder.group({}) let formControl: FormControl = new FormControl("", Validators.compose( [Validators.required, this.skuValidator] )) this.myForm.addControl("sku", formControl) } ngOnInit(): void { } onSubmit(form: any): void { console.log(form) } skuValidator(formControl: FormControl): { [s: string]: boolean } { if (!formControl.value.match(/^123/)) { return { invalidSku: true } } return { invalidSku: false } } }html代码如下<nz-card style="width:300px;"> <form [formGroup]="myForm" nz-form (ngSubmit)="onSubmit(myForm.value)"> <nz-form-item> <nz-form-label [nzSpan]="6" nzFor="sku">sku</nz-form-label> <nz-form-control [nzSpan]="14"> <input nz-input name="sku" type="text" id="sku" [formControl]="myForm.controls['sku']"> <nz-tag *ngIf="myForm.controls['sku'].hasError('required') && myForm.controls['sku'].touched" [nzColor]="'magenta'">请输入SKU</nz-tag> <nz-tag nzColor="error" *ngIf="myForm.controls['sku'].hasError('invalidSku')"> <i nz-icon nzType="close-circle"></i> <span>error</span> </nz-tag> </nz-form-control> </nz-form-item> <nz-form-item> <button type="submit" nz-button class="primary">Submit</button> </nz-form-item> </form> </nz-card>如果我们输入的sku不是123开头,可以看到以下页面
2021年09月06日
1,780 阅读
0 评论
1 点赞
2021-09-05
angular内置指令
ngIf用来决定显示或隐藏元素,指令条件可以是表达式。app.component.html代码<nz-card style="width:300px;" nzTitle="Card title" [nzExtra]="extraTemplate"> <p *ngIf=false>1</p> <p *ngIf="doNotDisplay">2</p> <p *ngIf="display()">3</p> </nz-card> <ng-template #extraTemplate> <a>More</a> </ng-template>app.component.ts代码import { Component } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { doNotDisplay: boolean = false display(): boolean { return true } } 隐藏的元素不会创建。ngSwitchngSwitch指令可以通过ngSwitchCase、ngSwitchDefault走不通的分支。app.component.html代码<nz-card style="width:300px;" nzTitle="Card title" [nzExtra]="extraTemplate" [ngSwitch]="choice"> <p *ngSwitchCase="1">1</p> <p *ngSwitchCase="2">2</p> <p *ngSwitchCase="3">3</p> <p *ngSwitchDefault>default</p> </nz-card> <ng-template #extraTemplate> <a>More</a> </ng-template>app.component.ts代码import { Component } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { choice: string = "4" }ngStyle给DOM元素设置CSS属性。最简单的用法[style.property]=valueapp.component.html代码<nz-card style="width:300px;" nzTitle="Card title" [nzExtra]="extraTemplate"> <p *ngIf=false>1</p> <p *ngIf="doNotDisplay">2</p> <p *ngIf="display()" [style.background-color]="backgroundColor">3</p> </nz-card> <ng-template #extraTemplate> <a>More</a> </ng-template>app.component.ts代码import { Component } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { doNotDisplay: boolean = false backgroundColor: string = 'red' display(): boolean { return true } }另外一种方式是使用键值对<nz-card style="width:300px;" nzTitle="Card title" [nzExtra]="extraTemplate"> <p *ngIf=false>1</p> <p *ngIf="doNotDisplay">2</p> <p *ngIf="display()" [ngStyle]="{'background-color':backgroundColor}">3</p> </nz-card> <ng-template #extraTemplate> <a>More</a> </ng-template>ngClassapp.component.css中定义一个类.bordered{ border: 1px dashed royalblue; }app.component.html代码<div [ngClass]="'bordered'" style="height: 400px;"></div>也可以通过如下代码<div [ngClass]="{bordered:false}" style="height: 400px;"></div>ngFor用于循环app.component.html代码<ul> <li *ngFor="let color of colors" [ngStyle]="{color:color}">{{color}}</li> </ul>app.component.ts代码import { Component } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { colors:Array<String> constructor(){ this.colors=[ 'red','blue','green' ] } }循环时,我们也可以获取索引<ul> <li *ngFor="let color of colors;let index=index" [ngStyle]="{color:color}">{{index}}--{{color}}</li> </ul>ngNonBindable指定不编译或者绑定页面中的某个特殊部分。app.component.html代码<p ngNonBindable> {{content}} </p> <p> {{content}} </p>app.component.ts代码import { Component } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { content:string="<div>content</div>" }innerHTML、innerText通过{{}}输出内容,会强制转换成文本。我们可以通过[innerHTML]输出html。[innerText]可以将html代码强制输出文本。app.component.html代码<div [innerHTML]="content"> </div> <div [innerText]="content"> </div>app.component.ts代码import { Component } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { content:string="<div>测试</div>" }
2021年09月05日
1,113 阅读
0 评论
25 点赞
2021-09-05
angular组件的输入与输出
所谓组件的输入与输出,其实就是给组件传值或者组件往外传值。类似于父组件向子组件传值或者子组件回调父组件的方法(也可以回调传值)。angular在模板上,通过[]实现组件的输入,()实现组件的输出。组件的输入比如有一个test的组件,其中有一个name属性,我们需要通过app组件将name传递给test组件。方式一:通过@Input()注解@Input()注解适合数据比较少的情况。首先,我们需要在TestComponent类中增加一个name属性,然后导入Input,然后在name属性前增加@Input()注解。import { Component, EventEmitter, OnInit,Input } from '@angular/core'; @Component({ selector: 'app-test', templateUrl: './test.component.html', styleUrls: ['./test.component.css'] }) export class TestComponent implements OnInit { @Input('newName') name: string; constructor() { this.name = "" } ngOnInit(): void { } } @Input('newName')中的newName代表我们起的一个别名,也就是说在传值的时候,我们是通过[newName]将值传递到组件的name属性。然后我们在模板文件test.component.html增加输出,以便测试值是否传递。<p>{{name}}</p>我们在app.component.html中调用app-test组件,并通过[]传值。<app-test [newName]='"test"'></app-test>测试方式二:通过Inputs[]配置项首先,我们需要在TestComponent类中增加一个name属性,然后在@Component注解中,增加Inputs[]配置项。import { Component, EventEmitter, OnInit } from '@angular/core'; @Component({ selector: 'app-test', templateUrl: './test.component.html', styleUrls: ['./test.component.css'], inputs: ['name:newName'] }) export class TestComponent implements OnInit { name: string; constructor() { this.name = "" } ngOnInit(): void { } } inputs: ['name:newName']中,name代表当前类的属性,冒号后面的newName代表别名,也就是说在传值的时候,我们是通过[newName]将值传递到组件的name属性。然后我们在模板文件test.component.html增加输出,以便测试值是否传递。<p>{{name}}</p>我们在app.component.html中调用app-test组件,并通过[]传值。<app-test [newName]='"test"'></app-test>组件的输出angular中通过()实现组件的输出。比如我们在app-test组件中,定义了一个like方法,此方法执行时,回调父组件的ringWasPlace方法,并传递一个字符串。在app.component.ts代码如下import { Component, EventEmitter, OnInit,Input } from '@angular/core'; @Component({ selector: 'app-test', templateUrl: './test.component.html', styleUrls: ['./test.component.css'], outputs: ['putRingOnIt'] }) export class TestComponent implements OnInit { putRingOnIt: EventEmitter<string> @Input('newName') name: string; constructor() { this.name = "" this.putRingOnIt = new EventEmitter(); } ngOnInit(): void { } liked(): void { this.putRingOnIt.emit('oh oh oh') } }父组件模板文件app.component.html<app-test [newName]='"test"' (putRingOnIt)="ringWasPlace($event)"></app-test> <h1> {{message}} </h1>父组件类app.component.ts如下import { Component } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { message: string; constructor() { this.message = "" } ringWasPlace(message: string):void { this.message = message; } } 测试,点击一下like按钮,看到输出如下
2021年09月05日
1,014 阅读
0 评论
0 点赞
2021-09-05
开启angular之旅
前言这年头,作为新生代的农民工真的太难了。虽说活到老,学到老,但是学习的速度永远跟不上技术的迭代。细数一下,做过的东西真不少了。angular开发环境打开安装nodejs进入nodejs官网,找到自己对应版本,下载安装即可安装完成后,输入node -v npm -vnpm替换淘宝源npm config set registry https://registry.npm.taobao.org安装angular/cliangular/cli是一个类似工具的东西,具体的我也没有深究,根据我使用一次的直观感受,它的作用就是,安装它后,我们可以通过各种不同的命令行来实现angular项目的创建,运行,调试等等npm install -g @angular/cli输入ng version输出以上页面,代表安装成功。创建angular项目ng new 项目名称创建angular项目,如下示例:创建名为 angular的项目ng new angular生成项目如下运行angular项目在项目文件夹下,输入ng serve打包运行项目,然后我们可以通过默认的4200端口访问http://localhost:4200/查看项目
2021年09月05日
1,145 阅读
0 评论
0 点赞
2021-09-04
关于node的一些默认配置
作为一个后端高企前端真的非常费劲。其实,之前也接触过Node,但是基本属于能用但是不会用的地步。最近在开发时,将一个angular的前端项目从windows迁移到linux继续开发,中间遇到了很多问题,借此记录一下。Linux默认配置可以通过npm config list查看Node的配置列表。也可以通过一下命令,通过可编辑文件的方式编辑配置文件。npm config edit配置文件位于登录用户(我这里使用root登录)的目录下,是个隐藏文件,可以通过以下命令查看cd /root ls -aWin默认配置可以通过npm config list查看Node的配置列表。在windows系统中,npm全局包下载位置在'C:\用户\AppData\Roaming\npm\node_modules'中。修改全局包存储位置可以通过npm config set命令修改默认全局包的存储路径比如npm config set prefix /usr/lib/node_modules将全局包存储路径改到/usr/lib/node_modules也可以通过npm config delete命令删除某个配置项比如npm config delete prefix删除配置的全局包信息。
2021年09月04日
931 阅读
0 评论
0 点赞
2021-08-30
一文撸清楚Java中的枚举enum
Java Enum类型的语法结构尽管和java类的语法不一样,应该说差别比较大。但是经过编译器编译之后产生的是一个class文件。该class文件经过反编译可以看到实际上是生成了一个类,该类继承了java.lang.Enum<E>。定义一个枚举定义一个枚举,最简单的方式可能向下面这样public enum Size{ SMALL, MEDIUM, LARGE, EXTRA_LARGE };枚举的构造函数枚举可以定义构造函数,但是必须是private类型。public enum DishType { Fish("FISH"), Chiken("CHIKEN"), Meat("MEAT"); private String type; private DishType(String type) { this.type = type; } public String getType() { return type; } public void setType(String type) { this.type = type; } }你可以向上面这样添加private修饰符或者啥都不添加,但是不能添加public或protect。重写方法与类一样,可以重写枚举的方法,比如toString()方法。public enum DishType { Fish("FISH"), Chiken("CHIKEN"), Meat("MEAT"); private String type; private DishType(String type) { this.type = type; } public String getType() { return type; } public void setType(String type) { this.type = type; } @Override public String toString() { return type; } }获取枚举值可以通过.语法获取枚举值。如果想获取所有的值,可以通过values()方法 for(DishType dishType:DishType.values()){ System.out.println(dishType); }获取原始值可以通过ordinal()方法获取枚举的原始值,也就是1、2、3System.out.println(fish.ordinal());控制台输出0,因为Fish是我们在枚举值第一个定义的,从0开始。反向获取枚举可以通过valueOf()反向获取枚举值DishType.valueOf("Fish");枚举中定义方法比如在枚举中定义一个sayHello方法public void sayHello() { System.out.println("hello,i am " + type); }然后调用 DishType fish = DishType.valueOf("Fish"); fish.sayHello();枚举中的匿名内部类枚举实例后有花括号时,该枚举实例是枚举类匿名内部之类定义性别枚举类package com.company.enumpackage; public enum Gender { //枚举值调用对应构造器创建 MALE("男") { public void info() { System.out.println("这个枚举代表男"); } }, FEMALE("女") { public void info() { System.out.println("这个枚举代表女"); } }, UNKNOWN("UNKNOWN"); private final String name; //枚举类的构造器只能使用private修饰 private Gender(String name) { this.name = name; } public String getName() { return this.name; } public void info() { System.out.println("这是第一个用于定义性别的枚举类"); } }调用Gender male = Gender.MALE; Gender female = Gender.FEMALE; Gender unKnown = Gender.UNKNOWN; male.info(); female.info(); unKnown.info();
2021年08月30日
894 阅读
0 评论
24 点赞
2021-08-29
java8 Optional<T>简介
Optional<T>是Java8增加的一个用于处理NullPointException异常的类。Optional<T>是一个容器类,代表一个值存在或不存在。如果用过Spring Boot Data Jpa,会发现里面好多返回值都是Optional<T>类型的。下面我们介绍一下Optional<T>类的常见使用方法。作为演示,我们创建了一个Dish类,代码如下:public class Dish { /** * 构造函数 * @param name 名称 * @param isVegetarian 是否蔬菜 */ public Dish(String name, boolean isVegetarian) { this.name = name; this.isVegetarian = isVegetarian; } /** * 名称 */ private String name; /** * 是否蔬菜 */ private boolean isVegetarian; @Override public String toString(){ return name; } public String getName() { return name; } public void setName(String name) { this.name = name; } public boolean isVegetarian() { return isVegetarian; } public void setVegetarian(boolean isVegetarian) { this.isVegetarian = isVegetarian; } } 创建一个Optional<T>实例创建Optional<T>实例,有两个方法,分别是of、ofNullable,ofNullable与是of的区别在于,如果传递的参数是null,那么会创建一个空的(empty)Optional<T>实例。 Optional<Dish> dishOptionalofNullable = Optional.ofNullable(null); dishOptionalofNullable.ifPresent(System.out::println); System.out.println("准备输出of方法的值"); Optional<Dish> dishOptionalof = Optional.of(null); dishOptionalof.ifPresent(System.out::println);运行代码,我们可以看到如下输出我们可以看到ofNullable创建的实例,即使传递的参数是null调用实例方法时,系统也会抛出异常,而of传递null值时,创建的Optional<T>实例也是null。判断是否为空通过isPresent()方法可以判断Optional<T>包含的类是否是null。返回true代表不是null,返回false代表是null。 Optional<Dish> emptyOptional = Optional.empty(); if (emptyOptional.isPresent()) { System.out.println(emptyOptional.get()); } else { System.out.println("empty optional"); }还有一个方法是ifPresent(Consumer<? super T> action)可以传递一个Consumer接口,当类不是null。 Optional<Dish> emptyOptional = Optional.empty(); emptyOptional.ifPresent(System.out::println);还有一个方法 ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction),当类不是null时,调用action接口,否则调用emptyAction接口。 List<Dish> menu = new ArrayList<>(); Dish fish = new Dish("鱼", false); Dish tomato = new Dish("西红柿", true); menu.add(fish); menu.add(tomato); menu.stream().filter(Dish::isVegetarian).findAny().ifPresentOrElse(System.out::println, () -> { System.out.println("没找到呢"); });获取值获取值比较简单,通过get()方法即可。 Optional<Dish> fishOptional = Optional.ofNullable(new Dish("鱼", false)); if(fishOptional.isPresent()){ System.out.println(fishOptional.get()); }通过orElse(T other)可以设置默认值。 Optional<Dish> fishOptional = Optional.ofNullable(new Dish("鱼", false)); Dish defaultDish = new Dish("default", false); if (fishOptional.isPresent()) { System.out.println(fishOptional.orElse(defaultDish)); } Optional<Dish> emptyOptional = Optional.empty(); System.out.println(emptyOptional.orElse(defaultDish));上面emptyOptional是空的,那么我们可以返回一个默认的Dish实例,下面看下控制台输出。orElse(T other)还有一些变种方法,大家可以试一下。
2021年08月29日
1,032 阅读
0 评论
0 点赞
2021-08-25
java中对象和Map的相互转换
实体对象转map集合private static Map<String, String> obj2Map(Object obj) { Map<String, String> map = new HashMap<String, String>(); // System.out.println(obj.getClass()); // 获取f对象对应类中的所有属性域 Field[] fields = obj.getClass().getDeclaredFields(); for (Field field : fields) { String varName = field.getName(); varName = varName.toLowerCase();//将key置为小写,默认为对象的属性 try { // 获取原来的访问控制权限 boolean accessFlag = field.isAccessible(); // 修改访问控制权限 field.setAccessible(true); // 获取在对象f中属性fields[i]对应的对象中的变量 Object o = field.get(obj); if (o != null) map.put(varName, o.toString()); // System.out.println("传入的对象中包含一个如下的变量:" + varName + " = " + o); // 恢复访问控制权限 field.setAccessible(accessFlag); } catch (IllegalArgumentException | IllegalAccessException ex) { ex.printStackTrace(); } } return map; }将map集合转化成实体对象利用反射实现/** * Map转成实体对象 * @param map map实体对象包含属性 * @param clazz 实体对象类型 * @return */ public static <T> T map2Object(Map<String, Object> map, Class<T> clazz) { if (map == null) { return null; } T obj = null; try { obj = clazz.newInstance(); Field[] fields = obj.getClass().getDeclaredFields(); for (Field field : fields) { int mod = field.getModifiers(); if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) { continue; } field.setAccessible(true); field.set(obj, map.get(field.getName())); } } catch (Exception e) { e.printStackTrace(); } return obj; }
2021年08月25日
921 阅读
0 评论
0 点赞
2021-08-21
java8谓词复合和函数复合
谓词及功能复合,就是在通过组合已有的谓词或功能,形成更加复杂的谓词或功能。谓词复合谓词(Predicate)接口包含三个方法:negate、and和or,通过这三个方法,我们可以在已有谓词的基础上,组合形成更加复杂的谓词。negate代表非,and代表和,or代表或。举个例子,我们有一个苹果(Apple)类,包含颜色(color)和重量(weight)两个属性。class Apple { public Apple(String color, double weight) { this.color = color; this.weight = weight; } private String color; private double weight; @Override public String toString() { return "color:" + color + "---------" + "weight:" + weight; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public double getWeight() { return weight; } public void setWeight(double weight) { this.weight = weight; } } 然后我们创建一个苹果的列表,存储几条测试数据。List<Apple> appleList = new ArrayList<>(); appleList.add(new Apple("red", 2)); appleList.add(new Apple("red", 6)); appleList.add(new Apple("green", 2)); appleList.add(new Apple("green", 6));negate测试我们创建一个查找红色苹果的谓词Predicate<Apple> redApple = apple -> "red".equals(apple.getColor());然后创建一个查找不是红色苹果的谓词List<Apple> notRedAppleList = appleList.stream().filter(notRedApple).collect(Collectors.toList()); for (Apple apple : notRedAppleList) { System.out.println(apple); }and测试我们首先创建一个查找重量大于5的谓词Predicate<Apple> weightThan5Apple = apple -> apple.getWeight() > 5;然后组合红苹果及重量大于5的两个谓词Predicate<Apple> redAndWeightThan5Apple = redApple.and(weightThan5Apple);测试 List<Apple> redAndWeightThan5AppleList = appleList.stream().filter(redAndWeightThan5Apple).collect(Collectors.toList()); for (Apple apple : redAndWeightThan5AppleList) { System.out.println(apple); }or测试还是利用刚才的谓词,这次我们测试重量大于5或者颜色是红色的苹果Predicate<Apple> redOrWeightThan5Apple = redApple.or(weightThan5Apple);测试 List<Apple> redOrWeightThan5AppleList = appleList.stream().filter(redOrWeightThan5Apple).collect(Collectors.toList()); for (Apple apple : redOrWeightThan5AppleList) { System.out.println(apple); }函数复合函数复合跟谓词复合类似,函数复合提供了两个接口方法:andThen和compose,通过字面含义我们可以知道andThen代表先执行第一个函数,然后在执行第二个函数,compose与之相反,先执行第二个函数,在执行第一个函数。 Function<Integer, Integer> funcPlus = x -> x + 1; Function<Integer, Integer> funcMul = y -> y * 2; Function<Integer, Integer> funcAndThen = funcPlus.andThen(funcMul); Function<Integer, Integer> funcCompose = funcPlus.compose(funcMul); System.out.println("andThen:" + funcAndThen.apply(1)); System.out.println("compose:" + funcCompose.apply(1));通过测试,我们发现andThen先执行了第一个函数,也就是1+1=2,然后执行2*2=4,所以最终结果就是4。compose限制性1*2=2,然后执行1+2=3,所以结果是3。
2021年08月21日
990 阅读
0 评论
0 点赞
1
...
19
20
21
...
53