首页
技术博客
PHP教程
数据库技术
前端开发
HTML5
Nginx
php论坛
新用户注册
|
会员登录
PHP教程
技术博客
编程问答
PNG素材
编程语言
前端技术
Android
PHP教程
HTML5教程
数据库
Linux技术
Nginx技术
PHP安全
WebSerer
职场攻略
JavaScript
开放平台
业界资讯
大话程序猿
登录
极速注册
取消
热门标签 | HotTags
random
text
require
chat
settings
int
subset
process
hash
bit
grid
client
typescript
python
web3
string
httpclient
spring
iostream
email
erlang
object
express
python3
hashset
bytecode
cookie
export
import
uml
c语言
filter
bitmap
scala
include
rsa
heatmap
solr
char
callback
web
actionscrip
case
post
ascii
perl
emoji
java
integer
hashcode
version
hook
flutter
const
byte
replace
less
controller
dll
数组
go
cpython
md5
install
tree
eval
dockerfile
function
plugins
merge
uri
nodejs
php
yaml
frameworks
dagger
bash
instance
timezone
当前位置:
开发笔记
>
编程语言
> 正文
Scala学习指南:从零开始掌握基础
作者:爱与嫉妒咋 | 来源:互联网 | 2024-11-07 18:07
本指南从零开始介绍Scala编程语言的基础知识,重点讲解了Scala解释器REPL(读取-求值-打印-循环)的使用方法。REPL是Scala开发中的重要工具,能够帮助初学者快速理解和实践Scala的基本语法和特性。通过详细的示例和练习,读者将能够熟练掌握Scala的基础概念和编程技巧。
一、Scala解释器的使用
REPL:Read(取值)-> Evaluation(求值)-> Print(打印)-> Loop(循环)
scala解释器也被称为REPL,会快速编译scala代码为字节码,然后交给JVM来执行。
计算表达式:在scala>命令行内,键入scala代码,解释器会直接返回结果。
如果你没有指定变量来存放这个值,那么值默认的名称为res,而且会
显示结果的数据类型,比如Int、Double、String等等。
例如,输入1 + 1,会看到res0: Int = 2
内置变量:在后面可以继续使用res这个变量,以及它存放的值。
例如,"Hi, " + res0,返回res2: String = Hi, 2
自动补全:在scala>命令行内,可以使用Tab键进行自动补全。
二、声明变量
声明val常量:可以声明val常量来存放表达式的计算结果。
例如,val result = 1 + 1
但是常量声明后,是无法改变它的值的,否则会返回error: reassignment
to val的错误信息。
声明var变量:如果要声明值可以改变的引用,可以使用var变量。
例如,var myresult = 1,myresult = 2
但是在Scala程序中,通常建议使用val,也就是常量。
因为在Spark的大型复杂系统中,需要大量的网络传输数据,
如果使用var,值可能被错误的更改,所以建议多使用val。
三、数据类型与操作符
1》基本数据类型: Byte、 Char、 Short、 Int、 Long、 Float、 Double、 Boolean。
Scala的数据类型统一都是类。 Scala自己会负责基本数据类型和引用类型的转换操作。
使用以上类型, 直接就可以调用大量的函数, 例如, 1.toString(), 1.to(10)。
类型的加强版类型: Scala使用很多加强类给数据类型增加了上百种增强的功能或函数。
·例如, String类通过StringOps类增强了大量的函数, "Hello".intersect(" World")。
·例如, Scala还提供了RichInt、 RichDouble、 RichChar等类型, RichInt就提供了to函数, 1.to(10), 此处Int先隐式转换为RichInt,然后再调用其to函数。
2》基本操作符: Scala的算术操作符与Java的算术操作符也没有什么区别, 比如+、 -、 *、 /、 %等, 以及&、 |、 ^、 >>、 <<等。
但是, 在Scala中, 这些操作符其实是数据类型的函数, 比如1 + 1, 可以写做1.+(1)
例如, 1.to(10), 又可以写做1 to 10
注:Scala中没有提供++、--操作符
, 我们只能使用
+
和
-
, 比如
counter = 1
,
counter++
是错误的, 必须写做
counter += 1
3》除了方法之外,Scala还提供函数
数学函数:sqrt() pow() min()
引入特定包时使用import 包名._;
import scala.math._ ,_是通配符,类似Java中的*
四、流程控制结构
1、if表达式的定义: 在Scala中, if表达式是有值的, 就是if或者else中最后一行语句返回的值。
例如, val age = 30; if (age > 18) 1 else 0
可以将if表达式赋予一个变量, 例如, val isAdult = if (age > 18) 1 else 0
另外一种写法, var isAdult = -1; if(age > 18) isAdult = 1 else isAdult = 0, 但是通常使用上一种写法
2、if表达式的类型推断: 由于if表达式是有值的, 而if和else子句的值类型可能不同, 此时if表达式的值是什么类型呢?
Scala会自动进行推断, 取两个类型的公共父类型Any。
例如, if(age > 18) 1 else 0, 表达式的类型是Int, 因为1和0都是Int
例如, if(age > 18) "adult" else 0, 此时if和else的值分别是String和Int, 则表达式的值是Any, Any是String和Int的公共父类型。
如果if后面没有跟else, 则默认else的值是Unit, 也用()表示, 类似于Java中的void或者null。
例如, val age = 12; if(age > 18) "adult"。 此时就相当于if(age > 18) "adult" else ()。
3、将if语句放在多行中: 默认情况下, REPL只能解释一行语句, 但是if表达式通常需要放在多行。
可以使用{}的方式, 比如以下方式, 或者使用:paste和ctrl+D的方式。
if(age > 18) { "adult"
} else if(age > 12) "teenager" else "children"
注:默认情况下, Scala不需要语句终结符, 默认将每一行作为一个语句
4、一行放多条语句: 如果一行要放多条语句, 则必须使用语句终结符
例如, 使用分号作为语句终结符, var a, b, c = 0; if(a <10) { b = b + 1
;
c = c + 1 }
通常来说, 对于多行语句, 还是会使用花括号的方式
var a, b, c = 0;if(a <10) {
b = b + 1;c = c + 1}
5、块表达式: 块表达式, 指的就是{}中的值, 其中可以包含多条语句, 最后一个语句的值就
是块表达式的返回值。
例如, var d = if(a <10) { b = b + 1; c + 1 }
6、输入和输出
print和println: print打印时不会加换行符, 而println打印时会加一个换行符。
printf可以用于进行格式化,例如, printf("Hi, my name is %s, I'm %d years old .", "Leo", 30)
readLine: readLine允许我们从控制台读取用户输入的数据, 类似于Java中的System.in和Scanner的作用。
综合案例:使用paste和ctrl+D
val name = readLine("Welcome to Game House. Please tell me your name: ")
print("Thanks. Then please tell me your age: ")
val age = readInt()
if(age > 18) {
printf("Hi, %s, you are %d years old, so you are legel to come here!", name, age)
} else {
printf("Sorry, boy, %s, you are only %d years old. you are illegal to come here!",
name, age)
}
五、循环
1、Scala拥有与Java相同的while和do-while循环
但没有与for(初始化变量;判断条件;更新变量)循环直接对应的对构。
Scala中的for:
for(i
<-
表达式)
,让变量i遍历<-右边表达式的所有值。
注意:
1、在for循环的变量之前并没有val或var的指定,该变量的类型是集合的元素类型。
2、循环变量的作用域一直持续到循环结束
3、to 和 until,两者得到都是集合,区别如下:
scala> 1 to 10 (包含10)
res8: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> 1 until 10 (不包含10)
res10: scala.collection.immutable.Range = Range(1, 2, 3, 4, 5, 6, 7, 8, 9)
4、循环的几种遍历方式
一、直接遍历------遍历字符串
二、求和---------1到8的和
三、以 变量<-表达式 的形式提供多个生成器,用分号将它们隔开(嵌套循环)
for(i<- 1 to 9;j<- 1 to i){
if(i==j) println(j+"*"+i+"="+j*i)
else print(j+"*"+i+"="+j*i+"\t")
}
四、在循环中使用变量
for(i<- 1 to 6;tem=2*i-1;j<- 1 to tem){
print("*");if(j==tem) {println()}}
五、守卫式,即在for循环中添加过滤条件if语句
for(i<- 1 to 3;j<- 1 to 3 if i!=j) print((10*i+j)+" ")
六、推导式
如果for循环的循环体以yield开始,则该循环会构造出一个集合,每次迭代生成集合中的一个值。
六、函数
1、函数的分类
单行函数:def sayHello(name: String) = print("Hello, " + name)
多行函数:如果函数体中有多行代码, 则可以使用代码块的方式包裹多行代码, 代码块中最后一行
的返回值就是整个函数的返回值。 与Java中不同, 不能使用return返回值。
比如如下的函数, 实现累加的功能:
def sum(n:
Int
) :
Int
= {
var sum = 0;
for(i <- 1 to n) sum += i
sum}
2、函数的定义与调用
在Scala中定义函数时, 需要定义函数的
函数名、 参数、 函数体。
def sayHello(name: String, age: Int) = {
if (age > 18) { printf("hi %s, you are a big boy\n", name); age }
else { printf("hi %s, you are a little boy\n", name); age}}
调用:sayHello("leo", 30)
注:Scala要求必须给出所有参数的类型, 但是不一定给出函数返回值的类型。
只要右侧的函数体中不包含递归的语句, Scala就可以自己根据右侧的表达式推断出返回类型。
3、递归函数与返回类型
如果在函数体内递归调用函数自身, 则必须给出函数的返回类型。
例如, 实现经典的斐波那契数列:
def feibo(n:Int):Int={
if(n<=2) 1
else feibo(n-1)+feibo(n-2)}
例如如下阶乘:
4、参数
1》默认参数
在Scala中, 有时我们调用某些函数时, 不希望给出参数的具体值, 而希望使用参数自身默认的值, 此时就在定义函数时使用默认参数。
def sayHello(firstName: String, middleName: String = "William", lastName:
String = "Croft") = firstName + " " + middleName + " " + lastName
如果给出的参数不够, 则会从左往右依次应用参数。
Java与Scala实现默认参数的区别如下:
-----------------------------------------------------------------------------------
Java:
public void sayHello(String name, int age) {
if(name == null) {
name = "defaultName"
} if(age == 0) {
age = 18
}}
sayHello(null, 0)
-----------------------------------------------------------------------------------
Scala:
def sayHello(name: String, age: Int = 20) {
print("Hello, " + name + ", your age is " + age)}
sayHello("leo")
2》带名参数
在调用函数时, 也可以不按照函数定义的参数顺序来传递参数, 而是使用带名参数的方式来
传递。如:sayHello(firstName = "Mick", lastName = "Nina", middleName = "Jack")
还可以混合使用未命名参数和带名参数, 但是未命名参数必须排在带名参数前面。如下:
正确:sayHello("Mick", lastName = "Nina", middleName = "Jack")
错误:sayHello("Mick", firstName = "Nina", middleName = "Jack")
3》使用序列调用变长参数
在如果要将一个已有的序列直接调用变长参数函数, 是不对的。 比如val s = sum(1 to 5)。
此时需要使用Scala特殊的语法将参数定义为序列, 让Scala解释器能够识别。
这种语法非常有用!Spark的源码中大量地使用。
例如:val s = sum(1 to 5 : _*) 通过
:_*
转换成参数序列
案例: 使用递归函数实现累加,如下:
def sum2(nums: Int*): Int = {
if (nums.length == 0) 0
else nums.head + sum2(nums.tail: _*)
}
调用:sum2(1,2,3,4,5) 或是 sum2(1 to 5 :_*)
注:1、定义nums为一个变长参数,定义函数时用*,调用函数需要表示一个参数序列时用:_*
2、head 表示集合中的第一个元素,tail 表示集合中除了第一个元素外的其他元
素
七、过程
定义:在Scala中, 定义函数时, 如果函数体直接包裹在了花括号里面, 而没有使用=连接,
则函数的返回值类型就是Unit, 这样的函数就被称之为过程。过程通常用于不需要返回值的函数。
过程还有一种写法, 就是将函数的返回值类型定义为Unit。比较如下:
def sayHello(name: String) = "Hello, " + name
def sayHello(name: String) { print("Hello, " + name); "Hello, " + name }
def sayHello(name: String): Unit = "Hello, " + name
八、lazy值
在Scala中, 提供了lazy值的特性, 也就是说, 如果将一个变量声明为lazy, 则只有在第一次使用
该变量时, 变量对应的表达式才会发生计算。这种特性对于特别耗时的计算操作特别有用, 比如打开文件进行IO, 进行网络IO等。
1、import scala.io.Source._
lazy val lines = fromFile("C://Users//Administrator//Desktop//test.txt").mkString
即使文件不存在, 也不会报错, 只有第一次使用变量时会报错, 证明了表达式计算的lazy特性
val lines = fromFile("C://Users//Administrator//Desktop//test.txt").mkString 这句会报错
2、val lines=sc.textFile("file:///home/tg/datas/ws")
val rdd1=lines.flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_)
val rdd2=rdd1.collect
算子: flatMap() map() reduceByKey()转换类型的算子(transformation)
collect()行动类型的算子(action)
3、val rdd=lines.flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_).map(m=>(m._2,m._1))
.sortByKey(true).map(m=>(m._2,m._1)).collect
注:转换类型的算子就是lazy类型,当遇到action行动类型的算子时,才会触发执行。
总结下划线的用法:
1、导包时,导入包中所有内容 import scala.io.Source._
2、将数列(集合)转换成参数序列 val result=sum(1 to 10:_*)
3、表示Spark算子操作的每一个元素 lines.flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_)
八、异常
在Scala中, 异常处理和捕获机制与Java是非常相似的。
try {
throw new IllegalArgumentException("x should not be negative")
} catch {
case _:
IllegalArgumentException => println("Illegal Argument!")
} finally {
print("release resources!")
}
try {
throw new IOException("user defined exception")
} catch {
case e1:
IllegalArgumentException => println("illegal argument")
case e2:
IOException => println("io exception")
}
九、数组
若数组长度固定使用Array,若数组长度不固定则使用ArrayBuffer
1、定长数组的两种创建方式
1》val nums=new Array[Int](10); //10个整数的数组 2》val array=Array("hello","jack")
省略关键字new创建数组的方式,实际上调用的是 Array.scala中的apply()方法。源码如下:
def apply[T: ClassTag](xs: T*): Array[T] = {
val array = new Array[T](xs.length)
var i = 0
for (x <- xs.iterator) {
array(i) = x;
i += 1 }
array}
2、变长数组:数组缓冲
注:scala.collection.mutable._ 可变 scala.collection.immutable._ 不可变
对于那种长度按需要变化的数组,Java有ArrayList,Scala有ArrayBuffer
变长数组ArrayBuffer使用时要导包 import scala.collection.mutable.ArrayBuffer
var arr1=ArrayBuffer[Int]()
变长数组操作:1、arr1+=1 2、arr1+=(2,5,6) 3、arr1 ++=Array(3,4)
4、arr1.trimEnd(5) 返回值为空,需再次调用arr1来查看删除后的数据
5、arr1.insert(1,3,4) 指定1的位置添加3,4元素
6、arr1.remove(3)
7、arr1.remove(3,2) 指定位置删除指定数量的元素
3、变长数组与定长数组之间的转换
变长数组→定长数组:.toArray (不改变原来的数组,系统会自动创建一个新的arry)
定长数组→变长数组:.toBuffer
4、遍历数组
until是RichInt类的方法, 返回所有小于( 不包括) 上限的数字。
5、数组常用算法
,除了sum求和,max最大值,min最小值以外还有如下:
6、数组的quickSort()快速排序方法
scala.util.Sorting.quickSort(array)
十、
高阶函数
filter :把一个函数作为参数的函数
for(i <- 0 until arr1.length if(arr1(i)%2==0)) print(arr1(i)+" ")
array.filter(m=>m%2==0) 这里的m可以省去简写成 array.filter(_%2==0)
m=>m%2==0 匿名函数 m=>{m%2==0}
算子: spark中的算子有一部分是和scala中的高阶函数是一致的,
但是有一部分是scala中没有的,比如reducekey
简写用下划线代替m: val rdd=lines.flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_)
lines.flatMap(m=>m.split(" ")).map(word=>(word,1)).reduceByKey((x,y)=>x+y)
十一、
映射(Map)
1、Scala映射就是键值对的集合Map。默认情况下,Scala中使用不可变的映射。
如果想使用可变集合Map,必须导入scala.collection.mutable.Map
不可变:
val map=Map("tom"->20,"jack"->23,"marray"->22)
val map2=Map(("tom",20),("jack",23),("marray",22))
可变:
val map3=scala.collection.mutable.Map(("tom",20),("jack",23),("marray",22))
val map4=new scala.collection.mutable.HashMap[String,Int]
映射这种数据结构是一种将键映射到值的函数。 区别在于通常的函数计算值, 而映射只是做查询。
2、获取映射中的值
注:1》如果映射并不包含请求中使用的键, 则会抛出异常。
2》要检查映射中是否有某个指定的键, 可以用contains方法。
3》getOrElse方法, 若包含相应的键, 就返回这个键所对应的值, 否则返加0。
4》映射.get(键)这样的调用返回一个Option对象, 要么是Some(键对应的值), 要么是None。
3、修改Map的元素
更新可变Map集合:
1》更新Map的元素 ages("Leo") = 31
2》增加多个元素 ages += ("Mike" -> 35, "Tom" -> 40)
3》 移除元素 ages -= "Mike"
更新不可变Map集合:
1》 添加不可变Map的元素, 产生一个新的集合Map, 原Map不变
val ages2 = ages + ("Mike" -> 36, "Tom" -> 40)
2》移除不可变Map的元素, 产生一个新的集合Map, 原Map不变
val ages3 = ages - "Tom"
4、遍历Map操作
//遍历map的entrySet for ((key, value) <- ages) println(key + " " + value)
// 遍历map的key for (key <- ages.keySet) println(key)
// 遍历map的value for (value <- ages.values) println(value)
// 生成新map, 反转key和value for ((key, value) <- ages) yield (value, key)
5、SortedMap和LinkedHashMap
// SortedMap可以自动对Map的key的排序
val ages = scala.collection.immutable.SortedMap("leo" -> 30, "alice" -> 15, "jen" -> 25)
// LinkedHashMap可以记住插入entry的顺序
val ages = new scala.collection.mutable.LinkedHashMap[String, Int]
ages("leo") = 30
ages("alice") = 15
ages("jen") = 25
6、Java Map与Scala Map的隐式转换
import scala.collection.JavaConversions.mapAsScalaMap
val javaScores = new java.util.HashMap[String, Int]()
javaScores.put("Alice", 10)
javaScores.put("Bob", 3)
javaScores.put("Cindy", 8)
val scalaScores: scala.collection.mutable.Map[String, Int] = javaScores
===========================================================
import scala.collection.JavaConversions.mapAsJavaMap
import java.awt.font.TextAttribute._
val scalaAttrMap = Map(FAMILY -> "Serif", SIZE -> 12)
val fOnt= new java.awt.Font(scalaAttrMap)
7、元组(tuple)
概念:元组是不同类型的值的聚集,对偶是元组的最简单形态,元组的索引从1开始,而不是0
Tuple拉链操作:
Tuple拉链操作指的就是zip操作,zip操作是Array类的方法, 用于将两个Array, 合并为一个Array
比如 Array(v1)和Array(v2), 使用zip操作合并后的格式为Array((v1,v2)),合并后的Array的元素类型为Tuple。例子如下:
val students = Array("Leo", "Jack", "Jen")
val scores = Array(80, 100, 90)
val studentScores = students.zip(scores)
for ((student, score) <- studentScores) println(student + " " + score)
注:如果Array的元素类型是Tuple, 调用Array的toMap方法, 可以将Array转换为Map
如,studentScores.toMap
scala
eval
io
int
编译
jvm
string
spark
byte
写下你的评论吧 !
吐个槽吧,看都看了
会员登录
|
用户注册
推荐阅读
import
从 .NET 转 Java 的自学之路:IO 流基础篇
本文详细介绍了 Java 中的 IO 流,包括字节流和字符流的基本概念及其操作方式。探讨了如何处理不同类型的文件数据,并结合编码机制确保字符数据的正确读写。同时,文中还涵盖了装饰设计模式的应用,以及多种常见的 IO 操作实例。 ...
[详细]
蜡笔小新 2024-12-26 17:37:25
import
golang常用库:配置文件解析库/管理工具viper使用
golang常用库:配置文件解析库管理工具-viper使用-一、viper简介viper配置管理解析库,是由大神SteveFrancia开发,他在google领导着golang的 ...
[详细]
蜡笔小新 2024-12-28 13:47:52
client
深入解析JVM垃圾收集器
本文基于《深入理解Java虚拟机:JVM高级特性与最佳实践》第二版,详细探讨了JVM中不同类型的垃圾收集器及其工作原理。通过介绍各种垃圾收集器的特性和应用场景,帮助读者更好地理解和优化JVM内存管理。 ...
[详细]
蜡笔小新 2024-12-28 13:35:19
import
Java并发编程:LinkedBlockingQueue的实际应用
本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ...
[详细]
蜡笔小新 2024-12-27 18:51:49
object
编写有趣的VBScript恶作剧脚本
本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ...
[详细]
蜡笔小新 2024-12-28 09:46:23
object
新浪笔试题
1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ...
[详细]
蜡笔小新 2024-12-27 19:32:17
int
深入理解设计模式与七大原则
本文详细探讨了Java中的24种设计模式及其应用,并介绍了七大面向对象设计原则。通过创建型、结构型和行为型模式的分类,帮助开发者更好地理解和应用这些模式,提升代码质量和可维护性。 ...
[详细]
蜡笔小新 2024-12-27 19:10:10
int
数据管理权威指南:《DAMA-DMBOK2 数据管理知识体系》
本书提供了全面的数据管理职能、术语和最佳实践方法的标准行业解释,构建了数据管理的总体框架,为数据管理的发展奠定了坚实的理论基础。适合各类数据管理专业人士和相关领域的从业人员。 ...
[详细]
蜡笔小新 2024-12-27 18:29:55
email
JQuery基础:省市联动与表单验证
本文介绍了如何使用JQuery实现省市二级联动和表单验证。首先,通过change事件监听用户选择的省份,并动态加载对应的城市列表。其次,详细讲解了使用Validation插件进行表单验证的方法,包括内置规则、自定义规则及实时验证功能。 ...
[详细]
蜡笔小新 2024-12-27 17:10:48
object
Java 序列化接口详解
本文深入探讨了 Java 中的 Serializable 接口,解释了其实现机制、用途及注意事项,帮助开发者更好地理解和使用序列化功能。 ...
[详细]
蜡笔小新 2024-12-27 15:06:12
bit
基于KVM的SRIOV直通配置及性能测试
SRIOV介绍、VF直通配置,以及包转发率性能测试小慢哥的原创文章,欢迎转载目录?1.SRIOV介绍?2.环境说明?3.开启SRIOV?4.生成VF?5.VF ...
[详细]
蜡笔小新 2024-12-25 19:26:39
string
Java编程入门:第一周学习总结
本文总结了Java程序设计第一周的学习内容,涵盖语言基础、编译解释过程及基本数据类型等核心知识点。 ...
[详细]
蜡笔小新 2024-12-25 13:31:43
object
深入理解Redis的数据结构与对象系统
本文详细探讨了Redis中的数据结构和对象系统的实现,包括字符串、列表、集合、哈希表和有序集合等五种核心对象类型,以及它们所使用的底层数据结构。通过分析源码和相关文献,帮助读者更好地理解Redis的设计原理。 ...
[详细]
蜡笔小新 2024-12-25 04:11:22
string
MySQL DateTime 类型数据处理及.0 尾数去除方法
本文介绍如何在 MySQL 中处理 DateTime 类型的数据,并解决获取数据时出现的.0尾数问题。同时,探讨了不同场景下的解决方案,确保数据格式的一致性和准确性。 ...
[详细]
蜡笔小新 2024-12-24 19:25:10
string
Java 数组及其常用操作
本文详细介绍了 Java 中的数组类型、定义方法以及常见操作,帮助开发者更好地理解和使用 Java 数组。 ...
[详细]
蜡笔小新 2024-12-24 12:34:53
爱与嫉妒咋
这个家伙很懒,什么也没留下!
Tags | 热门标签
random
text
require
chat
settings
int
subset
process
hash
bit
grid
client
typescript
python
web3
string
httpclient
spring
iostream
email
erlang
object
express
python3
hashset
bytecode
cookie
export
import
uml
RankList | 热门文章
1
css怎么给一个盒子加盒阴影
2
css中grid布局和表格有什么区别
3
css怎么给图片加上下边框
4
css calc()有啥用
5
css为什么要放在头部呢
6
css三个字如何和两个字对齐
7
css如何实现不显示元素
8
css如何设置图片轮廓
9
css grid布局的优缺点是什么?
10
css如何让页脚固定在底部
11
css3都有哪些新内容
12
css的语法规则是什么
13
如何解决css float错位问题
14
css行元素跟块元素有哪些相同点
15
css什么时候用padding
PHP1.CN | 中国最专业的PHP中文社区 |
DevBox开发工具箱
|
json解析格式化
|
PHP资讯
|
PHP教程
|
数据库技术
|
服务器技术
|
前端开发技术
|
PHP框架
|
开发工具
|
在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved |
京公网安备 11010802041100号
|
京ICP备19059560号-4
| PHP1.CN 第一PHP社区 版权所有