GeezerVison is showing willkernel.github.io — willkernel
简介
C++ 是一种静态类型的、编译式的、通用的、大小写敏感的、不规则的编程语言,支持过程化编程、面向对象编程和泛型编程 C++ 被认为是一种中级语言,它综合了高级语言和低级语言的特点 C++ 是由 Bjarne Stroustrup 于 1979 年在贝尔实验室开始设计开发的。C++ 进一步扩充和完善C,是 C 的一个超集,事实上,任何合法的 C 程序都是合法的 C++ 程序 注意:使用静态类型的编程语言是在编译时执行类型检查,而不是在运行时执行类型检查 2014 ISO/IEC 14882:2014 C++14 第四个C++标准
C++ 完全支持面向对象的程序设计,包括面向对象开发的四大特性: 封装 抽象 继承 多态
标准库 标准的 C++ 由三个重要部分组成: 核心语言,提供了所有构件块,包括变量、数据类型和常量,等等。 C++ 标准库,提供了大量的函数,用于操作文件、字符串等。 标准模板库(STL),提供了大量的方法,用于操作数据结构等
如果凑巧两个线程在同一时间使用不一致的值执行 setLower 和 setUpper 的话,则会使范围处于不一致的状态。例如,如果初始状态是 (0, 5),同一时间内,线程 A 调用 setLower(4) 并且线程 B 调用 setUpper(3),显然这两个操作交叉存入的值是不符合条件的,那么两个线程都会通过用于保护不变式的检查,使得最后的范围值是 (4, 3) —— 一个无效值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
@NotThreadSafe public class NumberRange { private int lower, upper; public int getLower() { return lower; } public int getUpper() { return upper; } public void setLower(int value) { if (value > upper) throw new IllegalArgumentException(...); lower = value; } public void setUpper(int value) { if (value < lower) throw new IllegalArgumentException(...); upper = value; } }
public interface WindowManager extends ViewManager
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
public interface ViewManager { /** * Assign the passed LayoutParams to the passed View and add the view to the window. * <p>Throws {@link android.view.WindowManager.BadTokenException} for certain programming * errors, such as adding a second view to a window without removing the first view. * <p>Throws {@link android.view.WindowManager.InvalidDisplayException} if the window is on a * secondary {@link Display} and the specified display can't be found * (see {@link android.app.Presentation}). * @param view The view to be added to this window. * @param params The LayoutParams to assign to view. */ public void addView(View view, ViewGroup.LayoutParams params); public void updateViewLayout(View view, ViewGroup.LayoutParams params); public void removeView(View view); }
WHERE AGE >= 25 AND/OR SALARY >= 65000; WHERE AGE IS NOT NULL WHERE NAME LIKE 'Ki%'; WHERE NAME GLOB 'Ki*'; WHERE AGE NOT IN ( 25, 27 ); WHERE AGE BETWEEN 25 AND 27;
SQL 子查询,子查询查找 SALARY > 65000 的带有 AGE 字段的所有记录,后边的 WHERE 子句与 EXISTS 运算符一起使用 SELECT AGE FROM COMPANY WHERE EXISTS (SELECT AGE FROM COMPANY WHERE SALARY > 65000);
AGE ---------- 25 23 25
SELECT * FROM COMPANY WHERE AGE > (SELECT AGE FROM COMPANY WHERE SALARY > 65000);
位运算符 A=60, B=13
表达式
布尔表达式
1
SELECT * FROM COMPANY WHERE SALARY = 10000;
数值表达式
1 2
SELECT COUNT(*) AS "RECORDS" FROM COMPANY; RECORDS = 7
SELECT * FROM COMPANY WHERE AGE BETWEEN 25 AND 27;
SELECT AGE FROM COMPANY WHERE EXISTS (SELECT AGE FROM COMPANY WHERE SALARY > 65000); SELECT * FROM COMPANY WHERE AGE > (SELECT AGE FROM COMPANY WHERE SALARY > 65000);
AND/OR
1 2 3
SELECT * FROM COMPANY WHERE AGE >= 25 AND SALARY >= 65000;
SELECT * FROM COMPANY WHERE AGE >= 25 OR SALARY >= 65000;
Update
1 2 3
UPDATE COMPANY SET ADDRESS = 'Texas' WHERE ID = 6;
UPDATE COMPANY SET ADDRESS = 'Texas', SALARY = 20000.00;
Delete
1 2
DELETE FROM COMPANY WHERE ID = 7; DELETE FROM COMPANY;
Like
通配符 百分号(%)代表零个、一个或多个数字或字符。下划线(_)代表一个单一的数字或字符
1 2 3 4 5
AGE 以 2 开头的所有记录 SELECT * FROM COMPANY WHERE AGE LIKE '2%';
ADDRESS 文本里包含一个连字符(-)的所有记录 SELECT * FROM COMPANY WHERE ADDRESS LIKE '%-%';
Glob
星号(*)代表零个、一个或多个数字或字符。问号(?)代表一个单一的数字或字符,大小写敏感
1
SELECT * FROM COMPANY WHERE AGE GLOB '2*';
Limit
限制返回数据数量
1
SELECT * FROM COMPANY LIMIT 6;
特定的偏移开始提取记录
1 2 3 4 5 6 7
SELECT * FROM COMPANY LIMIT 3 OFFSET 2;
ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 3 Teddy 23 Norway 20000.0 4 Mark 25 Rich-Mond 65000.0 5 David 27 Texas 85000.0
Order By
按 NAME 和 SALARY 升序降序排序
1
SELECT * FROM COMPANY ORDER BY NAME, SALARY [ASC|DESC];
Group By
对相同的数据进行分组,在 SELECT 语句中,GROUP BY 子句放在 WHERE 子句之后,放在 ORDER BY 子句之前
1 2 3 4 5 6 7 8 9
查找名称,薪资总和数据,以名称分组 SELECT NAME, SUM(SALARY) FROM COMPANY GROUP BY NAME; SELECT NAME, SUM(SALARY) FROM COMPANY GROUP BY NAME ORDER BY NAME;
NAME SUM(SALARY) ---------- ----------- Allen 15000.0 David 85000.0 James 10000.0
Having
过滤分组数据
1 2 3 4 5 6 7 8 9
SELECT column1, column2 FROM table1, table2 WHERE [ conditions ] GROUP BY column1, column2 HAVING [ conditions ] ORDER BY column1, column2
名称出现2次的数据 SELECT * FROM COMPANY GROUP BY name HAVING count(name) > 2;
Distinct
获取重复记录中的唯一一次记录
1 2 3 4 5 6
SELECT DISTINCT column1, column2,.....columnN FROM table_name WHERE [condition]
SQL92 不支持的特性如下 RIGHT OUTER JOIN 只实现了 LEFT OUTER JOIN FULL OUTER JOIN 只实现了 LEFT OUTER JOIN ALTER TABLE 支持 RENAME TABLE 和 ALTER TABLE 的 ADD COLUMN variants 命令,不支持 DROP COLUMN、ALTER COLUMN、ADD CONSTRAINT Trigger 支持 FOR EACH ROW 触发器,但不支持 FOR EACH STATEMENT 触发器 VIEWs 在 SQLite 中,视图是只读的,不可以在视图上执行 DELETE、INSERT 或 UPDATE 语句 GRANT 和 REVOKE 可以应用的唯一的访问权限是底层操作系统的正常文件访问权限
在Kotlin中一切都是对象(甚至是Java中原始数据类型),一切都是可null的。所以,当然我们可以有一个可null的integer,检查了一个对象的可null性,之后这个对象就会自动转型成不可null类型,这就是Kotlin编译器的智能转换,在 if 中, a 从 Int? 变成了 Int ,所以我们可以不需要再检查可null性而直接使用它,if 代码之外,又得检查处理,仅仅在变量当前不能被改变的时候才有效val 属性或者本地( val or var )变量,因为这个value可能被另外的线程修改,这时前面的检查会返回false
1 2 3 4 5 6 7 8 9 10 11 12 13
val a:Int?=null ... if(a!=null){ a.toString() }
简化代码 val a: Int? = null ... a?.toString()
val a:Int? = null val myString = a?.toString() ?: ""
throw 和 return 都是表达式
1 2
val myString = a?.toString() ?: return false val myString = a?.toString() ?: throw IllegalStateException()
object CityForecastTable { val NAME = "CityForecast" val ID = "_id" val CITY = "city" val COUNTRY = "country" }
object DayForecastTable { val NAME = "DayForecast" val ID = "_id" val DATE = "date" val DESCRIPTION = "description" val HIGH = "high" val LOW = "low" val ICON_URL = "iconUrl" val CITY_ID = "cityId" }
实现SqliteOpenHelper
1 2 3 4 5 6 7 8 9 10 11 12 13 14
fun SQLiteDatabase.createTable(tableName: String, ifNotExists: Boolean = false, vararg columns: Pair<String, SqlType>) { val escapedTableName = tableName.replace("`", "``") val ifNotExistsText = if (ifNotExists) "IF NOT EXISTS" else "" execSQL( columns.map { col -> "${col.first} ${col.second.render()}" }.joinToString(", ", prefix = "CREATE TABLE $ifNotExistsText `$escapedTableName`(", postfix = ");") ) }
class ForecastDbHelper(ctx: Context = App.instance) : ManagedSQLiteOpenHelper(App.instance, ForecastDbHelper.DB_NAME, null, ForecastDbHelper.DB_VERSION) { override fun onCreate(db: SQLiteDatabase) { db.createTable(CityForecastTable.NAME, true, CityForecastTable.ID to INTEGER + PRIMARY_KEY, CityForecastTable.CITY to TEXT, CityForecastTable.COUNTRY to TEXT)
db.createTable(DayForecastTable.NAME, true, DayForecastTable.ID to INTEGER + PRIMARY_KEY, DayForecastTable.DATE to INTEGER, DayForecastTable.DESCRIPTION to TEXT, DayForecastTable.HIGH to INTEGER, DayForecastTable.LOW to INTEGER, DayForecastTable.ICON_URL to TEXT, DayForecastTable.CITY_ID to INTEGER) }
/** * SQLite表与对象之间的互相映射 */ class CityForecast(val map: MutableMap<String, Any?>, val dailyForecast: List<DayForecast>) { var _id: Long by map var city: String by map var country: String by map
constructor(id: Long, city: String, country: String, dailyForecast: List<DayForecast>) : this(HashMap(), dailyForecast) { this._id = id this.city = city this.country = country } }
/**不同之处就是不需要设置id,因为它将 通过SQLite自增长*/ class DayForecast(val map: MutableMap<String, Any?>) { var _id: Long by map var date: Long by map var description: String by map var high: Long by map var low: Long by map var iconUrl: String by map var cityId: Long by map
class App : Application() { val database: SQLiteOpenHelper by lazy { MyDatabaseHelper(applicationContext) } override fun onCreate() { super.onCreate() val db = database.writableDatabase } }
Observable这个委托会帮我们监测我们希望观察的属性的变化。当被观察属性的 set 方法被调用的时候,它就会自动执行我们指定的lambda表达式。所以一旦该属性被赋了新的值,我们就会接收到被委托的属性、旧值和新值,下面的示例是一些我们需要关心的ViewMode,每次值被修改了,就会保存它们到数据库
1 2 3 4 5 6
class ViewModel(val db: MyDatabase) { var myProperty by Delegates.observable("") { d, old, new -> db.saveChanges(this, new) } }
class App : Application() { companion object { var instance: App by Delegates.notNull() } override fun onCreate() { super.onCreate() instance = this } }
从Map中映射值 属性的值会从一个map中获取value,属性的名字对应这个map中的key,如果我们importkotlin.properties.getValue ,我们可以从构造函数映射到 val 属性来得到一个不可修改的map。如果我们想去修改map和属性,我们也可以import kotlin.properties.setValue 。类需要一个 MutableMap 作为构造函数的参数
import kotlin.properties.getValue class Configuration(map: Map<String, Any?>) { val width: Int by map val height: Int by map val dp: Int by map val deviceName: String by map }
创建一个map
1 2 3 4 5 6
conf = Configuration(mapOf( "width" to 1080, "height" to 720, "dp" to 240, "deviceName" to "mydevice" ))
自定义委托 创建一个类然后继承 ReadWriteProperty :
1 2 3 4 5 6 7 8 9 10
private class NotNullSingleValueVar<T>() : ReadWriteProperty<Any ?, T> { override fun getValue(thisRef: Any?, property: KProperty <*>): T { throw UnsupportedOperationException() } override fun setValue(thisRef: Any?, property: KProperty <*>, value: T) { } }
class App : Application() { companion object { var instance: App by Delegates.notNull() } override fun onCreate() { super.onCreate() instance = this } }
上述可以任何地方修改问题,解决办法使用下面的委托,只能修改一次 companion object { var instance: App by DelegatesExt.notNullSingleValue() }
操作符
操作符在Adapter中的应用
1 2 3 4 5 6 7 8 9 10
// val size: Int get() = dailyForecast.size override fun getItemCount(): Int = items.size
class VH(itemView: View, val itemClick: OnItemClickListener) : RecyclerView.ViewHolder(itemView) { private val iconView: ImageView private val dateView: TextView private val descriptionView: TextView private val maxTemperatureView: TextView private val minTemperatureView: TextView
public class Artist { private long id; private String name; private String url; private String mbid; public long getId() { return id; } public void setId(long id) { this.id = id; } ···
Kotlin中创建数据类Artist.kt,自动生成所有属性和访问器
1
data class Artist(var id: Long, var name: String, var url: String, var mbid: String)
依赖注入(Dependency Injection),简称DI,又叫控制反转(Inversion of Control),简称IOC 当一个类的实例需要另一个类的实例,在传统的设计中,通常由调用者来创建被调用者的实例,然而依赖注入的方式,创建被调用者不再由调用者创建实例,创建被调用者的实例的工作由IOC容器来完成,然后注入到调用者。因此也被称为依赖注入
You are visitor 01402503 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.