首页 文章 精选 留言 我的

精选列表

搜索[学习],共10000篇文章
优秀的个人博客,低调大师

【Android进阶学习】底部Tab的两种实现方式

先写上代码,稍后在写分析的................... 第一种: 下面的tabs.xml布局文件中,整个布局是垂直显示的,分为FrameLayout和TabWidget上下两部分,在FrameLayout布局里面使用layout_weight=“1” ,而TabWidget没有设置这个属性,那就默认为0。那么在这布局中,FrameLayout就按比例分得整个屏幕的3/4,而没有设置layout_weight属性的TabWidget只是占用刚好能显示自己空间大小的位置。这样的话,就能达到就Tab置于底部了。 layout_weight具体可以看看http://liangruijun.blog.51cto.com/3061169/632532里面的FrameLayout布局 tabs.xml <?xmlversion="1.0"encoding="utf-8"?> <TabHostxmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/tabhost" android:layout_width="fill_parent" android:layout_height="fill_parent" > <LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <FrameLayout android:id="@android:id/tabcontent" android:layout_width="fill_parent" android:layout_height="match_parent" android:layout_weight="1" > <TextView android:id="@+id/view1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="nihao" /> <TextView android:id="@+id/view2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="nihenhao" /> </FrameLayout> <TabWidget android:id="@android:id/tabs" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout> </TabHost> main.xml <?xmlversion="1.0"encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> </LinearLayout> TestHostActivity.java packagecom.lingdududu.test; importandroid.app.TabActivity; importandroid.os.Bundle; importandroid.widget.TabHost; publicclassTestHostActivityextendsTabActivity{ /**Calledwhentheactivityisfirstcreated.*/ @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.tabs); TabHosttabhost=getTabHost(); tabhost.addTab(tabhost.newTabSpec("111").setIndicator("view1").setContent(R.id.view1)); tabhost.addTab(tabhost.newTabSpec("222").setIndicator("view2").setContent(R.id.view2)); } } 效果: 第二种: 在LinerLayout布局里面嵌套FrameLayout和RelativeLayout布局,将TabWidget放置在RelativeLayout里面,之后设置RelativeLayout的android:layout_alignParentBottom="true"属性,这个属性的功能是将TabWidget置于父元素(也就是LinerLayout)的底部。这样就能将Tab置于底部了。 <?xmlversion="1.0"encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TabHost android:id="@+id/tabhost" android:layout_width="fill_parent" android:layout_height="fill_parent"> <FrameLayout android:id="@android:id/tabcontent" android:layout_width="fill_parent" android:layout_height="fill_parent" android:paddingBottom="62px" > <TextView android:id="@+id/tab1" android:layout_width="fill_parent" android:layout_height="fill_parent" android:text="这是TabOne" /> <TextView android:id="@+id/tab2" android:layout_width="fill_parent" android:layout_height="fill_parent" android:text="这是TabTwo"/> </FrameLayout> <RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent" > <TabWidget android:id="@android:id/tabs" android:layout_alignParentBottom="true" android:layout_width="fill_parent" android:layout_height="65.0px" android:background="@drawable/tab_bg" /> </RelativeLayout> </TabHost> </LinearLayout> main.xml <?xmlversion="1.0"encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> </LinearLayout> TabHostActivity.java packagecom.lingdududu.test; importandroid.app.Activity; importandroid.os.Bundle; importandroid.widget.TabHost; publicclassTabHostActivityextendsActivity{ publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.tabs); TabHosttabs=(TabHost)findViewById(R.id.tabhost); tabs.setup(); TabHost.TabSpecspec=tabs.newTabSpec("tag1"); spec.setContent(R.id.tab1); spec.setIndicator("TabOne"); tabs.addTab(spec); spec=tabs.newTabSpec("tag2"); spec.setContent(R.id.tab2); spec.setIndicator("TabTwo"); tabs.addTab(spec); tabs.setCurrentTab(0); } } 效果图: 本文转自 lingdududu 51CTO博客,原文链接: http://blog.51cto.com/liangruijun/747173

优秀的个人博客,低调大师

《从零开始学Swift》学习笔记(Day 45)——重写方法

