objects = strs; // !!!在 Java 中不允许
// ……
}
为解决上述问题,必须声明对象的类型为 Source,但是这毫无意义,赋值和取值也显得非常麻烦,并没有让工作变轻松。
上述情况在kotlin中能很好的解决:
interface Source {
fun nextT(): T
}
fun demo(strs: Source) {
val objects: Source = strs // 这个没问题,因为 T 是一个 out-参数
// ……
}
类型参数声明处提供,所以我们称之为声明处型变
class Producer {
fun produce(): T {
...
}
}
val producer: Producer = Producer() // 这里不写 out 也不会报错
//val producer: Producer = Producer
() // out 可以但没必要,但是如果声明处没有加out关键字,那么这里就得使用out
类型投影(使用处型变)
与Java类似,只是将“? extends T”换成了“out T”,代表协变;“? super T”换成了“in T”,代表逆变。
以Array为例:
class Array(val size: Int) {
fun get(index: Int): T { ///* …… */ }
fun set(index: Int, value: T) { ///* …… */ }
}
该类在 T 上既不是协变的也不是逆变的。这造成了⼀些不灵活性。
考虑下列函数:
fun copy(from: Array, to: Array) {
assert(from.size == to.size)
for (i in from.indices)
to[i] = from[i]
}
错误代码:
val ints: Array = arrayOf(1, 2, 3)
val any: Array = Array(3) { "" }
copy(ints, any) // 错误
Array 在 T 上是不型变的,因此 Array 和 Array 之间没有关系。copy方法看上去没问题,但是调用起来编译器通不过
只需要修改一下copy方法,加一个out关键字:from: Array。这里发生的事情称为类型投影:我们说from不仅仅是一个数组,而是一个受限制的(投影的)数组:我们只可以调用返回类型为类型参数 T 的方法,如上,这意味着我们只能调用 get()。这就是我们的使用处型变的用法,并且是对应于 Java 的 Array、 但使用更简单些的方式。
补充1:java中的单个‘?’和kotlin中的星投影(‘*’)
在java中,单个 ? 号也能作为泛型通配符使用,相当于 ? extends Object。
在kotlin中也有等价写法,就是星投影,作用是当T未知时,可以安全的读或者写 。
对于 Foo ,其中 T 是一个具有上界 TUpper 的不型变类型参数,Foo<*> 对于读取值时等价于 Foo 而对于写值时等价于 Foo。
注意:如果你的类型定义里已经有了out或者in,那这个限制在变量声明时也依然在,不会被*号覆盖。
指定多个边界(where使用)
java中设置继承多个边界使用‘&’,示例:
class Monster{
}
kotlin中使用where,示例:
//T既要满足是字符又要是实现了Comparable接口的对象
fun copyWhenGreater(list: List, threshold: T): List
where T : CharSequence,
T : Comparable {
return list.filter { it > threshold }.map { it.toString() }
}
reified关键字
Java 中的泛型存在类型擦除的情况,任何在运行时需要知道泛型确切类型信息的操作都没法用了。java的解决方法是额外传递一个Class类型的参数,然后通过Class#isInstance方法来检查:
void check(Object item, Class type) {
if (type.isInstance(item)) {
System.out.println(item);
}
}
kotlin中的解决方法是使用关键字reified配合inline来解决:
inline fun printIfTypeMatch(item: Any) {
if (item is T) { // 里就不会在提示错误了
println(item)
}
}
再来个例子方便理解
inline fun T?.notNull(notNullAction: (T) -> Unit, nullAction: () -> Unit) {
if (this != null) {
//invoke即调用,Method类中的native方法
notNullAction.invoke(this)
} else {
nullAction.invoke()
}
}
嵌套类与内部类
嵌套
类可以嵌套在其他类中,此外接口和类的所有组合都是可能的,比如接口中嵌套类,类中嵌套接口。
class Outer{
private val bar: Int = 1
class Nested {
fun foo() = 2
}
}
val demo = Outer.Nested().foo() // == 2
内部类(inner关键字)
标记为 inner 的嵌套类能够访问其外部类的成员 。内部类会带有一个对外部类的对象的引用。
class Outer{
private val bar: Int = 1
inner class Nested {
fun foo() = bar
}
}
val demo = Outer.Nested().foo() // == 1
匿名内部类
很常见,来个例子
window.addMouseListener(object : MouseAdapter() {
override fun mouseClicked(e: MouseEvent) { /*……*/ }
override fun mouseEntered(e: MouseEvent) { /*……*/ }
})
枚举类
经常配合when使用,每个枚举常量都可以在声明中获取name和位置ordinal。
enum class RGB { RED, GREEN, BLUE }
inline fun > printAllValues() {
print(enumValues().joinToString { it.name })
}
fun main() {
printAllValues()
}
对象
如果我们只需要“一个对象而已”,并不需要特殊超类型,可以这么写
val adHoc = object {
var x: Int = 0
var y: Int = 0
}
匿名类前文提过了。
伴生对象,用companion关键字标记。用的地方很多,比如使用类名作为限定符来调用,定义一些常量。 在 JVM 平台,如果使用 @JvmStatic 注解,你可以将伴生对象的成员生成为真正的静态方法和字段。
类型别名
作用是用来简化函数声明的。
比如创建一个类型别名
typealias Restaurant = Organization<(Currency, Coupon?) -> Sustenance>
然后使用它
interface RestaurantPatron {
fun makeReservation(restaurant: Restaurant)
fun visit(restaurant: Restaurant)
fun complainAbout(restaurant: Restaurant)
}
如果我们需要去查看别名背后隐藏细节是什么,只需要Common+Click单击就可以了。
注意事项
类型别名只能定义在代码顶层位置
把2个对象设置成同一种类型别名,那么调用方法的时候编译器将发现不了你传参顺序出现的问题
typealias UserId = UniqueIdentifier
typealias ProductId = UniqueIdentifier
interface Store {
fun purchase(user: UserId, product: ProductId): Receipt
}
//productId和userId哪怕传参顺序错了,但是因为被类型解释成同一种东西,所以不会报错
val receipt = store.purchase(productId, userId)
补充1:import as
你是否遇到过需要导入两个同名的类的情况,使用的时候非常难受,总有一个前面带着一串包名对不?但是现在可以解决了,好消息!import a’s’它允许你给一个类型、函数或者属性一个新的命名,然后你可以把它导入到一个文件中。
常用于
委托
委托类
通过关键字 by 可以很方便的实现语法级别的委托模式。 示例:
interface DB{
fun save()
}
class SqlDB() : DB {
override fun save() { println("save to sql") }
}
class GreenDaoDB() : DB {
override fun save() { println("save to GreenDao") }
}
// 参数 通过 by 将接口实现委托给 db
// ↓ ↓
class UniversalDB(db: DB) : DB by db
fun main() {
UniversalDB(SqlDB()).save()
UniversalDB(GreenDaoDB()).save()
}
这种委托模式在我们实际编程中十分常见,UniversalDB 相当于一个壳,它提供数据库存储功能,但并不关心它怎么实现。具体是用 Sql 还是 GreenDao,传不同的委托对象进去就行。
然后有人就会说,我用java也可以实现啊,这个by有啥用啊
class UniversalDB implements DB {
DB db;
public UniversalDB(DB db) { this.db = db; }
// 手动重写接口,将 save 委托给 db.save()
@Override// ↓
public void save() { db.save(); }
}
no no no~上述接口只有一个方法,当我们想委托的接口方法很多的时候,这个by能极大的减少我们的代码量。 比如我们给MutableList添加一个方法,kotln只需要几行,而java继承List接口后会增加很多代码。
class LogList(val log: () -> Unit, val list: MutableList) : MutableList by list{
fun getAndLog(index: Int): String {
log()
return get(index)
}
}
委托属性
委托属性,委托出去的是属性的 getter,setter。
val text: String = by lazy{}
// 它的原理其实跟下面是一样的
// 语法层面上是等价的哈,实际我们不能这么写
val text: String
get() { lazy{} }
自定义委托属性
thisRef字段使用
class Owner {
//委托给StringDelegate
var text: String by StringDelegate()
}
class StringDelegate(private var s: String = "Hello") {
//提示:这里的Owner可以改成Any,这样任意类里面的 String 属性,我们都可以用这种方式去委托了
operator fun getValue(thisRef: Owner, property: KProperty<*>): String {
return s
}
operator fun setValue(thisRef: Owner, property: KProperty<*>, value: String?) {
if (value is String) {
s = value
}
}
}
补充1:Kotlin 标准库为几种有用的委托提供了工厂方法
延迟属性Lazy
可观察属性Observable
import kotlin.properties.Delegates
class User {
var name: String by Delegates.observable("") {
prop, old, new ->
println("$old -> $new")
}
}
fun main() {
val user = User()
user.name = "first"
user.name = "second"
}
打印结果如下:
-> first
first -> second
补充2:从 Kotlin 1.4 开始,一个属性可以把它的 getter 与 setter 委托给另一个属性
这种委托对于顶层和类的属性(成员和扩展)都可用。
这是很有用的,例如,当想要以一种向后兼容的方式重命名一个属性的时候:引入一个新的属性、 使用 @Deprecated 注解来注解旧的属性、并委托其实现。
class MyClass {
var newName: Int = 0
//旧属性直接委托给新属性,并添加过时标签,注意这里的“::”,一般就是这么用的
@Deprecated("Use 'newName' instead", ReplaceWith("newName"))
var oldName: Int by this::newName
}
fun main() {
val myClass = MyClass()
myClass.oldName = 42
//这里就实现了向后兼容
println(myClass.newName)
}
补充3:将属性储存在映射中
class User(val map: Map) {
val name: String by map
val age: Int by map
}
val user = User(mapOf(
"name" to "John Doe",
"age" to 25
))
println(user.name) // Prints "John Doe"
println(user.age) // Prints 25
函数
函数参数可以有默认值,当省略相应的参数时使用默认值。与其他语言相比,这可以减少重载数量。来个例子:
fun read(
b: Array,
off: Int = 0,
len: Int = b.size,
) { /*……*/ }
如果默认参数之后的最后一个参数是lambda表达式,那么它既可以作为具体参数在括号内传入,也可以在括号外传入
fun foo (
bar: Int=0,
baz: Int=0,
qux:->Unit,
){/*.....*/ }
foo(qux = { println("hello") }) // 使用两个默认值 bar = 0 与 baz = 1
foo { println("hello") } // 使用两个默认值 bar = 0 与 baz = 1
fun asList(vararg ts: T): List {
val result = ArrayList()
for (t in ts) // ts is an Array
result.add(t)
return result
}
补充1:伸展操作符 *
val a = arrayOf(1, 2, 3)
//list的长度为6
val list = asList(-1, 0, *a, 4)
补充2:中缀表示法 使用infix 关键字。必须满足一定条件。
必须是成员函数或者扩展函数
必须只有一个参数
参数不能接受可变数量的参数而且不能有默认值
//以Int的扩展函数shl为例
infix fun Int.shl(x: Int): Int { …… }
//中缀表示法这样写
1 shl 2
内联函数
inline fun lock(lock: Lock, body: () -> T): T { …… }
内联函数内部可以调其他函数,但是他的变量不能作为参数传入外部函数中,会报错,需要修改成noinline才行。
内联可能导致生成的代码增加;不过如果我们使用得当(即避免内联过大函数),性能上会有所提升。
禁用内联使用noinline关键字。配合inline使用的,也就是说在内联函数内,允许参数判空啊,使用参数啊等等。
高阶函数
高阶函数是将函数用作参数或返回值的函数。
示例,自定义String类的扩展函数
/**
* if [String.isNullOrEmpty], invoke f()
* otherwise invoke t()
*/
fun String?.notNull(f: () -> T, t: () -> T): T {
return if (isNullOrEmpty()) f() else t()
}
使用也简单
fun checkStringEnable(st:String):Boolean{
return st.notNull({true},{false})
}
集合
Kotlin 标准库提供了基本集合类型的实现: set、list 以及 map。 注意:
一个 只读 接口,提供访问集合元素的操作。
一个 可变 接口,通过写操作扩展相应的只读接口:添加、删除和更新其元素。
Kotlin 集合接口的图表
结论1:只读集合是型变的,可变集合是不型变的。
//List接口提供访问集合元素操作,所以printList能正常编译
fun printList(list: List) {
//注意:这里函数形参类型是List,函数内部是不知道外部传入是List还是List,全部当做List处理
list.forEach {
println(it)
}
}
fun main() {
val stringList: List = listOf("a", "b", "c", "d")
val intList: List = listOf(1, 2, 3, 4)
printList(stringList)//向函数传递一个List函数实参,也就是这里List是可以替换List
printList(intList)//向函数传递一个List函数实参,也就是这里List是可以替换List
}
看一个可变类型的fun printList(list: MutableList) {
//MutableList接口提供了add等方法,List则没有
list.add(3.0f)
list.forEach {
println(it)
}
}
fun main() {
val stringList: MutableList = mutableListOf("a", "b", "c", "d")
val intList: MutableList = mutableListOf
//编译报错:Type mismatch
printList(stringList)
//编译报错:Type mismatch
printList(intList)
}
Collection
集合层次结构的根。此接口表示一个只读集合的共同行为:检索大小、检测是否为成员等等。Collection继承自 Iterable接口,它定义了迭代元素的操作。可以使用Collection作为适用于不同集合类型的函数的参数。
Map
Map 不是 Collection 接口的继承者;但是它也是 Kotlin 的一种集合类型。 无论顺序如何,包含相同键值对的map是相等的。
常用示例
//List kotlin中默认实现是ArrayList
val numbers = listOf("one", "two", "three", "four")
println("Number of elements: ${numbers.size}")
println("Third element: ${numbers.get(2)}")
println("Fourth element: ${numbers[3]}")
println("Index of element \"two\" ${numbers.indexOf("two")}")
//MutableList
val numbers = mutableListOf(1, 2, 3, 4)
numbers.add(5)
numbers.removeAt(1)
numbers[0] = 0
numbers.shuffle()
println(numbers)
//set 默认实现是LinkedHashSet,另一种实现HashSet则不声明元素顺序
val numbers = setOf(1, 2Map, 3, 4)
println(numbers.first())
//map 默认实现是LinkedHashMap,保留插入顺序,HashMap则不声明元素顺序
val numbersMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key4" to 1)
//to 符号创建了一个短时存活的 Pair 对象,因此建议仅在性能不重要时才使用它。 为避免过多的内存使用,请使用其他方法。
val numbersMap = mutableMapOf().apply { this["one"] = "1"; this["two"] = "2" }
空集合
还有用于创建没有任何元素的集合的函数:emptyList()、emptySet() 与 emptyMap()
var empty=emptyList()
创建快照
创建了一个具有相同元素的新集合。
val sourceList = mutableListOf(1, 2, 3)
val copyList = sourceList.toMutableList()
val readOnlyCopyList = sourceList.toList()
sourceList.add(4)
println("Copy size: ${copyList.size}")
集合的各种操作创建集合
过滤示例
val numbers = listOf("one", "two", "three", "four")
val longerThan3 = numbers.filter { it.length > 3 }
映射示例
val numbers = setOf(1, 2, 3)
//[3,6,9]
println(numbers.map { it * 3 })
//[0,2,6]
println(numbers.mapIndexed { idx, value -> value * idx })
关联示例
val numbers = listOf("one", "two", "three", "four")
//{one=3, two=3, three=5, four=4}
println(numbers.associateWith { it.length })
迭代器
我们知道List和Set是可以获取迭代器的。 示例
val numbers = listOf("one", "two", "three", "four")
val numbersIterator = numbers.iterator()
while (numbersIterator.hasNext()) {
println(numbersIterator.next())
ListIterator 它支持列表双向迭代:正向与反向。
MutableListIterator可以在迭代列表时插入和替换元素。
区间和数列
使用… ;常见配合使用的操作符有in !in ;相关的函数**downTo、step、util
常用示例
//if中使用
if(i in 1..4){//等价于1 <= i && i <= 4
print(i)
}
//for循环中使用
for(i in 1..4) print(i)
//downTo使用
for (i in 4 downTo 1) print(i)
//设置步长
for(i in 1..8 step 2)print(i)
//util使用排除最后一个数据
for(i in 1 util 10)print(i)
//使用集合函数
var range=1..10
println(range.filter({it %2==0}))
补充1:数列实现 Iterable,其中 N 分别是 Int、Long 或 Char,因此可以在各种集合函数(如 map、filter 与其他)中使用它们。
序列
是一种容器类型,提供了与Iterable相同的函数,但是与Iterable的处理方式不同。有延迟性。
Iterable处理包含多个步骤时,会优先处理每个步骤完成并返回结果,有中间集合 。序列则在可能的情况下会延迟执行,挡请求整个处理链的结果时才进行实际计算。
示例
//创建一个序列
val numbersSequence = sequenceOf("four", "three", "two", "one")
//由一个Iterable对象(比如List或者Set)
var numbers=listof("one","two","three","four")
var numbersSequence = numbers.asSequence()
//由函数构建一个无限序列,并取前5个数据
var oddNumbers=generateSequence(1){it +2}
println(oddNumbers.take(5).toList())
//创建一个有限序列,通常用到null
val oddNumbersLessThan10 = generateSequence(1) { if (it + 2 < 10) it + 2 else null }
println(oddNumbersLessThan10.count())
//逐个或按任意大小的组块生成序列元素,sequence函数使用
val oddNumbers = sequence {
yield(1)
yieldAll(listOf(3, 5))
yieldAll(generateSequence(7) { it + 2 })
}
//打印结果:[1, 3, 5, 7, 9]
println(oddNumbers.take(5).toList())
序列处理示例对比
一个是Iterable,一个是Sequence,对于同一件事步骤是不同的。
假定有一个单词列表。下面的代码过滤长于三个字符的单词,并打印前四个单词的长度。
//使用List,需要23个步骤
val words = "The quick brown fox jumps over the lazy dog".split(" ")
val lengthsList = words.filter { println("filter: $it"); it.length > 3 }
.map { println("length: ${it.length}"); it.length }
.take(4)
println("Lengths of first 4 words longer than 3 chars:")
println(lengthsList)
使用序列,需要18个步骤
val words = "The quick brown fox jumps over the lazy dog".split(" ")
// 将列表转换为序列
val wordsSequence = words.asSequence()
val lengthsSequence = wordsSequence.filter { println("filter: $it"); it.length > 3 }
.map { println("length: ${it.length}"); it.length }
.take(4)
println("Lengths of first 4 words longer than 3 chars")
// 末端操作:以列表形式获取结果。
println(lengthsSequence.toList())
集合操作
转换
//基本的映射函数是map,如果需要元素索引可以使用mapIndexed
val numbers = setOf(1, 2, 3)
println(numbers.map { it * 3 })
println(numbers.mapIndexed { idx, value -> value * idx })
//不想产生null值使用mapNotNull和mapIndexedNotNull
println(numbers.mapNotNull{if(it==2} null else it*3)
println(number.mapIndexedNotNull{idx,value->if(idx==0) null else value*idx})
//关于映射转换 mapKeys和mapValues方法
val numbersMap=mapOf("key1" to 1,"key2" to 2,"key3" to 3,"key11" to 11)
println(numbersMap.mapKeys { it.key.toUpperCase() })
println(numbersMap.mapValues { it.value + it.key.length })
合拢 在一个集合(或数组)上以另一个集合(或数组)作为参数调用时,zip() 返回 Pair 对象的列表(List)。
val colors = listOf("red", "brown", "grey")
val twoAnimals = listOf("fox", "bear")
println(colors.zip(twoAnimals))
//打印结果:[(red, fox), (brown, bear)]
unzip反向转换,从键值对中构建两个列表
val numberPairs = listOf("one" to 1, "two" to 2, "three" to 3, "four" to 4)
println(numberPairs.unzip())
//打印结果:([one, two, three, four], [1, 2, 3, 4])
// flatten返回嵌套集合中所有元素的一个List
val numberSets = listOf(setOf(1, 2, 3), setOf(4, 5, 6), setOf(1, 2))
println(numberSets.flatten())
//flatMap使用,常用于集合合并
val list = listOf(
1..20,
2..15,
100..166)
val flatList = list.flatMap{
it.map{
"No.$it"
}
}
//joinToString使用
val numbers = listOf("one", "two", "three", "four")
println(numbers)
println(numbers.joinToString()) //one, two, three, four
//joinTo则是加到后面
val listString = StringBuffer("The list of numbers: ")
numbers.joinTo(listString)
println(listString)
//加头尾和分隔符
val numbers = listOf("one", "two", "three", "four")
//打印结果:start: one | two | three | four: end
println(numbers.joinToString(separator = " | ", prefix = "start: ", postfix = ": end"))
//指定长度限制
val numbers = (1..100).toList()
println(numbers.joinToString(limit = 10, truncated = "<...>"))
过滤
集合的过滤,基本函数是filter。
//过滤时想使用索引使用filterIndexed
val numbers = listOf("one", "two", "three", "four")
val filteredIdx = numbers.filterIndexed { index, s -> (index != 0) && (s.length < 5) }
//使用filterNot
val filteredNot = numbers.filterNot { it.length <= 3 }
//返回给定类型的集合元素,不符合的会无视
val numbers = listOf(null, 1, "two", 3.0, "four")
println("All String elements in upper case:")
numbers.filterIsInstance().forEach {
println(it.toUpperCase())
}
//返回非null
val numbers = listOf(null, "one", "two", null)
numbers.filterNotNull().forEach {
println(it.length) // 对可空的 String 来说长度不可用
}
另一个过滤函数是partition,意思是划分
val numbers = listOf("one", "two", "three", "four")
//这里划分成2个了
val (match, rest) = numbers.partition { it.length > 3 }
println(match)
println(rest)
检验谓词 any表示至少有一个元素匹配,none表示没有元素匹配,all表示所有元素匹配给定词
val numbers = listOf("one", "two", "three", "four")
val empty = emptyList()
println(numbers.any { it.endsWith("e") }) //true
println(numbers.none { it.endsWith("a") }) //true
println(numbers.all { it.endsWith("e") }) //false
println(emptyList().all { it > 5 }) //true
//空集合调用any和none用于判断是否有数据
println(empty.any())//false
println(empty.none())//ture
加减操作符(+ -)
集合和集合是可以直接通过加减操作符来操作的。
val numbers = listOf("one", "two", "three", "four")
val plusList = numbers + "five"
val minusList = numbers - listOf("three", "four")
println(plusList)
println(minusList)
分组
基本函数 groupBy() 使用一个 lambda 函数并返回一个 Map。
//按照首字母分组
var numbers=listOf("one", "two", "three", "four", "five")
println(numbers.groupBy{ it.first() })
//打印结果 {o=[ONE], t=[TWO, THREE], f=[FOUR, FIVE]}
println(numbers.groupBy(keySelector = { it.first() }, valueTransform = { it.toUpperCase() }))
取集合的一部分
常用的slice、take、takeLast、drop、dropLast
//slice 返回具有给定索引的集合元素列表
val numbers = listOf("one", "two", "three", "four", "five", "six")
println(numbers.slice(1..3)) //[two, three, four]
println(numbers.slice(0..4 step 2)) //[one,three,five]
println(numbers.slice(setOf(3, 5, 0))) //[four,six,one]
//take 从头开始获取指定数量的元素 takeLast从尾获取指定数量元素
//drop 从头去除指定数量的元素 dropLast从尾去除指定数量的元素
val numbers = listOf("one", "two", "three", "four", "five", "six")
println(numbers.take(3))
println(numbers.takeLast(3))
println(numbers.drop(1))
println(numbers.dropLast(5))
//chunked 将集合分解为给定大小的“块”
val numbers = (0..13).toList()
println(numbers.chunked(3){ it.sum() }) //14个数,分解成元素个数为3的块,并累加 [3, 12, 21, 30, 25]
//windowned 返回可能区间,与chunked有点不同
val numbers = listOf("one", "two", "three", "four", "five")
println(numbers.windowed(3)) //[[one, two, three], [two, three, four], [three, four, five]]
取单个元素
集合中通用方法elementAt,但是对于List建议使用get和[]
//elementAt方法检索特定位置的元素 对于List而言可以使用索引访问操作符
val numbers = linkedSetOf("one", "two", "three", "four", "five")
println(numbers.elementAt(3))
var list = listOf(1,2,3,4)
println(list.get(0))
//关于sortedSetOf方法 Set里数据源必须是有继承Comparable接口的,比如String
val numbersSortedSet = sortedSetOf("7", "2", "3", "4")
println(numbersSortedSet.elementAt(0)) //2 意思元素以升序存储
val numbersSortedSet = sortedSetOf("one", "two", "three", "four")
println(numbersSortedSet.elementAt(0)) //four
//first和last函数前面讲过了,略
//first和last 按条件取
val numbers = listOf("one", "two", "three", "four", "five", "six")
println(numbers.first { it.length > 3 })
println(numbers.last { it.startsWith("f") })
//random函数 随机取
val numbers = listOf(1, 2, 3, 4)
println(numbers.random())
//contains和containsAll检查是否存在
val numbers = listOf("one", "two", "three", "four", "five", "six")
println(numbers.contains("four")) //true
println(numbers.containsAll(listOf("four", "two"))) //true
集合排序
首先要排序,数据必须要实现Comparable接口,重写compareTo方法,不然谁知道怎么比对不。
大多数内置类型是可比较的:
数值类型使用传统的数值顺序:1 大于 0; -3.4f 大于 -5f,以此类推。
Char 和 String 使用字典顺序: b 大于 a; world 大于 hello。
//关于compareTo 正值表示我比较大 0表示相等
class Version(val major: Int, val minor: Int): Comparable {
override fun compareTo(other: Version): Int {
if (this.major != other.major) {
return this.major - other.major
} else if (this.minor != other.minor) {
return this.minor - other.minor
} else return 0
}
}
fun main() {
println(Version(1, 2) > Version(1, 3))
println(Version(2, 0) > Version(1, 5))
}
自定义排序
对不可比较对象排序,可以使用函数 sortedBy和sortedByDescending。
val numbers = listOf("one", "two", "three", "four")
val sortedNumbers = numbers.sortedBy { it.length }
println("Sorted by length ascending: $sortedNumbers")
倒序
//reversed 使用
val numbers = listOf("one", "two", "three", "four")
println(numbers.reversed())
随机顺序
//shuffled 使用
val numbers = listOf("one", "two", "three", "four")
println(numbers.shuffled())
聚合操作
Kotlin 集合包含用于常用的 聚合操作 (基于集合内容返回单个值的操作)的函数 。常见的比如max、min、average、sum、count。
val numbers = listOf(6, 42, 10, 4)
println("Count: ${numbers.count()}")
println("Max: ${numbers.max()}")
println("Min: ${numbers.min()}")
println("Average: ${numbers.average()}")
println("Sum: ${numbers.sum()}")
如果你想通过条件筛选可以使用xxxBy函数,示例如下
val numbers = listOf(5, 42, 10, 4)
val min3Remainder = numbers.minBy { it % 3 }
println(min3Remainder)
reduce和fold函数,fold可以设置初始值,而reduce则是把第一个和第二个元素作为第一步的操作参数
val numbers = listOf(5, 2, 10, 4)
val sum = numbers.reduce { sum, element -> sum + element }
println(sum) //21
val sumDoubled = numbers.fold(0) { sum, element -> sum + element * 2 }
println(sumDoubled) //42
集合写操作
注意是可变集合 ,比如mutableListOf的对象就能使用add,而listOf生成的就不能add。
val numbers = mutableListOf(1, 2, 3, 4, 3)
//添加
numbers.add(5)
//删除
numbers.remove(3)
//更新在后面讲
List相关操作
按索引取出元素
var numbers=listOf(1,2,3,4)
//通过下标和索引
println(numbers.get(0))
println(numbers[0])
//获取不到就返回默认值
println(numbers.getOrElse(5){99})
println(numbers.getOrNull(5))
取出一部分
val numbers = (0..13).toList()
println(numbers.subList(3, 6))
写操作 add 和addAll
val numbers = mutableListOf("one", "five", "six")
numbers.add(1,"two") //在1位置插入,位置后面的都往后移
numbers.add(2,"three")
println(numbers) //[one, two, three, four, five, six]
更新操作 使用get或者其操作符形式[]
val numbers = mutableListOf("one", "five", "three")
numbers[1]="two"
删除操作 使用removeAt,删除之后的元素索引都会减少1
val numbers = mutableListOf(1, 2, 3, 4, 3)
numbers.removeAt(1)
排序操作 使用sort、shuffle、reverse之类的。
val numbers = mutableListOf("one", "two", "three", "four")
numbers.sort() //[four, one, three, two] 为啥呢,因为字符有asc码
Set相关操作
常用的比如并集和交集还有差集合 (union、intersect、subtract)
val numbers = setOf("one", "two", "three")
println(numbers union setOf("four", "five")) //有顺序的啊,这个是[one, two, three, four, five]
println(numbers intersect setOf("two", "one")) //一样有顺序,这个是[one, two]
println(numbers subtract setOf("three", "four")) //[one, two]
Map相关操作
val numbersMap = mapOf("one" to 1, "two" to 2, "three" to 3)
println(numbersMap.keys) //[one, two, three]
println(numbersMap.values) //[1,2,3]
getOrDefault和getOrElse以及get(key: K)
val numbersMap = mapOf("one" to 1, "two" to 2, "three" to 3)
println(numbersMap.get("one")) //1
println(numbersMap.getOrDefault("four", 10)) //10
过滤
plus 与 minus
map写操作 put和putAll使用
//写一条
val numbersMap = mutableMapOf("one" to 1, "two" to 2)
numbersMap.put("three", 3)
println(numbersMap)
//写多条
numbersMap.putAll(setOf("four" to 4, "five" to 5))
map删除 remove的使用(可以remove())
val numbersMap = mutableMapOf("one" to 1, "two" to 2, "three" to 3)
numbersMap.remove("one")
println(numbersMap)
//通过键或值从可变 Map 中删除条目
val numbersMap = mutableMapOf("one" to 1, "two" to 2, "three" to 3, "threeAgain" to 3)
numbersMap.keys.remove("one")
println(numbersMap)
numbersMap.values.remove(3)
println(numbersMap)
//通过-=
val numbersMap = mutableMapOf("one" to 1, "two" to 2, "three" to 3)
numbersMap -= "two"
println(numbersMap)
后话
kotlin语言中文站 码上开学 朱涛的自习室 kotlin项目GitHub地址 Android KTX官方文档 Kotlin DSL script代替Groovy DSL script
你可能感兴趣的:(Kotlin,kotlin)
Kotlin D3
GH小杨
kotlin 开发语言 android
KotlinD3面向对象一、课程目标本次课程旨在让学员全面且深入地了解面向对象编程的核心概念,透彻掌握类与对象之间的紧密关系,熟练运用Kotlin语言中各类常用类进行程序开发。通过理论知识的系统讲解、丰富多样的实际案例分析以及详细的代码解读,帮助学员将面向对象编程思想融入到Kotlin编程实践中,提升解决实际问题的能力,为后续开发复杂的Kotlin应用程序奠定坚实基础。二、面向对象的概念2.1什么
Android面试题之Kotlin Flow的collect和collectLatest有什么区别?
AntDreamer
kotlin android kotlin 开发语言 面试
本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点在Kotlin协程库中,collect和collectLatest是用于收集流数据的两种不同操作。理解它们的区别,将有助于确保在处理流数据时的效率和行为符合预期。1.基本定义collect:是一个挂起函数,用于启动流的收集过程。收集过程会逐个处理每个发射的值,并从上游流向下游执行相
Kotlin:Flow 全面详细指南,附带源码解析。
2401_84520377
程序员 kotlin 开发语言 android
Flow需要在协程里面使用,因为collect是挂起函数,另外基于冷流的特性,不调用collect构建器的代码压根不会走。所以只能是协程。那我取消协程不就行了吗?。好像之前有看到过有开发者提出过,是否要给flow单独加一个取消的函数,被Jetbrains无情的拒绝了,哈哈哈哈很搞笑。下面引用Kotlin官方的一段话。Flowadherestothegeneralcooperativecancell
android flow中collect和collectLatest的区别
stevenzqzq
android
嗯,我现在要分析用户的问题。用户问的是articleAdapter.loadStateFlow.collect{...}这段代码的含义,以及KotlinFlow中collect和collectLatest的区别。首先,我需要确认自己是否完全理解这两个问题,然后再逐步回答。首先,关于loadStateFlow.collect这段代码,用户可能是在使用Paging3库时遇到了相关代码,想了解它的作用。
第一行代码(第三版)kotlin-android-extensions报错处理
代码随想笔记
android kotlin 开发语言
classMainActivity:AppCompatActivity(){overridefunonCreate(savedInstanceState:Bundle?){super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)valmBt_1:Button=findViewById(R.id.button1)
```markdown
伍辰惟
#超越边界:构建优雅的六边形架构(HexagonalArchitecture)hex-arch-kotlin-spring-bootReferenceJVMmultimoduleprojectforareactivemicroserviceandlambdausingahexagonalarchitecture,DDD,Kotlin,SpringBoot,Quarkus,Lambda,Gradle
探索未来架构的钥匙:Hex-Arch-Kotlin-Spring-Boot
孟振优Harvester
探索未来架构的钥匙:Hex-Arch-Kotlin-Spring-Boothex-arch-kotlin-spring-bootReferenceJVMmultimoduleprojectforareactivemicroserviceandlambdausingahexagonalarchitecture,DDD,Kotlin,SpringBoot,Quarkus,Lambda,Gradle.项
Android Coil总结
xiangxiongfly915
Android android Coil
文章目录AndroidCoil总结概述添加依赖用法基本用法占位图变形自定义ImageLoader取消加载协程支持缓存清除缓存监听简单封装AndroidCoil总结概述Coil是一个用于Android的Kotlin图像加载库,旨在简化图像加载和显示的过程。它基于Kotlin协程,提供了简洁的API和高效的性能。添加依赖implementation"io.coil-kt:coil:2.4.0"用法基本
Android中的AsyncTask。
Java资深爱好者
android
AsyncTask是Android框架中的一个工具类,用于在后台线程中执行耗时操作,并在操作完成后更新UI界面。它简化了多线程编程中的很多复杂性,尤其是在需要与UI线程交互的场景中。然而,需要注意的是,从Android11(API级别30)开始,AsyncTask已被标记为过时(deprecated),Google推荐使用Kotlin的协程(Coroutines)或者Java的并发工具类(如Exe
Kotlin 5种单例模式
tangweiguo03051987
Kotlin语法 kotlin 单例模式 javascript
在Kotlin中实现单例模式有多种方法,以下是几种常见的方法:饿汉式饿汉式是最简单的一种实现方式,在类加载时就完成了实例的初始化。//饿汉式objectSingleton1{funprintMessage(){println("===饿汉式")}}懒汉式懒汉式是延迟加载的方式,只有在第一次使用时才创建实例。classSingleton2privateconstructor(){companiono
Kotlin 实现图片裁剪
zimoyin
kotlin 开发语言 android
/***图片裁剪*@paramoriginalImage原始图像*@paramstartX裁剪区域的起始x坐标*@paramstartY裁剪区域的起始y坐标*@paramendX裁剪区域的结束x坐标*@paramendY裁剪区域的结束y坐标**/funcropImage(originalImage:BufferedImage,startX:Int,startY:Int,endX:Int,endY:
Kotlin 图片调整亮度
zimoyin
kotlin 开发语言 android
/***图片亮度调整*@paramimage图片*@paramparam在当前亮度基础上添加或者减去亮度*@throwsIOException*/funsetImageLight(image:BufferedImage,param:Int):BufferedImage{for(iin0untilimage.width){for(jin0untilimage.height){varrgb=image
Android中的AtomicLong:原理、使用与实战指南
jiet_h
Android 夯实基础 android
本文结合生产环境实战案例,带你彻底搞懂AtomicLong在Android多线程开发中的应用。全文包含大量Kotlin代码示例,建议收藏备用。一、为什么需要AtomicLong?在Android开发中,当多个线程同时操作同一个Long型变量时,你可能会遇到这样的诡异场景:varcounter=0Lfunincrement(){//这个操作在并发场景下会出错!counter++}这个简单的自增操作,
Kotlin 绘制图片文字并自动换行
zimoyin
kotlin 开发语言 android
/***绘制文本,并允许指定文本长度和行高,并自动换行*@paramtext要绘制的文本*@paramx0绘制文本的起始X坐标*@paramy0绘制文本的起始Y坐标*@parammaxWidth绘制文本的最大宽度*@paramlineHeight绘制文本的行高*@paramfont要绘制文本的字体*@paramstyle要绘制文本的字体样式*/funGraphics2D.drawString(te
Kotlin Compose Multiplatform下导航解决方案
AsterCass
kotlin 开发语言 android multiplatform compose 多平台 KMP
原文链接欢迎大家对于本站的访问-AsterCasc前言其实笔者在写这篇文章的时候,KMP已经有实验性的导航解决方案了,官方文档compose-navigation-routing中有介绍,而且使用起来也比较简单,可以参考我构建的的样例的这个分支但是目前版本由于是实验性的,不支持深层链接,而且返回手势只有安卓支持,甚至这些都不是最重要的,最大问题在于:笔者在使用这个导航的时候发现,官方导航组件在安卓
Android Kotlin中Room数据库的参数传递
t0_54coder
android 数据库 kotlin 个人开发
在Android开发中,Room数据库是一个非常强大且灵活的持久化存储解决方案。通过Room库,我们可以轻松地与SQLite数据库进行交互。然而,当我们尝试在查询中传递参数时,可能会遇到一些问题。本文将通过一个实际案例来讨论如何在Kotlin中使用Room数据库时正确传递参数。问题背景假设我们正在开发一个待办事项(To-DoList)应用,使用Kotlin编写。应用中,我们需要根据ID查找特定的待
Kotlin函数式编程与Lambda表达式
Ya-Jun
android kotlin java 开发语言
Kotlin函数式编程与Lambda表达式一、函数式编程基础1.1什么是函数式编程函数式编程是一种编程范式,它将计算过程视为数学函数的求值,强调使用不可变数据和纯函数。在Kotlin中,函数式编程的特性让我们能够写出更简洁、更易维护的代码。主要特点:函数是一等公民不可变性无副作用声明式而非命令式1.2为什么要使用函数式编程//传统命令式编程funcalculateTotal(numbers:Lis
Kotlin 扩展函数
tangweiguo03051987
Kotlin语法 kotlin android 开发语言
Kotlin扩展函数是一种强大的功能,它允许你为现有的类添加新的函数,而不需要修改原始类的代码。这意味着你可以为任何类添加方法,即使你没有访问该类的源代码。这对于创建通用工具函数、简化代码和提高可读性非常有用。如何定义扩展函数扩展函数的定义语法如下:funClassName.methodName(parameters){//函数体}其中,ClassName是你想要扩展的类的名称,methodNam
Java/Kotlin 开发者如何快速入门 C++
居然是阿宋
java kotlin c++
Java/Kotlin开发者如何快速入门C++如果你已经掌握了Java或Kotlin,并希望快速入门C++,你会发现两者有许多相似之处,但C++由于其底层特性(如指针、手动内存管理)而显得更加复杂。本篇博客将对比Java/Kotlin与C++之间的关键概念,帮助你更快理解C++。1.面向对象编程(OOP)C++Java/Kotlinclass(类)class(类)struct(结构体,默认publ
Kotlin协程(二)协程的生命周期及管理
&岁月不待人&
协程 kotlin 开发语言 android
在Kotlin中,协程的生命周期主要涉及创建(Starting)、执行(Active)、挂起(Suspended)、取消(Cancelled)和完成(Completed)这些状态。协程的生命周期受CoroutineScope和Job控制。1.协程的生命周期状态Kotlin协程的生命周期可以分为以下几个阶段:1.1新建(New)调用launch或async创建协程,但协程还未执行。示例valjob=
Kotlin/Java 实现 Html 转图片
zimoyin
java kotlin html
1.Html2Imagegui.avahtml2image2.0.1StringHtmlTemplateStr="....";//HTMLHtmlParserhtmlParser=newHtmlParserImpl();htmlParser.loadHtml(HtmlTemplateStr);ImageRendererimageRenderer=newImageRendererImpl(htmlP
Kotlin Flow常用用法
tangweiguo03051987
Kotlin语法 kotlin 前端 开发语言
KotlinFlow是Kotlin编程语言中的一个强大特性,用于处理异步数据流。它是Kotlin协程库的一部分,旨在以声明式和响应式的方式处理异步数据流。Flow的设计与协程无缝集成,使得异步编程更加简单和直观。suspendfunmain(){//创建Flow的几种方法valflow=flow{emit(1)emit(2)emit(3)emit(4)emit(5)}.collect{printl
Kotlin by关键字实现委托模式
tangweiguo03051987
kotlin 开发语言 android
在Kotlin中,by关键字主要用于委托(Delegation)。它允许将一个类的某些功能委托给另一个对象来处理。Kotlin提供了两种主要的委托方式:类委托和属性委托。委托的主要组成部分委托对象:负责实现被委托的属性或方法。被委托对象:包含被委托的属性或方法。委托的优点代码简洁:使用委托可以减少代码重复,使代码更加简洁。可扩展性:可以通过修改委托对象来改变被委托属性或方法的行为,而不需要修改原始
Kotlin协变与逆变区别
tangweiguo03051987
kotlin 开发语言 android
在Kotlin中,协变和逆变是泛型编程中的两个重要概念,它们允许我们在类型系统中更加灵活地处理类型关系。1.协变:协变允许我们使用比原始类型更具体的类型。在kotlin中,通过在类型参数上加out关键字来表示协变,生产者,例如,如果我们有一个泛型类List,其中T是一个协变类型参数,那么我们可以将List赋值给List,因为String是Any的子类型。2.逆变:逆变允许我们使用比原始类型更一般的
Kotlin常用同步方法
tangweiguo03051987
kotlin 开发语言 android
Kotlin常用同步实现方法:1.使用synchronized关键字2.使用ReentrantLock3.使用原子操作4.使用线程安全集合5.使用信号量Semaphore6.使用读写锁ReentrantReadWriteLock7.使用条件变量:Condition一般与ReentrantLock一起使用//使用synchronized关键字classNumber1{privatevarnumber
Kotlin观察者模式
tangweiguo03051987
kotlin 观察者模式 java
观察者模式是一种设计模式,它定义了对象之间的一对多依赖关系,当一个对象改变状态时,所有依赖于它的对象都会得到通知并自动更新。这种模式在许多编程场景中非常有用,例如事件处理、数据绑定和通知系统。观察者模式的主要组成部分主题(Subject):维护观察者的列表,并提供添加和删除观察者的方法。当主题的状态发生变化时,它会通知所有观察者。观察者(Observer):定义了一个更新接口,当主题状态发生变化时
Kotlin DSL(Domain-Specific Language,领域特定语言)
tangweiguo03051987
kotlin python 开发语言
DSL(Domain-SpecificLanguage,领域特定语言)是一种专门为某个特定领域设计的编程语言。与通用编程语言(如Java、Kotlin等)相比,DSL通常具有更简洁的语法和更少的语法元素,这使得它更适合用于描述特定领域的概念和操作。在Kotlin中,DSL可以以多种方式实现,例如使用函数式编程、使用扩展函数、使用中缀表达式等。以下是实现DSL的示例://使用函数式编程funbuil
Kotlin基础学习(十八)—— Kotlin 运算符重载与约定
浅唱整个春天
Kotlin基础 kotlin 学习 android
Kotlin允许使用对应名称的函数来重载一些标准的数学运算,但是不能定义自己的运算符Kotlin中的约定:为不同操作符规范操作符重载的约定。例如,如果在你的类中定义了一个名为plus的特殊方法,那么按照约定,就可以在该类的实例上使用+运算符。Kotlin允许我们为自己的类型提供预定义的一组操作符的实现。这些操作符具有固定的符号表示(如+或*)和固定的优先级。为实现这样的操作符,我们为相应的类型(即
【Android】聊聊Kotlin操作符重载
AI绘画师-海绵
Kotlin android kotlin
算数运算操作符重载在kotlin中我定义一个类dataclassPoint(valx:Int,valy:Int)然后实例化两个对象valp1=Point(3,5)valp2=Point(5,7)想表示p1的元素x加上p2的元素x,p1的元素y,加上p2的元素y.然后输出一个p3.valp3=Point(p1.x+p2.x,p2.y+p2.y)以上这种写法没有任何问题。不过我们可以利用Kotlin扩
Kotlin快速入门指南:运算符重载与移动端开发
UqndTf__
kotlin 开发语言 android
Kotlin是一门现代化的跨平台编程语言,广泛应用于移动端开发。本文将为您提供一份详细的Kotlin快速入门指南,重点介绍运算符重载的使用和移动端开发的相关内容。我们将通过实例代码来帮助您更好地理解这些概念。运算符重载在Kotlin中,运算符可以被重载,使得它们可以用于不同的数据类型或自定义的类。这种特性可以提高代码的可读性和简洁性。下面我们将通过几个例子来演示如何重载运算符。1.加法运算符重载我
PHP,安卓,UI,java,linux视频教程合集
cocos2d-x小菜
java UI linux PHP android
╔-----------------------------------╗┆
zookeeper admin 笔记
braveCS
zookeeper
Required Software
1) JDK>=1.6
2)推荐使用ensemble的ZooKeeper(至少3台),并run on separate machines
3)在Yahoo!,zk配置在特定的RHEL boxes里,2个cpu,2G内存,80G硬盘
数据和日志目录
1)数据目录里的文件是zk节点的持久化备份,包括快照和事务日
Spring配置多个连接池
easterfly
spring
项目中需要同时连接多个数据库的时候,如何才能在需要用到哪个数据库就连接哪个数据库呢?
Spring中有关于dataSource的配置:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
&nb
Mysql
171815164
mysql
例如,你想myuser使用mypassword从任何主机连接到mysql服务器的话。
GRANT ALL PRIVILEGES ON *.* TO 'myuser'@'%'IDENTIFIED BY 'mypassword' WI
TH GRANT OPTION;
如果你想允许用户myuser从ip为192.168.1.6的主机连接到mysql服务器,并使用mypassword作
CommonDAO(公共/基础DAO)
g21121
DAO
好久没有更新博客了,最近一段时间工作比较忙,所以请见谅,无论你是爱看呢还是爱看呢还是爱看呢,总之或许对你有些帮助。
DAO(Data Access Object)是一个数据访问(顾名思义就是与数据库打交道)接口,DAO一般在业
直言有讳
永夜-极光
感悟 随笔
1.转载地址:http://blog.csdn.net/jasonblog/article/details/10813313
精华:
“直言有讳”是阿里巴巴提倡的一种观念,而我在此之前并没有很深刻的认识。为什么呢?就好比是读书时候做阅读理解,我喜欢我自己的解读,并不喜欢老师给的意思。在这里也是。我自己坚持的原则是互相尊重,我觉得阿里巴巴很多价值观其实是基本的做人
安装CentOS 7 和Win 7后,Win7 引导丢失
随便小屋
centos
一般安装双系统的顺序是先装Win7,然后在安装CentOS,这样CentOS可以引导WIN 7启动。但安装CentOS7后,却找不到Win7 的引导,稍微修改一点东西即可。
一、首先具有root 的权限。
即进入Terminal后输入命令su,然后输入密码即可
二、利用vim编辑器打开/boot/grub2/grub.cfg文件进行修改
v
Oracle备份与恢复案例
aijuans
oracle
Oracle备份与恢复案例
一. 理解什么是数据库恢复当我们使用一个数据库时,总希望数据库的内容是可靠的、正确的,但由于计算机系统的故障(硬件故障、软件故障、网络故障、进程故障和系统故障)影响数据库系统的操作,影响数据库中数据的正确性,甚至破坏数据库,使数据库中全部或部分数据丢失。因此当发生上述故障后,希望能重构这个完整的数据库,该处理称为数据库恢复。恢复过程大致可以分为复原(Restore)与
JavaEE开源快速开发平台G4Studio v5.0发布
無為子
我非常高兴地宣布,今天我们最新的JavaEE开源快速开发平台G4Studio_V5.0版本已经正式发布。
访问G4Studio网站
http://www.g4it.org
2013-04-06 发布G4Studio_V5.0版本
功能新增
(1). 新增了调用Oracle存储过程返回游标,并将游标映射为Java List集合对象的标
Oracle显示根据高考分数模拟录取
百合不是茶
PL/SQL编程 oracle例子 模拟高考录取 学习交流
题目要求:
1,创建student表和result表
2,pl/sql对学生的成绩数据进行处理
3,处理的逻辑是根据每门专业课的最低分线和总分的最低分数线自动的将录取和落选
1,创建student表,和result表
学生信息表;
create table student(
student_id number primary key,--学生id
优秀的领导与差劲的领导
bijian1013
领导 管理 团队
责任
优秀的领导:优秀的领导总是对他所负责的项目担负起责任。如果项目不幸失败了,那么他知道该受责备的人是他自己,并且敢于承认错误。
差劲的领导:差劲的领导觉得这不是他的问题,因此他会想方设法证明是他的团队不行,或是将责任归咎于团队中他不喜欢的那几个成员身上。
努力工作
优秀的领导:团队领导应该是团队成员的榜样。至少,他应该与团队中的其他成员一样努力工作。这仅仅因为他
js函数在浏览器下的兼容
Bill_chen
jquery 浏览器 IE DWR ext
做前端开发的工程师,少不了要用FF进行测试,纯js函数在不同浏览器下,名称也可能不同。对于IE6和FF,取得下一结点的函数就不尽相同:
IE6:node.nextSibling,对于FF是不能识别的;
FF:node.nextElementSibling,对于IE是不能识别的;
兼容解决方式:var Div = node.nextSibl
【JVM四】老年代垃圾回收:吞吐量垃圾收集器(Throughput GC)
bit1129
垃圾回收
吞吐量与用户线程暂停时间
衡量垃圾回收算法优劣的指标有两个:
吞吐量越高,则算法越好
暂停时间越短,则算法越好
首先说明吞吐量和暂停时间的含义。
垃圾回收时,JVM会启动几个特定的GC线程来完成垃圾回收的任务,这些GC线程与应用的用户线程产生竞争关系,共同竞争处理器资源以及CPU的执行时间。GC线程不会对用户带来的任何价值,因此,好的GC应该占
J2EE监听器和过滤器基础
白糖_
J2EE
Servlet程序由Servlet,Filter和Listener组成,其中监听器用来监听Servlet容器上下文。
监听器通常分三类:基于Servlet上下文的ServletContex监听,基于会话的HttpSession监听和基于请求的ServletRequest监听。
ServletContex监听器
ServletContex又叫application
博弈AngularJS讲义(16) - 提供者
boyitech
js AngularJS api Angular Provider
Angular框架提供了强大的依赖注入机制,这一切都是有注入器(injector)完成. 注入器会自动实例化服务组件和符合Angular API规则的特殊对象,例如控制器,指令,过滤器动画等。
那注入器怎么知道如何去创建这些特殊的对象呢? Angular提供了5种方式让注入器创建对象,其中最基础的方式就是提供者(provider), 其余四种方式(Value, Fac
java-写一函数f(a,b),它带有两个字符串参数并返回一串字符,该字符串只包含在两个串中都有的并按照在a中的顺序。
bylijinnan
java
public class CommonSubSequence {
/**
* 题目:写一函数f(a,b),它带有两个字符串参数并返回一串字符,该字符串只包含在两个串中都有的并按照在a中的顺序。
* 写一个版本算法复杂度O(N^2)和一个O(N) 。
*
* O(N^2):对于a中的每个字符,遍历b中的每个字符,如果相同,则拷贝到新字符串中。
* O(
sqlserver 2000 无法验证产品密钥
Chen.H
sql windows SQL Server Microsoft
在 Service Pack 4 (SP 4), 是运行 Microsoft Windows Server 2003、 Microsoft Windows Storage Server 2003 或 Microsoft Windows 2000 服务器上您尝试安装 Microsoft SQL Server 2000 通过卷许可协议 (VLA) 媒体。 这样做, 收到以下错误信息CD KEY的 SQ
[新概念武器]气象战争
comsci
气象战争的发动者必须是拥有发射深空航天器能力的国家或者组织....
原因如下:
地球上的气候变化和大气层中的云层涡旋场有密切的关系,而维持一个在大气层某个层次
oracle 中 rollup、cube、grouping 使用详解
daizj
oracle grouping rollup cube
oracle 中 rollup、cube、grouping 使用详解 -- 使用oracle 样例表演示 转自namesliu
-- 使用oracle 的样列库,演示 rollup, cube, grouping 的用法与使用场景
--- ROLLUP , 为了理解分组的成员数量,我增加了 分组的计数 COUNT(SAL)
技术资料汇总分享
Dead_knight
技术资料汇总 分享
本人汇总的技术资料,分享出来,希望对大家有用。
http://pan.baidu.com/s/1jGr56uE
资料主要包含:
Workflow->工作流相关理论、框架(OSWorkflow、JBPM、Activiti、fireflow...)
Security->java安全相关资料(SSL、SSO、SpringSecurity、Shiro、JAAS...)
Ser
初一下学期难记忆单词背诵第一课
dcj3sjt126com
english word
could 能够
minute 分钟
Tuesday 星期二
February 二月
eighteenth 第十八
listen 听
careful 小心的,仔细的
short 短的
heavy 重的
empty 空的
certainly 当然
carry 携带;搬运
tape 磁带
basket 蓝子
bottle 瓶
juice 汁,果汁
head 头;头部
截取视图的图片, 然后分享出去
dcj3sjt126com
OS Objective-C
OS 7 has a new method that allows you to draw a view hierarchy into the current graphics context. This can be used to get an UIImage very fast.
I implemented a category method on UIView to get the vi
MySql重置密码
fanxiaolong
MySql重置密码
方法一:
在my.ini的[mysqld]字段加入:
skip-grant-tables
重启mysql服务,这时的mysql不需要密码即可登录数据库
然后进入mysql
mysql>use mysql;
mysql>更新 user set password=password('新密码') WHERE User='root';
mysq
Ehcache(03)——Ehcache中储存缓存的方式
234390216
ehcache MemoryStore DiskStore 存储 驱除策略
Ehcache中储存缓存的方式
目录
1 堆内存(MemoryStore)
1.1 指定可用内存
1.2 驱除策略
1.3 元素过期
2 &nbs
spring mvc中的@propertysource
jackyrong
spring mvc
在spring mvc中,在配置文件中的东西,可以在java代码中通过注解进行读取了:
@PropertySource 在spring 3.1中开始引入
比如有配置文件
config.properties
mongodb.url=1.2.3.4
mongodb.db=hello
则代码中
@PropertySource(&
重学单例模式
lanqiu17
单例 Singleton 模式
最近在重新学习设计模式,感觉对模式理解更加深刻。觉得有必要记下来。
第一个学的就是单例模式,单例模式估计是最好理解的模式了。它的作用就是防止外部创建实例,保证只有一个实例。
单例模式的常用实现方式有两种,就人们熟知的饱汉式与饥汉式,具体就不多说了。这里说下其他的实现方式
静态内部类方式:
package test.pattern.singleton.statics;
publ
.NET开源核心运行时,且行且珍惜
netcome
java .net 开源
背景
2014年11月12日,ASP.NET之父、微软云计算与企业级产品工程部执行副总裁Scott Guthrie,在Connect全球开发者在线会议上宣布,微软将开源全部.NET核心运行时,并将.NET 扩展为可在 Linux 和 Mac OS 平台上运行。.NET核心运行时将基于MIT开源许可协议发布,其中将包括执行.NET代码所需的一切项目——CLR、JIT编译器、垃圾收集器(GC)和核心
使用oscahe缓存技术减少与数据库的频繁交互
Everyday都不同
Web 高并发 oscahe缓存
此前一直不知道缓存的具体实现,只知道是把数据存储在内存中,以便下次直接从内存中读取。对于缓存的使用也没有概念,觉得缓存技术是一个比较”神秘陌生“的领域。但最近要用到缓存技术,发现还是很有必要一探究竟的。
缓存技术使用背景:一般来说,对于web项目,如果我们要什么数据直接jdbc查库好了,但是在遇到高并发的情形下,不可能每一次都是去查数据库,因为这样在高并发的情形下显得不太合理——
Spring+Mybatis 手动控制事务
toknowme
mybatis
@Override
public boolean testDelete(String jobCode) throws Exception {
boolean flag = false;
&nbs
菜鸟级的android程序员面试时候需要掌握的知识点
xp9802
android
熟悉Android开发架构和API调用
掌握APP适应不同型号手机屏幕开发技巧
熟悉Android下的数据存储
熟练Android Debug Bridge Tool
熟练Eclipse/ADT及相关工具
熟悉Android框架原理及Activity生命周期
熟练进行Android UI布局
熟练使用SQLite数据库;
熟悉Android下网络通信机制,S