重写实例方法 在子类中重写从父类继承来的实例方法和静态方法。先介绍实例方法的重写。 下面看一个示例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 class Person{ varname:String varage:Int funcdescription()->String{ //实例方法 return "\(name)年龄是:\(age)" } class funcprintClass()->(){ //静态方法 print( "Person打印..." ) } init(name:String,age:Int){ self.name=name self.age=age } } class Student:Person{ varschool:String convenienceinit(){ self.init(name: "Tony" ,age: 18 ,school: "清华大学" ) } init(name:String,age:Int,school:String){ self.school=school super .init(name:name,age:age) } overridefuncdescription()->String{ //重写实例方法description,重写的方法前面要添加关键字override print( "父类打印\(super.description())" ) return "\(name)年龄是:\(age),所在学校:\(school)。" } override class funcprintClass()->(){ //重写静态方法printClass print( "Student打印..." ) } } letstudent1=student() print( "学生1:\(student1.description())" ) //调用了description方法 Person.printClass() Student.printClass() 使用super.description()语句调用父类的description方法,其中super指代父类实例。 重写静态方法printClass,在静态方法中不能访问实例属性。 调用了description方法。由于在子类中重写了该方法,所以调用的是子类中的description方法。输出结果是: 父类打印Tony年龄是: 18 学生1:Tony年龄是: 18,所在学校:清华大学。 为了测试静态方法重写,调用Person.printClass()语言,它是调用父类的printClass静态方法,输出结果是: Person打印... 调用Student.printClass()语言,它是调用子类的printClass静态方法,输出结果是: Student打印... 重写静态方法 与类的静态属性定义类似,静态方法使用class或static关键字,但是使用哪一个要看子类中是否重写该方法。class修饰的静态方法可以被重写,static关键字就不能被重写。 示例代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Account{ varowner:String= "Tony" //账户名 //不能换成static class funcinterestBy(amount:Double)->Double{ //静态方法 return 0.08886 *amount } } class TermAccount:Account{ //定期账户 //可以换成static override class funcinterestBy(amount:Double)->Double{ //静态方法 return 0.09 *amount } } //调用静态方法 print(Account.interestBy(10_000. 00 )) print(TermAccount.interestBy(10_000. 00 )) 由于被重写所以代码class funcinterestBy(amount: Double) -> Double中的class不能换成static。静态方法interestBy可以使用class或static,除非在TermAccount的子类中重写方法interestBy。 本文转自 tony关东升 51CTO博客,原文链接:http://blog.51cto.com/tonyguan/1747504,如需转载请自行联系原作者

优秀的个人博客,低调大师

《从零开始学Swift》学习笔记(Day 46)——下标重写

下标是一种特殊属性。子类属性重写是重写属性的getter和setter访问器,对下标的重写也是重写下标的getter和setter访问器。 下面看一个示例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 classDoubleDimensionalArray{ letrows:Int,columns:Int vargrid:[Int] init(rows:Int,columns:Int){ self.rows=rows self.columns=columns grid=Array(count:rows*columns,repeatedValue: 0 ) } subscript(row:Int,col:Int)->Int{ //定义下标 get{ return grid[(row*columns)+col] } set{ grid[(row*columns)+col]=newValue } } //定义下标 } class SquareMatrix:DoubleDimensionalArray{ overridesubscript(row:Int,col:Int)->Int{ //重写父类下标 get{ return super .grid[(row*columns)+col] } set{ super .grid[(row*columns)+col]=newValue*newValue } } } varary2=SquareMatrix(rows: 5 ,columns: 5 ) for vari= 0 ;i< 5 ;i++{ for varj= 0 ;j< 5 ;j++{ ary2[i,j]=i+j } } for vari= 0 ;i< 5 ;i++{ for varj= 0 ;j< 5 ;j++{ print( "\t\t\(ary2[i,j])" ) } print( "\n" ) } 其中super.grid[(row * columns) + col]语句中使用super调用父类的grid属性。 其中super.grid[(row * columns) + col] = newValue * newValue语句是给父类的grid属性赋值。 本文转自 tony关东升 51CTO博客,原文链接:http://blog.51cto.com/tonyguan/1747531,如需转载请自行联系原作者

优秀的个人博客,低调大师

《从零开始学Swift》学习笔记(Day 49)——扩展声明

声明扩展的语法格式如下: 1 2 3 extension类型名{ //添加新功能 } 声明扩展的关键字是extension,“类型名”是Swift中已有的类型,包括类、结构体和枚举,但是我们仍然可以扩展整型、浮点型、布尔型、字符串等基本数据类型,这是因为这些类型本质上也是结构体类型。打开Int的定义如下: 1 2 3 4 5 6 7 8 9 structInt:SignedInteger{ init() init(_value:Int) static funcconvertFromIntegerLiteral(value:Int)->Int typealiasArrayBoundType=Int funcgetArrayBoundValue()->Int static varmax:Int{get} static varmin:Int{get} } 从定义可见Int是结构体类型。不仅是Int类型,我们熟悉的整型、浮点型、布尔型、字符串等数据类型本质上都是结构体类型。 Swift中的扩展机制可以在原始类型中添加的新功能包括: 实例计算属性和类型计算属性 实例方法和类型方法 构造函数 下标 还有嵌套类型等内容也可以扩展,扩展还可以遵从协议。 本文转自 tony关东升 51CTO博客,原文链接:http://blog.51cto.com/tonyguan/1747536,如需转载请自行联系原作者

优秀的个人博客,低调大师

android用户界面之Gallery3D学习资料汇总

一、Gallery之根蒂根基教程 1.Android Gallery与衍生BaseAdapter容器 http://www.apkbus.com/android-6249-1-1.html 2.Android 根蒂根基 UI 编程之八(相簿浏览 Gallery) http://www.apkbus.com/android-14004-1-1.html 3.android Gallery的进修心得 http://www.apkbus.com/android-17606-1-1.html 4.Android入家世十三篇之Gallery + ImageSwitcher http://www.apkbus.com/android-220-1-1.html 5.Android---UI篇---Gallery(画廊视图) http://www.apkbus.com/android-14231-1-1.html 6.Android Gallery组件详解 http://www.apkbus.com/android-6204-1-1.html 7.Android 控件之Gallery图片集 http://www.apkbus.com/android-1340-1-1.html 8.Android Gallery的简单应用 http://www.apkbus.com/android-7039-1-1.html 9.Gallery3D笔记 http://www.apkbus.com/android-1955-1-1.html 10.Gallery3D各个界面可见局限策画办法 http://www.apkbus.com/android-1952-1-1.html 11.Android对Gallery的商量 http://www.apkbus.com/android-13211-1-1.html 12.Android Gallery3D源码解析 http://www.apkbus.com/android-51639-1-1.html 二、Gallery殊效教程 1.Android中实现Gallery 点击放大 http://www.apkbus.com/android-1017-1-1.html 2.Android中Gallery和ImageSwitcher同步主动(迁移转变)播放图片库 [color=#999999 !important] http://www.apkbus.com/android-19172-1-1.html 3.Android控件之Gallery实现图片列表 http://www.apkbus.com/android-14327-1-1.html 4.Android gallery实现图片的阁下轮回扭转源码分享 http://www.apkbus.com/android-745-1-1.html 5.android开辟之gallery(画廊) http://www.apkbus.com/android-15749-1-1.html 6.Gallery 图片拖动结果(实例+贴图) http://www.apkbus.com/android-1009-1-1.html 7.应用长途图片填充Gallery http://www.apkbus.com/android-51641-1-1.html 8.Android Gallery3D结果 教程 案例 代码 http://www.apkbus.com/android-51642-1-1.html 9.哄骗Gallery来实现缩略图浏览器 http://www.apkbus.com/android-51643-1-1.html 三、Gallery实例源码 1.应用Android自带Gallery组件实现CoverFlow,源码+解析 http://www.apkbus.com/android-13321-1-1.html 2.Android自定义Gallery,实现CoverFlow结果 http://www.apkbus.com/android-18441-1-1.html 3.一个Gallery 3D结果实例 http://www.apkbus.com/android-39891-1-1.html 4.gallery走廊结果图片查看器 http://www.apkbus.com/android-794-1-1.html 5.经由过程SurfaceView实现像Gallery手势滑动图片结果 http://www.apkbus.com/android-12828-1-1.html 6.android Gallery实现异步加载收集图片 并只加载当前停止页面图 http://www.apkbus.com/android-51646-1-1.html 7.连络ImageSwithcer和Gallery控件建造一个图片浏览(附源代码) http://www.apkbus.com/android-51651-1-1.html 转自:链接 本文转自SharkBin博客园博客,原文链接:http://www.cnblogs.com/SharkBin/p/5099343.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

Linux学习笔记 - 第二章 Linux操作系统

1.硬件架构及系统组成 |--硬件架构 可用于运行linux系统的硬件架构 包括:x86 , x64(amd64) , m6800 , m68k , Arm , ultrasparc , power , powerpc(ppc) , MIPS , alpha , ... |--系统组成 硬件 内核 系统调用 库函数 外部应用 ... 2.Linux版本 2.1 Linux核心版本 稳定版本:2.2.x , 2.4.x , 2.6.x , 3.0.x , 4.0.x 开发版本:2.3.x , 2.4.x , 2.5.x , 版本中数字所表达的含义:主版本.次版本.释出版本-修订版本 2.2 Linux发行版 由各个商业组织、社区组织以Linux核心为基本,增加很多应用程序,让后一起打包并 发行出的版本 目前存在的发行版有数百种之多,比较主流的是以下几种 Debian Ubuntu mint knopix slackware S.u.S.E SLES-S.u.S.E Linux Enterprise Server OpenSUSE RedHat Red Hat Enterprise(RHEL) RHEL 7.2 CentOS-Community Enterprise OS Fedora Core(每6个月更新) Gentoo ArchLinux GNU/Linux<===发行特点:通常以源码方式发行 2.3 Linux发行版版本号 发行版本有自己的版本号 例子:RHEL:5.x,6.x,7.x Fedora:23 Debian:8.x OpenSuSE:13.x 3.获取Linux版本 核心获取:www.kernel.org 发行版获取:通过各发行版的官方网站,或国内镜像站点:mirrors.163.com , mirrors.sohu.com , mirrors.aliyun.com 4.Linux哲学思想: 4.1 一切皆文件:把几乎所有资源统统抽象为文件形式,包括硬件设备,甚至通讯接口类; 例如:open(),read(),write(),close(),delete(),create(); 4.2 由众多功能单一的程序组成,一个程序只做一件事,并且做好;即:组合小程序完成复杂任务; 4.3 尽量避免与用户交互, 目标:易于以编程的方式实现自动化任务; 4.4 使用文本文件保存配置信息; 示例:硬件设备也通过文件表示 物理终端:/dev/console 虚拟终端:/dev/tty#[1..6] 串行终端:/dev/ttys# 伪终端:/dev/pts/# 5.安装Linux 5.1 硬件直接安装 安装方法:通过DVD-R,USB,网络等 5.2 通过虚拟机安装 虚拟化平台:Vmware workstation , Oracle VirtualBox 安装方法:通过ISO镜像文件或本地物理光盘驱动器 6.Linux登录 6.1 GUI用户界面(Graphic User Interface) 比较主流的图形界面接口有:KDE , GNome 6.2 CLI用户界面(Command Line Interface) 比较主流的命令行接口有:bash , sh , tsh , csh 6.3 接口提示符说明 [root@node1 ~]# COMMAND prompt: root:当前登录的用户 node1:当前主机的主机名,非完整格式;完整格式一般为:node1.domain.com ~:用户当前所在的目录(current directory),也称为工作目录(working directory),为相对 路径; #:命令提示符,#为管理员提示符,$为普通用户提示符;管理员拥有最高权限,可以执行所有 操作;普通用户不具有管理权限,不能进行管理操作; 6.4 Linux终端 物理终端:是指控制台,Console 虚拟终端:使用tty标识,默认启用6个,可以通过Ctrl+Alt+F[1..6]进行切换 图形终端:可以在CLI下启用startx启动,可以通过Ctrl+Alt+F7切换;在新版本的CentOS下, startx在哪个虚拟终端下启动,就是用该虚拟终端的编号; 串行终端:使用ttys标识 伪终端:使用pts标识,SSH连接方式属于伪终端 示例: ~]# tty<===显示当前运行的终端设备 7.程序管理 程序的组成部分:指令+数据 二进制程序 配置文件 库文件 帮助文件 程序包管理器 程序的组成文件打包成一个或有限几个文件 安装 卸载 查询 各版本Linux程序包管理 Debian:dpkg,apt-get RedHat:rpm,yum --> dnf S.u.S.E:rpm,zypper ArchLinux:port Gentoo:完全源码 LFS:Linux From Scratch kali:集成了很多黑客工具 8.Linux系统中命令类型 |--外部命令:由外部应用(第三方)提供的应用 |--内部命令:shell内部的应用 |--查看方法: ~]# type COMMAND ~]# *** builtin<===此显示结果说明命令为内部命令 ~]# '显示为文件路径'<===此显示结果说明命令为外部命令 ---Note---命令可以有别名,别名可以与原名相同,此时原名被隐藏,此时如果要运行原命令则使 用\COMMAND 本文转自careluck51CTO博客,原文链接: http://blog.51cto.com/brave8898/1851054 ,如需转载请自行联系原作者

优秀的个人博客,低调大师

Hadoop MapReduce概念学习系列之MapReduce的特点(八)

MapReduce 为什么如此受欢迎?尤其现在互联网+时代,互联网+公司都在使用 MapReduce。MapReduce 之所以如此受欢迎,它主要有以下几个特点。 1、MapReduce易于编程。它简单的实现一些接口,就可以完成一个分布式程序,这个分布式程序可以分布到大量廉价的 PC 机器运行。也就是说你写一个分布式程序,跟写一个简单的串行程序是一模一样的。 就是因为这个特点使得 MapReduce 编程变得非常流行。 2、良好的扩展性。当你的计算资源不能得到满足的时候,你可以通过简单的增加机器来扩展它的计算能力。 3、高容错性。MapReduce 设计的初衷就是使程序能够部署在廉价的 PC 机器上,这就要求它具有很高的容错性。比如其中一台机器挂了,它可以把上面的计算任务转移到另外一个节点上面上运行,不至于这个任务运行失败,而且这个过程不需要人工参与,而完全是由 Hadoop 内部完成的。 4、适合 PB 级以上海量数据的离线处理。这里加红字体离线处理,说明它适合离线处理而不适合在线处理。比如像毫秒级别的返回一个结果,MapReduce 很难做到。 MapReduce 虽然具有很多的优势,但是它也有不擅长的地方。这里的不擅长不代表它不能做,而是在有些场景下实现的效果差,并不适合 MapReduce 来处理,主要表现在以下几个方面。 1、实时计算。MapReduce 无法像 Mysql 一样,在毫秒或者秒级内返回结果。 2、流式计算。流式计算的输入数据时动态的,而 MapReduce 的输入数据集是静态的,不能动态变化。这是因为 MapReduce 自身的设计特点决定了数据源必须是静态的。 3、DAG(有向图)计算。多个应用程序存在依赖关系,后一个应用程序的输入为前一个的输出。在这种情况下,MapReduce 并不是不能做,而是使用后,每个MapReduce 作业的输出结果都会写入到磁盘,会造成大量的磁盘IO,导致性能非常的低下。 MapReduce 定义 Hadoop 中的 MapReduce 是一个使用简单的软件框架,基于它写出来的应用程序能够运行在由上千个商用机器组成的大型集群上,并以一种可靠容错式并行处理TB级别的数据集。 MapReduce 来源 Hadoop MapReduce 源于 Google 在2004年12月份发表的 MapReduce 论文。 Hadoop MapReduce 其实就是 Google MapReduce 的一个克隆版本。 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/5058757.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

《从零开始学Swift》学习笔记(Day 36)——静态方法

静态方法与静态属性类似,Swift中定义了静态方法,也称为类型方法。静态方法的定义与静态属性类似,枚举和结构体的静态方法使用的关键字是static;类静态方法使用的关键字是class或static,如果使用static定义,则该方法不能在子类中被重写(override);如果使用class定义,则该方法可以被子类重写。 结构体静态方法 看一个结构体静态方法的示例,代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 structAccount{ varowner:String= "Tony" //声明实例属性账户名 static varinterestRate:Double= 0.0668 //声明静态属性利率 static funcinterestBy(amount:Double)->Double{ //定义静态方法 return interestRate*amount } funcmessageWith(amount:Double)->String{ //定义实例方法 letinterest=Account.interestBy(amount) return "\(self.owner)的利息是\(interest)" } } //调用静态方法 print(Account.interestBy(10_000. 00 )) varmyAccount=Account() //调用实例方法 print(myAccount.messageWith(10_000. 00 )) 枚举静态方法 看一个枚举静态方法的示例,代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 enum Account{ case 中国银行 case 中国工商银行 case 中国建设银行 case 中国农业银行 static varinterestRate:Double= 0.0668 //声明静态属性利率 static funcinterestBy(amount:Double)->Double{ //定义静态方法 return interestRate*amount } } //调用静态方法 print(Account.interestBy(10_000. 00 )) //调用静态方法 从示例可以看出,结构体和枚举的静态方法使用定义没有区别。 类静态方法 看一个类静态方法的示例,代码如下: 1 2 3 4 5 6 7 8 9 10 11 class Account{ varowner:String= "Tony" //账户名 //可以换成static class funcinterestBy(amount:Double)->Double{ //使用关键字class定义静态方法 return 0.08886 *amount } } //调用静态方法 print(Account.interestBy(10_000. 00 )) //调用静态方法 本文转自 tony关东升 51CTO博客,原文链接:http://blog.51cto.com/tonyguan/1746990,如需转载请自行联系原作者

优秀的个人博客,低调大师

Storm概念学习系列之Tuple元组(数据载体)

Tuple元组 Tuple 是 Storm 的主要数据结构,并且是 Storm 中使用的最基本单元、数据模型和元组。 Tuple 描述 Tuple 就是一个值列表, Tuple 中的值可以是任何类型的,动态类型的Tuple的fields可以不用声明;默认情况下,Storm中的Tuple支持私有类型、字符串、字节数组等作为它的字段值,如果使用其他类型,就需要序列化该类型。 Tuple的字段默认类型有 :integer、 float、 double、 long、short、 string、 byte、 binary(byte[])。 Tuple元组,是消息传递的基本单元,是一个命名的值列表,元组中的字段可以是任何类型的对象。Storm使用元组作为其数据模型,元组支持所有的基本类型、字符串和字节数组作为字段值,只要实现类型的序列化接口就可以使用该类型的对象。 元组本来应该是一个key-value的Map,但是由于各个组件间传递的元组的字段名称已经事先定义好,所以只要按序把元组填入各个value即可,所以元组是一个vlue的List。 Tuple是Storm采用的数据表示模型,所有的数据都以Tuple的形式在各个组件之间流动。Tuple是一组字段列表,每个字段由一个字段名和字段值组成,每个Tuple类似于数据库中的一行记录。在默认的情况下,Tuple的字段类型可以是integer、long、short、byte、string、double、float、boolean和byte array。当然,你也可以通过实现序列化器自定义类型。 Tuple 数据结构如图 1 所示。 图 1 Tuple 数据结构 Tuple 可以理解成键值对。例如,创建一个Bolt 要发送两个字段(命名为 double 和 triple),其中键就是定义在declareOutputFields 方法中的 Fields 对象,值就是在 emit 方法中发送的 Values 对象。 以下是一个简单例子 public class DoubleAndTripleBolt extends BaseRichBolt { OutputCollectorBase _collector; @Override public void prepare(Map conf, TopologyContext context, OutputCollectorBase collector) { _collector = collector; } @Override public void execute(Tuple input) { int val = input.getInteger(0); _collector.emit(input, new Values(val*2, val*3)); _collector.ack(input); } @Override public void declareOutputFields(OutputFieldsDeclarer declarer) { declarer.declare(new Fields("double", "triple")); }} 此外,在使用的 Storm Java 包中, backtype.storm.tuple 主要有以下几个类: Fileds.class MessageId.class Tuple.class TupleImpl.class Values.class 列出以上内容是为了更好地理解 Tuple,这样能够从本质上理解 Tuple,在使用时更加得心应手。 Tuple 的生命周期 了解一个 Tuple 的生命周期就需要查看源码,如下的 Java 代码展示了 Spout(消息源)接口发出 Tuple(消息)的整个过程。 public interface ISpout extends Serializable { void open(Map conf, TopologyContext context, SpoutOutputCollector collector); void nextTuple(); void ack(Object msgId); void fail(Object msgId); void close(); } 首 先, Storm 调 用 Spout(消息源)的nextTuple 方法来获取下一个Tuple,Spout通过Open 方法的参数提供的SpoutOutputCollector将新Tuple发射到其中一个输出消息流。 注意:发射Tuple 时, Spout提供一个message-id,通过这个ID 来追踪该Tuple。 接下来, Storm跟踪该Tuple的树形结构是否成功创建,并根据 messageid调用Spout中的ack函数,以确认Tuple是否被完全处理。如果Tuple超时,则调用 Spout 的 fail 方法。 由此看出,同一个Tuple不管是acked,还是failed都是由创建它的Spout发出并维护的,所以,即使Spout 在集群环境中同时执行很多的任务,该Tuple 也不会被其他任务调用或生成 acked或 failed 状态。总之, Storm会利用内部的 Acker 机制保证每个Tuple 被可靠地处理。最后,在任务完成后,Spout调用Close方法结束 Tuple 的使命。 比如 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/5989281.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

Android开发学习笔记:Intent的简介以及属性的详解

一.Intent的介绍 Intent的中文意思是“意图,意向”,在Android中提供了Intent机制来协助应用间的交互与通讯,Intent负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述,Android则根据此Intent的描述,负责找到对应的组件,将 Intent传递给调用的组件,并完成组件的调用。Intent不仅可用于应用程序之间,也可用于应用程序内部的Activity/Service之间的交互。因此,可以将Intent理解为不同组件之间通信的“媒介”专门提供组件互相调用的相关信息。 二.Inten启动组件的方法 Intent可以启动一个Activity,也可以启动一个Service,还可以发起一个广播Broadcasts。具体方法如下: 组件名称 方法名称 Activity startActvity( ) startActivity( ) Service startService( ) bindService( ) Broadcasts sendBroadcasts( ) sendOrderedBroadcasts( ) sendStickyBroadcasts( ) 三.Intent的属性 Intent有以下几个属性: 动作(Action),数据(Data),分类(Category),类型(Type),组件(Compent)以及扩展信(Extra)。其中最常用的是Action属性和Data属性。 1.Intent的Action属性 Action是指Intent要完成的动作,是一个字符串常量。SDK中定义了一些标准的Action常量如下表所示。 Constant Target component Action ACTION_CALL activity Initiate a phone call. ACTION_EDIT activity Display data for the user to edit. ACTION_MAIN activity Start up as the initial activity of a task, with no data input and no returned output. ACTION_SYNC activity Synchronize data on a server with data on the mobile device. ACTION_BATTERY_LOW broadcast receiver A warning that the battery is low. ACTION_HEADSET_PLUG broadcast receiver A headset has been plugged into the device, or unplugged from it. ACTION_SCREEN_ON broadcast receiver The screen has been turned on. ACTION_TIMEZONE_CHANGED broadcast receiver The setting for the time zone has changed. 下面是一个测试Action常量的例子: main.xml <?xmlversion="1.0"encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> <Button android:text="测试Action属性" android:id="@+id/getBtn" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> strings.xml <?xmlversion="1.0"encoding="utf-8"?> <resources> <stringname="hello">测试Action属性</string> <stringname="app_name">IntentActionDemo</string> </resources> MainActivity.java packagecom.android.action.activity; importandroid.app.Activity; importandroid.content.Intent; importandroid.os.Bundle; importandroid.view.View; importandroid.view.View.OnClickListener; importandroid.widget.Button; publicclassMainActivityextendsActivity{ privateButtongetBtn; @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); getBtn=(Button)findViewById(R.id.getBtn); getBtn.setOnClickListener(newOnClickListener(){ @Override publicvoidonClick(Viewv){ Intentintent=newIntent(); intent.setAction(Intent.ACTION_GET_CONTENT);//设置IntentAction属性 intent.setType("vnd.android.cursor.item/phone");//设置IntentType属性 //主要是获取通讯录的内容 startActivity(intent);//启动Activity } }); } } 效果图: 2.Intent的Data属性 Intent的Data属性是执行动作的URI和MIME类型,不同的Action有不同的Data数据指定。比如:ACTION_EDIT Action应该和要编辑的文档URI Data匹配,ACTION_VIEW应用应该和要显示的URI匹配。 3.Intent的Category属性 Intent中的Category属性是一个执行动作Action的附加信息。比如:CATEGORY_HOME则表示放回到Home界面,ALTERNATIVE_CATEGORY表示当前的Intent是一系列的可选动作中的一个。下表是SDK文档中关于Category的信息。 Constant Meaning CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to display data referenced by a link — for example, an image or an e-mail message. CATEGORY_GADGET The activity can be embedded inside of another activity that hosts gadgets. CATEGORY_HOME The activity displays the home screen, the first screen the user sees when the device is turned on or when the HOME key is pressed. CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in the top-level application launcher. CATEGORY_PREFERENCE The target activity is a preference panel. 下面是一个回到Home界面的例子: main.xml <?xmlversion="1.0"encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical"android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="测试IntentCategory" /> <Button android:id="@+id/Button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="转到Home界面" /> </LinearLayout> strings.xml <?xmlversion="1.0"encoding="utf-8"?> <resources> <stringname="hello">HelloWorld,MainActivity!</string> <stringname="app_name">IntentCategoryDemo</string> </resources> MainActivity.java packagecom.android.category.activity; importandroid.app.Activity; importandroid.content.Intent; importandroid.os.Bundle; importandroid.view.View; importandroid.view.View.OnClickListener; importandroid.widget.Button; publicclassMainActivityextendsActivity{ privateButtonbtn; @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); btn=(Button)findViewById(R.id.Button1); btn.setOnClickListener(newOnClickListener(){ @Override publicvoidonClick(Viewv){ Intentintent=newIntent(); intent.setAction(Intent.ACTION_MAIN);//添加Action属性 intent.addCategory(Intent.CATEGORY_HOME);//添加Category属性 startActivity(intent);//启动Activity } }); } } 效果图: 4.Intent的Type属性 Intent的Type属性显式指定Intent的数据类型(MIME)。一般Intent的数据类型能够根据数据本身进行判定,但是通过设置这个属性,可以强制采用显式指定的类型而不再进行推导。 5.Intent的Compent属性 Intent的Compent属性指定Intent的的目标组件的类名称。通常 Android会根据Intent 中包含的其它属性的信息,比如action、data/type、category进行查找,最终找到一个与之匹配的目标组件。但是,如果 component这个属性有指定的话,将直接使用它指定的组件,而不再执行上述查找过程。指定了这个属性以后,Intent的其它所有属性都是可选的。 6.Intent的Extra属性 Intent的Extra属性是添加一些组件的附加信息。比如,如果我们要通过一个Activity来发送一个Email,就可以通过Extra属性来添加subject和body。 下面的例子在第一个Activity的EditText输入用户名,该年龄保存在Intent的Extras属性中。当单击Button时,会在第二个Activity中显示用户名。 first.xml <?xmlversion="1.0"encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="请输入用户名" /> <EditText android:id="@+id/EditText1" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/Button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="测试Extras属性" /> </LinearLayout> second.xml <?xmlversion="1.0"encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:id="@+id/TextView1" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> strings.xml <?xmlversion="1.0"encoding="utf-8"?> <resources> <stringname="hello">HelloWorld,FirstActivity!</string> <stringname="app_name">IntentExtrasDemo</string> </resources> FirstActivity.java packagecom.android.extras.activity; importandroid.app.Activity; importandroid.content.Intent; importandroid.os.Bundle; importandroid.view.View; importandroid.view.View.OnClickListener; importandroid.widget.Button; importandroid.widget.EditText; publicclassFirstActivityextendsActivity{ privateButtonbtn; privateEditTextetx; @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.first); btn=(Button)findViewById(R.id.Button1); etx=(EditText)findViewById(R.id.EditText1); btn.setOnClickListener(newOnClickListener(){ @Override publicvoidonClick(Viewv){ Intentintent=newIntent(); //设置Intent的class属性,跳转到SecondActivity intent.setClass(FirstActivity.this,SecondActivity.class); //为intent添加额外的信息 intent.putExtra("useName",etx.getText().toString()); //启动Activity startActivity(intent); } }); } } SecondActivity.java packagecom.android.extras.activity; importandroid.app.Activity; importandroid.content.Intent; importandroid.os.Bundle; importandroid.widget.TextView; publicclassSecondActivityextendsActivity{ privateTextViewtv; @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); //设置当前的Activity的界面布局 setContentView(R.layout.second); //获得Intent Intentintent=this.getIntent(); tv=(TextView)findViewById(R.id.TextView1); //从Intent获得额外信息,设置为TextView的文本 tv.setText(intent.getStringExtra("useName")); } } 注意:在添加第二个Activity SecondActivity的时候,要在AndroidManifest.xml里面添加上SecondActivity,具体如下,即是在15行</activity>的后面添加上16~18行的代码。如果不这样做,就会在模拟器上出现错误。 <?xmlversion="1.0"encoding="utf-8"?> <manifestxmlns:android="http://schemas.android.com/apk/res/android" package="com.android.extras.activity" android:versionCode="1" android:versionName="1.0"> <uses-sdkandroid:minSdkVersion="10"/> <applicationandroid:icon="@drawable/icon"android:label="@string/app_name"> <activityandroid:name=".FirstActivity" android:label="@string/app_name"> <intent-filter> <actionandroid:name="android.intent.action.MAIN"/> <categoryandroid:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <activityandroid:name=".SecondActivity" android:label="@string/app_name"> </activity> </application> </manifest> 效果图: 本文转自 lingdududu 51CTO博客,原文链接: http://blog.51cto.com/liangruijun/634411

优秀的个人博客,低调大师

8、周期性任务、find、break和continue 学习笔记

find [options] [查找路径] [查找条件] [处理动作] 查找路径:默认为当前目录 查找条件:默认为查找指定路径下的所有文件 处理动作:默认为显示 查找条件: -name "文件名称" 支持使用globbing正则表达式 -iname "文件名称" 查找时不区分字符大小写 -user UserName 根据属主查找 -group GroupName 根据属组查找 -uid UID 根据uid查找 -gid GID 根据gid查找 -nouser 查找没有属主的文件 -nogroup 查找没有属组的文件 组合条件: -a 与,同时满足 -o 或,满足其一 -not, ! 非,取反 -type: 根据文件类型查找 f: 普通文件 d: 目录 b: 块设备 c: 字符设备 l: 符号链接文件 p: 命名管道 s: 套接字 -size: 根据文件大小查找(常用单位:k, M, G) -#M 查找所有文件大小小于#M的文件 +#M 查找所有文件大小大于#M的文件 #M 查找所有文件大小等于#M的文件 根据时间戳查找: 以天为单位(time): -atime -mtime -ctime +# 查找(#+1)天之外被访问过的文件 -# 查找#天之内被访问过的文件 查找短于(#+1)> x >=#天的时间段被访问过 以分钟为单位(min): -amin -mmin -cmin +# 查找(#+1)分之外被访问过的文件 -# 查找#天之分被访问过的文件 查找短于(#+1)> x >=#分的时间段被访问过 根据权限查找: -perm [+|-]MODE MODE 精确匹配 +MODE 任何一类用户的任何一位权限匹配;常用于查找某类用户的某特定权限是否存在; -MODE 每类用户的指定要检查的权限位都匹配; 文件权限:644 -perm 600 否,因为不匹配644 -perm +222 是,因为任何一位有2权限 -perm +002 否,因为任何一位的权限都不匹配 -perm -444 是,因为每位的4权限都匹配 练习: 1、查找/var/目录属主为root且属组为mail的所有文件; # find /var/ -user root -a -group mail 2、查找/usr目录下不属于root、bin或hadoop的所用文件; # find /usr/ -not -user root -a -not -user bin -a -not -user hadoop # find /usr/ -not \( -user root -o -user bin -o -user hadoop \) 3、查找/etc/目录下最近一周内其内容修改过的,且不属于root或hadoop的文件; # find /etc/ -mtime -7 -a -not -user root -a -not -user hadoop # find /etc/ -mtime -7 -a -not \( -user root -o -user hadoop \) 4、查找当前系统上没有属主或属组,且最近1个月内曾被访问过的文件; # find / \( -nouser -o -nogroup \) -a -atime -30 5、查找/etc/目录下大于1M且类型为普通文件的所有文件; # find /etc/ -size +1M -a -type f 6、查找/etc/目录所有用户都没有写权限的文件; # find /etc/ -not -perm +222 所有都没有:相反:任何一个有 所有都有:相反:至少有一个没有 7、查找/etc/目录下至少有一类用户没有写权限; # find /etc/ -not -perm -222 8、查找/etc/init.d/目录下,所有用户都有执行权限且其它用户有写权限的文件; # find /etc/init.d/ -perm -113 处理动作: -print 默认打印在标准输出上 -ls 以长格式输出各文件信息 -exec COMMAND {} \; 对查找到的文件执行指定的命令 -ok COMMAND {} \; 交互式的-exec; | xargs COMMAND find补充材料(摘自互联网): find与xargs 在使用find命令的-exec选项处理匹配到的文件时, find命令将所有匹配到的文件一起传递给exec执行。但有些系统对能够传递给exec的命令长度有限制,这样在find命令运行几分钟之后,就会出现 溢出错误。 错误信息通常是“参数列太长”或“参数列溢出”。这就是xargs命令的用处所在,特别是与find命令一起使用。 find命令把匹配到的文件传递给xargs命令,而xargs命令每次只获取一部分文件而不是全部,不像-exec选项那样。这样它可以先处理最先获取的一部分文件,然后是下一批,并如此继续下去。 在有些系统中,使用-exec选项会为处理每一个匹配到的文件而发起一个相应的进程,并非将匹配到的文件全部作为参数一次执行;这样在有些情况下就会出现进程过多,系统性能下降的问题,因而效率不高; 而使用xargs命令则只有一个进程。另外,在使用xargs命令时,究竟是一次获取所有的参数,还是分批取得参数,以及每一次获取参数的数目都会根据该命令的选项及系统内核中相应的可调参数来确定。 文件的特殊权限: 可执行文件:suid 任何用户执行此可执行文件时,不再以用户自己的身份当作进程的属主,而是以文件的属主当作进程的属主 suid表现为文件属主执行权限位上的s或S,有执行权限的为s而没有执行权限的为S 如何设定suid权限: chmod u+s FILE 目录文件:sgid 具有sgid的目录,用户在此目录下创建文件时,新建文件的属组不再是用户所属的基本组,而是目录的属组 sgid表现为文件属组执行权限位上的s或S,有执行权限的为s而没有执行权限的为S 如何设定sgid权限: chmod g+s FILE ... 粘滞位:sticky 对于公共可写的目录,用户可创建文件,可以删除自己的文件,但无法删除别的用户的文件 sticky表示为文件其它用户执行权限位上的t或T,,有执行权限的为t而没有执行权限的为T 如何设定sticky权限: chmod o+t FILE ... 练习: 1、复制cat命令至/tmp目录,普通用户使用/tmp/cat命令能查看root用户有权限查看的所有文件 cp `which cat` /tmp/ cp /etc/shadow /tmp/ chmod u+s cat 2、新建/tmp/test目录: 要求openstack和docker用户对其有写权限,且在目录创建的文件的属组都为cloud组 要求每个用户不能删除别人的文件,但可以编辑 mkdir /tmp/test groupadd cloud useradd -G cloud openstack useradd -G cloud docker chmod g+w /tmp/test/ chown :cloud /tmp/test chmod g+s test/ Linux任务计划: 一次性任务执行:at 周期性任务执行:crontab 一次性任务执行: at: 交互式:让用户在at>提示符输入多个要执行命令; at TIME at> Ctrl+d:提交任务; 批处理:将任务的各命令写入文件由at进行调用; at -f /path/to/at_job_file TIME at作业有队列:使用单个字母表示 查看作业:at -l = atq 删除一个尚未执行的作业: at -d job_num atrm job_num 任务计划的执行结果会通过邮件的方式发送给任务提交者; mail命令: 交互模式接收邮件; 交互模式发送邮件: -s "Subject" < /path/to/somefile 周期性任务计划:cron crond: 守护进程 服务进程: 阻塞,轮询 系统cron: 文件:/etc/crontab 用户cron: /var/spool/cron/UserName /etc/crontab文件:每行定义一个独立的任务; SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root HOME=/ # For details see man 4 crontabs # Example of job definition: # .---------------- minute (0 - 59) # | .------------- hour (0 - 23) # | | .---------- day of month (1 - 31) # | | | .------- month (1 - 12) OR jan,feb,mar,apr ... # | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat # | | | | | # * * * * * user-name command to be executed 时间表示法: 1、每个时间位都应该使用其可用的有效取值范围内的值; 2、某时间位上的*表示对应位的所有有效取值; 3、-: 连续的时间相邻点取值; 4、,: 离散的时间点取值; 5、/#:表示在指定时间范围内每隔#一次; 注意:通过输出重定向而拒收邮件: 将执行结果重定向到/dev/null &> /dev/null 将邮件发给空用户 MAILTO="" 用户cron: 使用crontab命令来实现 -l: 查看自己的cron任务列表; -e: 通过EDITOR变量中定义的编辑器打开用户自己的cron配置文件; 编辑单独的任务都使用-e选项,无论是删除、修改还是新建; -r: 移除crontab文件 如果是管理员: -u UserName:为别的用户配置crontab作业; # crontab -e -u docker 提醒:如果在crontab的用户命令中使用%,得转义为\% 5 3 * * * /bin/touch ~/testfile_`date +\%Y-\%m-\%d`.txt 在使用单引号后,%也可以不用转义 5 3 * * * /bin/touch ~/testfile_`date +'%Y-%m-%d'`.txt 练习: 1、每3分钟执行一个“echo "how are you?"; 2、每周2、4、6备份/etc/目录至/backup目录中,备份的文件名以当etc_开头并跟上当日的日期作为文件名; 3、每天6、9、12、15、18查看一下当前系统挂载的所有文件系统,并将查看的结果追加至/tmp/mounts.txt文件中; 4、每天每两小时取当前系统内存空间余量,将其保存至/stats/memory.txt文件中; crontab文件的格式: 空白行会被忽略 # 开头的行是注释; 1、*/3 * * * * /bin/echo "how are you?" 2、3 2 * * 2,4,6 /bin/tar -Jcf /backup/etc_`date '+%F'`.tar.xz /etc/* 3、17 6,9,12,15,18 * * * /bin/mount >> /tmp/mounts.txt 4、34 */2 * * * /bin/grep "^MemFree:" /proc/meminfo >> /stats/memory.txt 如何实现秒级别的任务: * * * * * for i in {0..4}; do /bin/echo "how are you?"; sleep 10; done facl: 文件访问控制列表 facl: 附加原有权限模型之上另一层权限控制机制,保存至文件扩展属性信息中; getfacl FILE 获取文件的权限信息 setfacl {-x|-m} 权限 FILE 设置文件的权限 -m: 设定权限 -m u:UserName:Perms -m g:GroupName:Perms -m m::Perms -x: 取消权限 -x u:UserName -x g:GroupName -x m: -R: 递归 bash编程之循环控制: for varName in LIST; do 循环体 done while CONDITION; do 循环体 done until CONDITION; do 循环体 done 循环控制: continue: 提前结束本次循环而开始评估下一轮; break [n]: 跳出当前循环 练习:提示用户输入用户名,显示用户的ID号;直到用户输入quit退出; #!/bin/bash # if [ $UID -ne 0 ]; then echo "`basename $0` must be running as root" exit 1 fi while true; do read -p "Enter a user name: " userName if [ "$userName" == 'quit' ]; then break fi id -u $userName done 练习:写一个脚本 1、提示用户输入一个目录路径; 2、显示目录下至少包含一个大写字母的文件名; #!/bin/bash # while true; do read -p "Enter a directory: " dirName [ "$dirName" == 'quit' ] && exit 3 [ -d "$dirName" ] && break || echo "Wrong directory..." done for fileName in $dirName/*; do if [[ "$fileName" =~ .*[[:upper:]]{1,}.* ]]; then echo "$fileName" fi done 本文转自开源殿堂 51CTO博客,原文链接http://blog.51cto.com/kaiyuandiantang/1943241:,如需转载请自行联系原作者

优秀的个人博客,低调大师

学习ios【2】Objective-C 数字和字符串

一 数字 1.使用Foundation.h可以直接导入所有的头文件。 在XCode中,想查看某个方法帮助,可以将光标放在方法上,按住option键同时单击即可。 官方文档: https://developer.apple.com/library/mac/navigation/ 2.数字对象 objective-c有几种基本数据类型,int float long等,不过有些时候比如NSArray需要使用数字对象,而前面几种基本数据类型并不是对象,此时我们可以使用NSNumber. 对于每种基本数据类型,类方法都可以为它创建一个NSNumber对象,并设定值。这些方法都是以numberWith开头,如numberWithInteger等。也可以使用实例方法将以前创建的NSNuber对象设置为指定的值,这些方法是以initWith开头,如initWithFloat。 NSNumber类有很多方法,几种常见用法如下: numberWith…:用初始值创建NSNumber对象,例如:numberWithInt:100; integerValue:获取NSNumber对象的值,其它如charValue,floatValue等; isEqualToNumber:比较两个NSNumber对象的数值是否相等,返回一个BOOL值。 compare:比较两个NSNumber对象数值的大小。返回结果有NSOrderedAscending,NSOrderedSame和NSOrderedDescending。 最近objective-c语言扩展允许通过@表达式创建数字对象。如果@之后的值是一个表达式或者变量需要使用括号。 #import <Foundation/Foundation.h> int main(int argc,const char * argv[]) { @autoreleasepool { NSNumber *myNumber,*floatNumber,*intNumber; intNumber=[NSNumber numberWithInt:100]; NSLog(@"%li",[intNumber integerValue]);//100 floatNumber=[NSNumber numberWithFloat:100.00]; NSLog(@"%f",[floatNumber floatValue]);//100.000000 myNumber=[NSNumber numberWithChar:'A']; NSLog(@"%c",[myNumber charValue]);//A //判断两个数字是否相等 if([intNumber isEqualToNumber:floatNumber]==YES) { NSLog(@"int number is equal to float number");//√ } else{ NSLog(@"int number is not equal to float number"); } //比较两个数字大小 if([intNumber compare:myNumber]==NSOrderedAscending) { NSLog(@"int number is less than mynumber"); } else{ NSLog(@"int number is more than mynumber");//√ } //@语法 intNumber=@200; NSLog(@"%li",[intNumber integerValue]);//200 } return 0; } 二 字符串 1.常量字符串对象 在字符串开头放一个@符号,就可以创建一个字符串常量对象。例如:@"Hello World!" 2.decription NSLog(@"%@",a)中,%@既可以显示NSString对象,也可以显示其它对象。通过覆盖description方法,可以自定义对象的显示格式。 Complex.h #import <Foundation/Foundation.h> @interface Complex : NSObject @property int real,imaginary; -(void)setReal:(int)r andImaginary:(int)m; @end Complex.m #import "Complex.h" @implementation Complex @synthesize real,imaginary; -(void)setReal:(int)r andImaginary:(int)m { self.real=r; self.imaginary=m; } //重写description,自定义输出格式 -(NSString *)description { return [NSString stringWithFormat:@"%i + %ii",self.real,self.imaginary]; } @end main.m #import <Foundation/Foundation.h> #import "Complex15.h" int main(int argc,const char * argv[]) { @autoreleasepool { Complex15 *c=[[Complex15 alloc] init]; [c setReal:1 andImaginary:2]; NSLog(@"%@",c);//由<Complex15: 0x10010ffa0> 变为 1 + 2i } return 0; } 2.不可变字符串NSString 注意:不可变字符串对象表明它所引用的字符串对象的字符不可改变,但是可以重新为它们指定为其它的不可变字符串对象。 NSString常用的方法: length:获取字符串长度; NSString stringWithString:复制字符串内容; stringByAppendingString:连接两个字符串; isEqualToString:比较两个字符串是否相等; compare:字符串比较,常用于排序。比较结果为NSOrderedAssending,NSOrderedSame或NSOrderedDescending。 uppercaseString:字符串转换为大写; lowercaseString:字符串转换为小写。 int main(int argc, const char * argv[]) { @autoreleasepool { NSString *str1=@"This is String A"; NSString *str2=@"This is String B"; NSString *result; NSComparisonResult compareResult; // 字符串长度 NSLog(@"length of str1 is %lu",[str1 length]);//length of str1 is 16 //复制字符串 result=[NSString stringWithString:str1]; NSLog(@"Copy str1,result is: %@",result);//Copy str1,result is: This is String A //追加字符串 str2=[str1 stringByAppendingString:str2]; NSLog(@"str1 append str2 is:%@",str2);//str1 append str2 is:This is String AThis is String B //字符串是否相等 if([str1 isEqualToString:result]){ NSLog(@"str1==result");//√ } else{ NSLog(@"str!=str2"); } //比较字符串 compareResult=[str1 compare:str2]; if(compareResult==NSOrderedAscending){ NSLog(@"str1<str2");//√ }else if(compareResult==NSOrderedSame){ NSLog(@"str1=str2"); }else{ NSLog(@"str1>str2"); } //大小写转换 result=[str1 uppercaseString]; NSLog(@"upper case:%@",result);//upper case:THIS IS STRING A result=[str1 lowercaseString]; NSLog(@"lower case:%@",result);//lower case:this is string a } return 0; } 子字符串操作: substringToIndex:返回一个子串,截取从开头到指定索引数的字符,但是不包括这个字符。 substringFromIndex:返回一个子串,截取从指定位置到字符串结尾的字符。 substringWithRange:返回指定范围的字符,参数是NSRange类型。 rangeOfString:在字符串中查找子串,返回结果是NSRange类型,它是一个结构变量,不是对象变量。返回结果range.location表示子串起始位置,range.length表示子串长度。如果找不到指定子串,则location为NSNotFound。 int main(int argc, const char * argv[]) { @autoreleasepool { NSString *str1=@"This is String A"; NSString *result; NSRange range; //从开头取前N个字符 result=[str1 substringToIndex:4]; NSLog(@"前4个字符:%@",result);//前4个字符:This //取第N个字符到结尾 result=[str1 substringFromIndex:8]; NSLog(@"后8个字符:%@",result);//后8个字符:String A //提取第8到13个字符 result=[[str1 substringFromIndex:8] substringToIndex:6]; NSLog(@"第8到13个字符:%@",result);//第8到13个字符:String //另一种实现方式 result=[str1 substringWithRange:NSMakeRange(8,6)]; NSLog(@"第8到13个字符:%@",result);//第8到13个字符:String //查找子串 range=[str1 rangeOfString:@"String"]; NSLog(@"String子串位置%lu,长度是%lu",range.location,range.length);//String子串位置8,长度是6 //查找不存在的子串 range=[str1 rangeOfString:@"StringA"]; if(range.location==NSNotFound){ NSLog(@"未找到子串StringA");//√ }else{ NSLog(@"子串StringA位置为%lu",range.location); } } } 3.可变字符串NSMutableString NSMutalbleString是NSString的子类,用来创建可以更改字符的字符串对象。 NSMutableString常用方法: insertString:atIndex :在指定位置插入字符串; appendString: 在字符串结尾插入字符串; deleteCharactersInRange:删除字符串中指定数目的字符。 setString:直接设置可变字符串对象的内容; int main(int argc, const char * argv[]) { @autoreleasepool { NSString *str=@"This is String A"; NSMutableString *mstr; NSRange substr; mstr=[NSMutableString stringWithString:str]; NSLog(@"%@",mstr);//This is String A //插入字符 [mstr insertString:@" mutable" atIndex:7]; NSLog(@"%@",mstr);//This is mutable String A //追加字符 [mstr appendString:@" and String B"]; NSLog(@"%@",mstr);//This is mutable String A and String B //删除子串 [mstr deleteCharactersInRange:NSMakeRange(16, 8)]; NSLog(@"%@",mstr);//This is mutable and String B //查找子串并删除 substr=[mstr rangeOfString:@"and String B"]; if(substr.location!=NSNotFound){ [mstr deleteCharactersInRange:substr]; NSLog(@"%@",mstr);//This is mutable } //直接设置可变字符串内容 [mstr setString:@"This is String."]; NSLog(@"%@",mstr);//This is String. //替换子串 [mstr replaceCharactersInRange:NSMakeRange(7, 1) withString:@" mutable "]; NSLog(@"%@",mstr);//This is mutable String. 本文转自 陈敬(Cathy) 博客园博客,原文链接:http://www.cnblogs.com/janes/p/5467215.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

《从零开始学Swift》学习笔记(Day 29)——访问级别

访问级别: Swift提供了3种不同访问级别,对应的访问修饰符为:public、internal和private。这些访问修饰符可以修饰类、结构体、枚举等面向对象的类型,还可以修饰变量、常量、下标、元组、函数、属性等内容。 public。可以访问自己模块中的任何public实体。如果使用import语句引入其他模块,我们可以访问其他模块中的public实体。 internal。只能访问自己模块的任何internal实体,不能访问其他模块中的internal实体。internal可以省略,换句话说,默认访问限定是internal。 private。只能在当前源文件中使用的实体,称为私有实体。使用private修饰,可以用作隐藏某些功能的实现细节。 使用访问修饰符的示例代码如下: 1 2 3 4 5 6 7 public class PublicClass{} internalclassInternalClass{} private class PrivateClass{} public varintPublicVariable= 0 letintInternalConstant= 0 private funcintPrivateFunction(){} 使用最佳访问级别: 由于中Swift中访问限定符能够修饰的实体很多,使用起来比较繁琐,下面我们给出一些最佳实践。 1.统一性原则 原则1:如果一个类型(类、结构体、枚举)定义为internal或private,那么类型声明的变量或常量不能使用public访问级别。因为public的变量或常量可以被任何人访问,而internal或private的类型不可以。 原则2:函数的访问级别不能高于它的参数和返回类型(类、结构体、枚举)的访问级别。假设函数声明为public级别,而参数或者返回类型声明为internal或private,就会出现函数可以被任何人访问,而它的参数和返回类型不可以访问的矛盾情况。 2.设计原则 如果我们编写的是应用程序,应用程序包中的所有Swift文件和其中定义的实体,都是供本应用使用的,而不是提供其他模块使用,那么我们就不用设置访问级别了,即使用默认的访问级别。 如果我们开发的是框架,框架编译的文件不能独立运行,因此它天生就是给别人使用的,这种情况下我们要详细设计其中的Swift文件和实体的访问级别,让别人使用的可以设定为public,不想让别人看到的可以设定为internal或private。 3.元组类型的访问级别 元组类型的访问级别遵循元组中字段最低级的访问级别,例如下面的代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 private class Employee{ varno:Int= 0 varname:String= "" varjob:String? varsalary:Double= 0 vardept:Department? } structDepartment{ varno:Int= 0 varname:String= "" } private letemp=Employee() vardept=Department() private varstudent1=(dept,emp)① 4.枚举类型的访问级别 枚举中成员的访问级别继承自该枚举,因此我们不能为枚举中的成员指定访问级别。示例代码如下: 1 2 3 4 5 6 7 public enum WeekDays{ case Monday case Tuesday case Wednesday case Thursday case Friday } 由于WeekDays枚举类型是public访问级别,因而它的成员也是public级别。 本文转自 tony关东升 51CTO博客,原文链接:http://blog.51cto.com/tonyguan/1746589,如需转载请自行联系原作者

优秀的个人博客,低调大师

《从零开始学Swift》学习笔记(Day 32)——计算属性

计算属性本身不存储数据,而是从其他存储属性中计算得到数据。 计算属性概念: 计算属性提供了一个getter(取值访问器)来获取值,以及一个可选的setter(设置访问器)来间接设置其他属性或变量的值。计算属性的语法格式如下: 1 2 3 4 5 6 7 8 9 10 11 12 面向对象类型类型名{ 存储属性 ...... var计算属性名:属性数据类型{ get{ return 计算后属性值 } set(新属性值){ ...... } } } 定义计算属性比较麻烦,要注意后面的几个大括号的对齐关系。 我们先看一个示例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 import Foundation class Employee{ varno:Int= 0 varfirstName:String= "Tony" //存储属性 varlastName:String= "Guan" //存储属性 varjob:String? varsalary:Double= 0 lazyvardept:Department=Department() varfullName:String{ //计算属性 get{ return firstName+ "." +lastName //返回拼接的结果 } set(newFullName){ //存储传递进来的参数值 varname=newFullName.componentsSeparatedByString( "." ) firstName=name[ 0 ] lastName=name[ 1 ] } } } structDepartment{ letno:Int= 0 varname:String= "" } varemp=Employee() print(emp.fullName) //取出属性值 emp.fullName= "Tom.Guan" //给属性赋值 print(emp.fullName) 只读计算属性: 计算属性可以只有getter访问器,没有setter访问器,这就是只读计算属性。指定计算属性不仅不用写setter访问器,而且get{}代码也可以省略。与上一节相比,代码将大大减少。修改上一节示例为只读计算属性,代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Employee{ varno:Int= 0 varfirstName:String= "Tony" varlastName:String= "Guan" varjob:String? varsalary:Double= 0 lazyvardept:Department=Department() varfullName:String{ //简洁的setter访问器 return firstName+ "." +lastName } } structDepartment{ letno:Int= 0 varname:String= "" } varemp=Employee() print(emp.fullName) 只读计算属性不能够赋值,下列语句是错误的。 1 emp.fullName= "Tom.Guan" 本文转自 tony关东升 51CTO博客,原文链接:http://blog.51cto.com/tonyguan/1746597,如需转载请自行联系原作者

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册