
第一章 java技术入门
1练习环境变量的设置,如果出现问题,试分析其原因并更正。
2编写HelloWorld程序,并编译执行。
3在屏幕上打印出一下图形。
Java程序设计
4编辑、编译、运行以下程序,说出程序的功能。改变变量n的初值,观察运行结果。
public class Sum10_for
{
public static void main(String[] args)
{
int i=1,n=10,s=0;
Systemoutprint("Sum("+n+")=");
for(i=1;i<n;i++)
{
s+=i;
Systemoutprint(i+"+");
}
Systemoutprintln(i+"="+(s+i));
}
}
第二章 面向对象程序设计
1创建一个带缺省构造方法的类,在构造方法中打印一条信息。为这个类创建一个对象
2设计一个银行账户类,成员变量包括账号、储户姓名、开户时间、身份z号码、存款余额等账户信息,成员方法包括存款、取款等 *** 作。
//3定义一个点对象。
4编写并测试一个代表地址的Address类,地址信息由国家、省份、城市、街道、邮编组成,并可以返回完整的地址信息。
5定义并测试一个代表员工的Employee类。员工属性包括编号、姓名、基本薪水,还包括获取这些属性的方法。
6创建一个Dog类,有名字、颜色、年龄等属性,定义构造方法来初始化类的这些属性,定义方法输出Dog信息,编写应用程序使用Dog类。
第四章 运算符、表达式和流程控制
1测试++运算符。问:当a=1时,如下表达式:(++a)+(++a)+(++a);(a++)+(a++)+(a++);(++a)+(a++)+(++a)+(a++)的值分别是多少。
2写一个打印从1到100值的程序
3编写一个程序,求三个数中的最大值。
4求1~1000之间可以同时被3、5、7整除的数字。
5利用条件运算符的嵌套来完成此题:学习成绩>=90分的同学用A表示,60-89分之间的用B表示,60分以下的用C表示。
程序分析:(a>b)a:b这是条件运算符的基本例子。
6利用递归方法求5!。
第五章 数组
1定义一个由整数组成的数组,要求求出其中的奇数个数和偶数个数。
2现在有如下的一个数组:
int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5};
要求将不为0的值存入一个新数组。
3定义一个整型数组,求出数组元素的和、数组的最大值和最小值,并输出。
4设级数Sn定义为:S0=0,S1=1,Sn=Sn-1+2Sn-2(n>=2),将前10个Sn数放入数组中。
5打印出二维数组中元素的最大值,及其行、列位置。
第六章 面向对象编程进阶
1设计一个表示用户的User类,类中的变量有用户名、口令等,定义类的三个构造方法(无参、为用户名赋值、为用户名和口令赋值),并设计获取和设置口令的方法和返回类信息的方法。
2创建一个名为Dog的类,具有重载的bark()方法。此方法应根据不同的基本数据类型进行重载,并根据被调用的版本,打印出不同类型的狗的叫声。编写main()来调用所有不同版本的方法。
3编写具有两个方法的类,在第一个方法内调用第二个方法两次:第一次调用不使用this,第二次调用时使用this。
4编写具有两个重载构造方法的类,并在第一个构造方法中调用第二个构造方法。
5创建一个带有public,private,protected和包访问权限的成员变量以及成员方法的类。创建该类的一个对象,看看在你试图调用所有类成员时,会得到什么类型的编译信息。注意在同一目录中的所有类都是缺省包范围。
6(1)创建两个带有缺省构造器的类,A和B。从A中继承一个名为C的新类,并在C内创建一个B类的成员。不要给C编写构造器。创建一个C类的对象并观察其结果。
(2)对上述程序进行修改,使A和B含有带参数的构造器,以取代缺省的构造器。为C写一个构造器,并在其中执行所有初始化。
7证明基类构造器(a)总是被调用(b)在导出类构造器之前被调用
8创建一个仅有一个非缺省构造器的基类,并创建一个带有缺省构造器和非缺省构造器的导出类。在导出类的构造器中调用基类的构造器。
9(1)创建一个Root类,令其含有名为Component1、Component2、Component3的类各一个实例(这些也由你写)。从Root中派生一个类Stem,也含有上述各“组成部分”。所有的类都应带有打印出类的相关信息的缺省构造器。
(2)修改上述程序,使每个类都仅有非缺省的构造器。
10创建一个类,它应带有一个被重载了三次的方法。创建一个子类,并添加一个该方法的新的重载定义,展示着四个方法在子类中都可以使用。
11建立一个人类(Person)和学生类(Student),功能要求如下:
(1)Person中包含4个保护型的数据成员name、addr、sex、age,表示姓名、地址、性别和年龄。用一个4参构造方法、一个两参构造方法、一个无参构造方法、一个输出方法显示4种属性。
(2)Studeng类继承Person类,并增加输出成员math、english存放数学和英语成绩。用一个6参构造方法、一个两参构造方法、一个无参构造方法和重写输出方法用于显示6种属性。
11在包中编写一个类,你的类应具备一个protected方法。在包外部,试着调用该protected方法并解释此结果。然后,从你的类中派生一个导出类,并从该导出类的一个方法内部调用该protected方法。
12(1)创建一个名为Amphibian的类。由此派生出一个被称为Frog的类。在基类中设置适当的方法。在main()中,编写一个Frog并向上转型至Amphibian,然后说明所有方法都可工作。
(2)修改上述程序,使Frog重载基类中方法的定义,并重新调用,观察现象。
13声明一个图书类,其数据成员为书名、编号(利用静态变量实现自动编号)、书价,并拥有静态数据成员册数,记录图书的总册数,在构造方法中利用此静态变量为对象的编号赋值,在主方法中定义对象数组,并求出总册数。
14创建一个含有static final数据成员和final数据成员的类,说明二者间的区别。
15创建一个带有final数据成员的类。由此派生出一个类并重载此数据成员。
16创建一个包含两个方法的基类。在第一个方法中可以调用第二个方法。然后产生一个继承自该基类的导出类,且重载基类的第二个方法。为该导出类创建一个对象,向上转型到基类型并调用第一个方法,解释发生的情况。
第七章 高级类特性
1(1)创建一个Rodent(啮齿动物):Mouse(老鼠),Gerbil(鼹鼠),Hamster(大颊鼠)这样的继承层次结构。在基类中,提供对所有的Rodent都通用的方 法,在基类中,根据特定的Rodent类型重载这些方法,以便执行不同的行为。(2)修改上述程序,使Rodent成为一个抽象类。只要有可能,就将Rodent的方法声明为抽象方法。
2创建一个基类,包含抽象方法print(),并在导出类中将其重载。重载的版本中会打印基类中定义的某个整型变量的值。在定义该变量时,请赋予非零值。在基类的构造器中,可以调用这个方法。现在,在main()方法中,创建一个导出类对象,然后调用它的print()方法。解释发生的情形。
3创建一个不包含任何方法的抽象类,从它那里导出一个子类,并添加一个方法。在测试类中创建一个静态方法,可以接受一个指向基类的引用,将其向下转型到导出类,然后再调用该静态方法。在main()方法中,证实它的可行性。
4定义类Shape,用来表示一般二维图形。Shape具有抽象方法area和perimeter,分别用来计算形状的面积和周长。试定义一些二维形状类(如矩形、三角形、圆形等),这些类均为Shape类的子类。
4在某个包中创建一个接口,内含三个方法,然后在另一个包中实现此接口。
5创建三个接口,使之各有两个方法。再创建一个新的接口,继承三者,并添加一个新方法。然后创建一个类,在实现此新接口的同时,继承一个实际的类。并为这个类写四个方法,每个方法分别以四个接口中的一个作为参数。在main()中,创建这个类的对象,然后将它作为参数传递给那四个方法。
6在第一个包中创建至少有一个方法的接口。然后在第二个包内创建一个类,在其中增加一个protected的内部类以实现那个接口。在第三个包中,继承这个类,并在一个方法中返回该内部类的对象,在返回的时候向上转型为第一个包中的接口类型。
7创建一个至少有一个方法的接口。在某个方法内定义一个内部类,以实现此接口,这个方法返回此接口的引用。
8创建一个private内部类,实现一个public接口。写一个方法,它返回一个指向此private内部类的实例的引用,并将此引用向上转型为该接口类型。通过尝试向下转型,说明此内部类被完全隐藏了。
9创建一个仅有非缺省构造器的类。再创建第二个类,它包含一个方法,能够返回第一个类的引用。通过写一个继承自第一个类的匿名内部类,而创建一个用以返回的对象。
10定义一个品牌电脑的枚举类,其中只有固定的几个电脑品牌。
11定义一个Person类,其中包含姓名、年龄、生日、性别等属性,其中性别只能 是男或女。
第八章 异常处理
1编写一个类,在main()的try块里抛出一个Exception对象。传递一个字符串参数给Exception的构造器。在catch子句里捕获此异常对象,并且打印字符串参数。添加一个finally子句,打印一条信息以证明这里确实得到了执行。
//2使用extends关键字建立一个自定义异常类。为这个类写一个接受字符串参数的构造器,把此参数保存在对象内部的字符串引用中。写一个方法打印此字符串。写一个try-catch子句,对这个异常进行测试。
3为一个类定义两个方法,f()和g()。在g()里,抛出一个泥定义的新异常。在f()里,调用g(),捕获它抛出的异常,并且在catch子句里抛出RuntimeException。在main()方法里测试你的代码。
第九章 精通常用的java类
1计算字符串中子串出现的次数
2写一个接收两个字符串的方法,判断两个字符串是否相等,做==的同时,用eques做测试,在main()里面用不同的字符串做测试,并打印结果。
3写一个会随机生成25个整型值的程序。对每一个只,用if-else语句判断其实大于、小于,还是等于下一个随机生成的数。
4统计一个字符串中单词的个数。设单词之间用一个或多个空格分隔,该字符串只由字母与空格组成。
5输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。
6编写程序,统计出字符串“want you to know one thing“中字母n和字母o
的出现次数。
7字符串 *** 作:
(1)从字符串“Java技术学习班20091211”中提取开班日期。
(2)将“IBM JAVA学习班”中的字符串JAVA替换为“J2SE”。
(3)取出“JAVA技术学习班20091211”中的第八个字符。
(4)清除“JAVA技术学习班20091211”中的所有的0
(5)清除“JAVA 技术学习班 学生 信息”中的所有空格。
8定义一个StringBuffer类对象,然后通过append()方法向对象中添加26个小写字母,要求每次只添加一次,共添加26次,然后按照逆序的方式输出,并且可以删除前五个字符。
9输入一个Email地址,然后使用正则表达式验证该Email地址是否正确。
10编写程序,用0~1之间的随机数来模拟扔硬币试验,统计扔1000次后出现正反面次数并输出。
11编写正则表达式,判断给定的是否是一个合法的IP地址。
第十一章 集合与映射
1(1)创建一个新类Gerbil(沙鼠),包含int gerbilNumber,在构造器中初始化它。添加一个方法hop(),用以打印gerbil的号码。创建一个ArrayList,并向其中添加一串Gerbil对象。使用get()遍历List,并且对每个Gerbil调用hop()
(2)修改上述程序,使用Iterator遍历List,并调用hop()。
2使用上述中的Gerbil类,将其放入Map中,将Gerbil的名字String(键)与每个Gerbil(值)关联起来。有keySet()获取Iterator,使用它遍历Map,针对每个"键"查询Gerbil,然后打印出"键",并调用hop()。
3创建一个新容器,用private ArrayList来保存对象。用Class reference来判断容器中的第一个对象的类型,然后只允许用户插入此类型的对象。
4用String数组创建一个只能存取String的容器,这样使用的时候就没有类型转换的问题了。当容器发现数组不够大的时候,应该能够自动调整其内部数组的容量。
//5创建一个包括两个String对象的类,然后做一个只比较第一个字符串的Comparable。产生多个对象并存入ArrayList。验证一下,排序能否正常工作。再做一个只比较第二个String的Comparator,然后验证一下,排序是否正常
6写一个类,在其中创建一个已经初始化的对象数组。使用此数组填充List。使用subList()生成此List的子集,然后使用removeAll()将子集从List中移除。
7创建自己的容器,使它只能容纳特定类型的对象。
8编写学生类,该类定义了3个属性:学号、姓名、成绩。可以通过构造方法设
置3个属性的值,并覆写Object类的toString()放法,在List集合中加入5
个学生对象,并将内容输出,之后使用比较器将对象的内容进行排序并显示在屏幕上。
public static List<List<string>> GetList(List<string> list)
{
List<List<string>> _result = new List<List<string>>();
List<string> _use;
int beginIndex = 0;
int count = listCount;
int i = 0;
while (i < count)
{
_use = new List<string>();
_useAdd(list[beginIndex]);
for (i = beginIndex + 1; i < listCount; i++)
{
if (ConvertToInt32(list[i]) - ConvertToInt32(list[i - 1]) == 1)//你说的连续就是两个值相差1吧?不是就自己改差值
_useAdd(list[i]);
else
{
_resultAdd(_use);
beginIndex = i;
break;
}
}
}
return _result;
}
前言
本文目录
Scala字符串 Scala 集合 1 数组 2 list 3 set 4 Map 42 map遍历 方式一: foreach 方式二: 迭代器 方式三: for循环 5 元组 trait特性 模式匹配match-case 并发 Actor Model Actor的特征: Actor与Actor之间通信: Scala隐式转换系统 隐式值 隐式视图 隐式类
Scala字符串
Scala中字符串也是分为两种: 可变长度的StringBuilder和不可变长度的String, 其 *** 作用法与Java几乎一致
接下来, 通过代码来查看常用方法:
//定义字符串 val str1 = "Hello Scala" var str2 = "Hello Scala" var str2_1 = "hello scala" //字符串比较 println(str1 == str2) println(str1equals(str2)) println(str1equalsIgnoreCase(str2_1)) //上述三个比较全部返回true //按字典顺序比较两个字符串 println(str1compareTo(str3)) //按字典顺序比较两个字符串,不考虑大小写 println(str1compareToIgnoreCase(str3)) //从0开始返回指定位置的字符 println(str1charAt(6)) //追加 println(str2concat(" Language")) //是否以指定的后缀结束 println(str1endsWith("la")) //使用默认字符集将String编码为 byte 序列 println(str1getBytes) //哈希码 println(str1hashCode) //指定子字符串在此字符串中第一次出现处的索引 println(str1indexOf("ca")) //字符串对象的规范化表示形式 println(str1intern()) //指定子字符串在此字符串中最后一次出现处的索引 println(str1lastIndexOf("al")) //长度 println(str1length) //匹配正则表达式 println(str1matches("d+")) //替换字符 println(str1replace('a','o')) //根据字符切割, 需要注意Scala中从数组中取元素使用小括号 println(str1split(" ")(1)) //是否以指定字符串开始 println(str1startsWith("Hel")) //截取子字符串 println(str1substring(3)) println(str1substring(3,7)) //大小写 println(str1toLowerCase()) println(str1toUpperCase()) //去空格 println(str1trim) //使用StringBuilder val strBuilder = new StringBuilder //拼接字符串 strBuilderappend("Hello ") strBuilderappend("Scala") println(strBuilder) //反转 println(strBuilderreverse) //返回容量 println(strBuildercapacity) //指定位置插入 println(strBuilderinsert(6,"Spark "))
Scala 集合
1 数组
Java中使用 new String[10]的形式可以创建数组, 但Scala中创建数组需要用到Array关键词, 用[ ]指定数组中元素的泛型, 取值使用小括号(index)
//创建Int类型的数组, 默认值为0 val nums = new Array[Int](10) //创建String类型的数组, 默认值为null val strs = new Array[String](10) //创建Boolean类型的数组, 默认值为false val bools = new Array[Boolean](10) //通过索引遍历数组,给元素赋值 for (index <- 0 until numslength) nums(index) = index + 1 //数组遍历,编码的逐步简化 numsforeach ( (x: Int) => print(x + " ") ) println() numsforeach ( (x => print(x + " ")) ) println() numsforeach(print(_)) println() numsforeach(print)
foreach函数传入一个函数参数, 由于Scala支持类型推测, 可以将参数函数的参数类型省略; 在参数函数中, 该函数的参数只出现一次, 因为可以使用下划线_代替(如果有多个可以使用_1/_2); 最后由于Scala语言的灵活性, 只需传入print这个函数也会遍历打印整个集合
创建二维数组分两步: 创建一个泛型为数组的数组, 然后对这个数组遍历,
val secArray = new Array[Array[String]](5) for (index <- 0 until secArraylength){ secArray(index) = new Array[String](5) } //填充数据 for (i <- 0 until secArraylength;j <- 0 until secArray(i)length) { secArray(i)(j) = i j + "" } secArrayforeach(array => arrayforeach(println))
2 list
Scala中列表的定义使用List关键词 List集合是一个不可变的集合 下面来看创建List已经list调用的方法
//创建列表 val list = List(1,2,3,4,5) //对列表遍历 listforeach(println) //contains判断是否包含某个元素 println(listcontains(6)) //反序,返回一个新的List listreverseforeach(println) //去前n个元素,返回一个新的List listtake(3)foreach(println) //删除前n个元素,返回一个新的List listdrop(2)foreach(println) //判断集合中是否有元素满足判断条件 println(listexists(_ > 4)) //把List中的元素用设置的字符(串)进行拼接 listmkString("==")foreach(print) /map是一个高阶函数,需要一个函数参数 返回值是That,意思是谁调用的map返回的类型跟调用map方法的对象的类型一致 这里map返回的仍然是list,因此在map中可对每一个元素进行相同 *** 作 map返回的list的泛型由编码传入的函数返回类型决定,如下(_ 100)返回的list的泛型就是Int / listmap(println) listmap(_ 100)foreach(println) val logList = List("Hello Scala" , "Hello Spark") /由上述介绍可知,split()返回一个数组,因此map返回的类型是泛型为数组类型的list 需要对返回的list进行两次遍历,第一次遍历得到Array,第二次遍历拿到String / logListmap(_split(" "))foreach(_foreach(println)) / 如果想直接拿到String,需要: 扁平 *** 作 用到的函数是flatMap,flatMap返回的类型也是调用该方法的类型,但它可以直接得到String类型的单词 / logListflatMap(_split(" "))foreach(println) 对map和flatMap的理解可参考下图: Nil创建一个空List Nilforeach(println) //:: *** 作可用来添加元素 val list1 = 1::2::Nil list1foreach(println) 需要注意的是, 上述创建的list均为不可变长度的list, 即list中的元素只有在创建时才能添加 创建可变长度的list, 需要用到ListBuffer, 看代码: //创建一个ListBuffer,需要导包scalacollectionmutableListBuffer val listBuffer = new ListBuffer[String] //使用+=添加元素 listBuffer+=("hello") listBuffer+=("Scala") listBufferforeach(println) //使用-=去除元素 listBuffer-=("hello")
3 set
Scala中使用Set关键词定义无重复项的集合
Set常用方法展示:
//创建Set集合,Scala中会自动去除重复的元素 val set1 = Set(1,1,1,2,2,3) //遍历Set即可使用foreach也可使用for循环 set1foreach(x => print( x + "\t")) val set2 = Set(1,2,3,5,7) //求两个集合的交集 set1intersect(set2)foreach(println) set1&(set2)foreach(println) //求差集 set2diff(set1)foreach(println) set2&~(set1)foreach(println) //求子集,如果set1中包含set2,则返回true注意是set1包含set2返回true println(set2subsetOf(set1)) //求最大值 println(set1max) //求最小值 println(set1min) //转成List类型 set1toListmap(println) //转成字符串类型 set1mkString("-")foreach(print)
4 Map
Scala中使用Map关键字创建KV键值对格式的数据类型
41 创建map集合
val map = Map( "1" -> "Hello", 2 -> "Scala", 3 -> "Spark" )
创建Map时, 使用->来分隔key和value, KV类型可不相同, 中间使用逗号进行分隔
42 map遍历
遍历map有三种方式, 即可使用foreach, 也可使用与Java中相同用法的迭代器, 还可使用for循环
方式一: foreach
mapforeach(println)
此时, 打印的是一个个二元组类型的数据, 关于元组我们后文中会详细介绍, 此处只展示一下二元组的样子: (1,Hello); (2,Scala); (3,Spark)
方式二: 迭代器
val keyIterator = mapkeysiterator while (keyIteratorhasNext){ val key = keyIteratornext() println(key + "--" + mapget(key)get) }
此时需注意:
mapget(key)返回值, 返回提示:
an option value containing the value associated with key in this map, or None if none exists
即返回的是一个Option类型的对象, 如果能够获取到值, 则返回的是一个Some(Option的子类)类型的数据, 例如打印会输出Some(Hello), 再通过get方法就可以获取到其值;
如果没有值会返回一个None(Option的子类)类型的数据, 该类型不能使用get方法获取值(本来就无值, 强行取值当然要出异常)
看get方法的提示(如下), 元素必须存在, 否则抛出NoSuchElementException的异常
Returns the option's value Note: The option must be nonEmpty
Throws:
PredefNoSuchElementException - if the option is empty
既然这样, 对于None类型的数据就不能使用get了, 而是使用getOrElse(“default”)方法, 该方法会先去map集合中查找数据, 如果找不到会返回参数中设置的默认值 例如,
//在上述map定义的情况下执行下述代码,会在终端打印default
println(mapget(4)getOrElse("default"))
1
2
方式三: for循环
for(k <- map) println(k_1 + "--" + k_2)
此处, 将map中的每一对KV以二元组(1, Hello)的形式赋给k这一循环变量 可通过k_1来获取第一个位置的值, k_2获取第二个位置的值
43 Map合并
//合并map val map1 = Map( (1,"a"), (2,"b"), (3,"c") ) val map2 = Map( (1,"aa"), (2,"bb"), (2,90), (4,22), (4,"dd") )
map1++:(map2)foreach(println)
++和++:的区别
函数 调用 含义
++ map1++(map2) map1中加入map2
++: map1++:(map2) map2中加入map1
注意:map在合并时会将相同key的value替换
44 Map其他常见方法
//filter过滤,虑去不符合条件的记录 mapfilter(x => { IntegerparseInt(x_1 + "") >= 2 })foreach(println) //count对符合条件的记录计数 val count = mapcount(x => { IntegerparseInt(x_1 + "") >= 2 }) println(count); / 对于filter和count中条件设置使用IntegerparseInt(x_1 + "")是因为: 定义map时,第一个key使用的是String类型,但在传入函数时每一个KV转化为一个二元组(Any,String)类型,x_1获取Any类型的值,+""将Any转化为String,最后再获取Int值进行判断 / //contains判断是否包含某个key println(mapcontains(2)) //exist判断是否包含符合条件的记录 println(mapexists(x =>{ x_2equals("Scala") }))
5 元组
元组是Scala中很特殊的一种集合, 可以创建二元组, 三元组, 四元组等等, 所有元组都是由一对小括号包裹, 元素之间使用逗号分隔
元组与List的区别: list创建时如果指定好泛型, 那么list中的元素必须是这个泛型的元素; 元组创建后, 可以包含任意类型的元素
创建元组即可使用关键字Tuple, 也可直接用小括号创建, 可以加 “new” 关键字, 也可不加 取值时使用 "tuple_XX"获取元组中的值
元组的创建和使用
//创建元组 val tuple = new Tuple1(1) val tuple2 = Tuple2("zhangsan",2) val tuple3 = Tuple3(1,20,true) val tuple4 = (1,2,3,4) val tuple18 = (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18) //注意:使用Tuple关键字最多支持22个元素 val tuple22 = Tuple22(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22) //使用 println(tuple2_1 + "\t" + tuple2_2) //元组中嵌套元组 val t = Tuple2((1,2),("zhangsan","lisi")) println(t_1_2) 元组的遍历 //tupleproductIterator可以得到迭代器, 然后用来遍历 val tupleIterator = tuple22productIterator while(tupleIteratorhasNext){ println(tupleIteratornext()) } toString, swap方法 //toString, 将元组中的所有元素拼接成一个字符串 println(tuple3toString()) //swap翻转,只对二元组有效 println(tuple2swap)
trait特性
Scala中的trait特性相对于Java而言就是接口 虽然从功能上两者极其相似, 但trait比接口还要强大许多: trait中可以定义属性和方法的实现, 这点又有点像抽象类; Scala的类可以支持继承多个trait, 从结果来看即实现多继承
Scala中定义trait特性与类相似, 不同在于需要使用"trait"关键字 其他注意点在代码注释中做出说明:
trait Read { val readType = "Read" val gender = "m" //实现trait中方法 def read(name:String){ println(name+" is reading") } } trait Listen { val listenType = "Listen" val gender = "m" //实现trait中方法 def listen(name:String){ println(name + " is listenning") } } //继承trait使用extends关键字,多个trait之间使用with连接 class Person extends Read with Listen{ //继承多个trait时,如果有同名方法或属性,必须使用“override”重新定义 override val gender = "f" } object test { def main(args: Array[String]): Unit = { val person = new Person() personread("zhangsan") personlisten("lisi") println(personlistenType) println(personreadType) println(persongender) } } object Lesson_Trait2 { def main(args: Array[String]): Unit = { val p1 = new Point(1,2) val p2 = new Point(1,3) println(p1isEqule(p2)) println(p1isNotEqule(p2)) } } trait Equle{ //不实现trait中方法 def isEqule(x:Any) :Boolean //实现trait中方法 def isNotEqule(x : Any) = { !isEqule(x) } } class Point(x:Int, y:Int) extends Equle { val xx = x val yy = y def isEqule(p:Any) = { / isInstanceOf:判断是否为指定类型 asInstanceOf:转换为指定类型 / pisInstanceOf[Point] && pasInstanceOf[Point]xx==xx } }
模式匹配match-case
Scala中的模式匹配match-case就相当于Java中的switch-case Scala 提供强大的模式匹配机制, 即可匹配值又可匹配类型 一个模式匹配包含一系列备选项, 每个备选项都以case关键字开始 并且每个备选项都包含了一个模式以及一到多个表达式, 箭头符号 => 隔开了模式和表达式。
object Lesson_Match { def main(args: Array[String]): Unit = { val tuple = Tuple7(1,2,3f,4,"abc",55d,true) val tupleIterator = tupleproductIterator while(tupleIteratorhasNext){ matchTest(tupleIteratornext()) } } / 注意 1模式匹配不仅可以匹配值,还可以匹配类型 2模式匹配中,如果匹配到对应的类型或值,就不再继续往下匹配 3模式匹配中,都匹配不上时,会匹配到case _ ,相当于default / def matchTest(x:Any) ={ x match { //匹配值 case 1 => println("result is 1") case 2 => println("result is 2") case 3 => println("result is 3") //匹配类型 case x:Int => println("type is Int") case x:String => println("type is String") case x :Double => println("type is Double") case _ => println("no match") } } }
由于匹配到对应的类型或值时, 就不再继续往下匹配, 所有在编写备选项时要将范围小的放在前面, 否则就会失去意义 这就类似于try-catch中处理异常时, 也要先从小范围开始
样例类case classes
使用case关键字定义的类就是样例类(case classes), 样例类实现类构造参数的getter方法 (构造参数默认被声明为val) , 当构造参数类型声明为var时, 样例类会实现参数的setter和getter方法
样例类默认实现toString, equals, copy和hashCode等方法 样例类在创建对象时可new, 也可不new
//使用case关键字定义样例类 case class Person(name:String, age:Int) object Lesson_CaseClass { def main(args: Array[String]): Unit = { //创建样例类对象,可new可不new val p1 = new Person("zhangsan",18) val p2 = Person("lisi",20) val p3 = Person("wangwu",22) val list = List(p1,p2,p3) listforeach { x => { x match { case Person("zhangsan",18) => println("zhs") case Person("lisi",20) => println("lisi") case p:Person => println("is a person") case _ => println("no match") } } } } }
并发 Actor Model
Actor Model相当于Java中的Thread, Actor Model用来编写并行计算或分布式系统的高层次抽象 Actor不需要担心多线程模式下共享锁的问题, 可用性极高
Actors将状态和行为封装在一个轻量级的进程/线程中, 但它不和其他Actors分享状态, 每个Actors有自己的世界观, 当需要和其他Actors交互时, 通过发送异步的, 非堵塞的(fire-and-forget)事件和消息来交互 发送消息后不必等另外Actors回复, 也不必暂停, 每个Actors有自己的消息队列, 进来的消息按先来后到排列, 这就有很好的并发策略和可伸缩性, 可以建立性能良好的事件驱动系统
Actor的特征:
ActorModel是消息传递模型,基本特征就是消息传递
消息发送是异步的,非阻塞的
消息一旦发送成功,不能修改 (类似发邮件)
Actor之间传递时,自己决定决定去检查消息,而不是一直等待,是异步非阻塞的
定义Actor需要继承Actor这一trait, 实现act这一方法, 并且使用感叹号! 来发送消息
一个简单实例:
import scalaactorsActor //自定义Actor class myActor extends Actor{ def act(){ while(true){ receive { case x:String => println("save String ="+ x) case x:Int => println("save Int") case _ => println("save default") } } } } object Lesson_Actor { def main(args: Array[String]): Unit = { //创建actor的消息接收和传递 val actor =new myActor() //启动 actorstart() //发送消息写法 actor ! "Hello Scala Actor !" } }
Actor与Actor之间通信:
//创建样例类,用来发送 case class Message(actor:Actor,msg:Any) class Actor1 extends Actor{ def act(){ while(true){ //对接收的消息进行模式匹配 receive{ case msg :Message => { println("i sava msg! = "+ msgmsg) //回复消息 msgactor!"i love you too !" } case msg :String => println(msg) case _ => println("default msg!") } } } } //为了实现Actor中的通信,需要拿到另一个Actor的对象 class Actor2(actor :Actor) extends Actor{ //发送消息 actor ! Message(this,"i love you !") def act(){ while(true){ receive{ case msg :String => { if(msgequals("i love you too !")){ println(msg) actor! "could we have a date !" } } case _ => println("default msg!") } } } } object Lesson_Actor2 { def main(args: Array[String]): Unit = { val actor1 = new Actor1() actor1start() val actor2 = new Actor2(actor1) actor2start() } }
Scala隐式转换系统
隐式转换是指在编写程序时, 尽量少的去编写代码, 让编译器去尝试在编译期间自动推导出某些信息来, 这就类似于在Scala中定义变量时不需要指定变量类型 这种特性可以极大的减少代码量, 提高代码质量
Scala中提供强大的隐式转换系统, 分别为: 隐式值, 隐式视图和隐式类
隐式值
先来看一个隐式值的Demo:
object Lesson_Implicit1 { def main(args: Array[String]): Unit = { implicit val name = "Scala Study" sayName } def sayName(implicit name:String) = { println("say love to " + name) } }
这里将name变量声明为implicit, 编译器在执行sayName方法时发现缺少一个String类型的参数, 此时会搜索作用域内类型为String的隐式值, 并将搜索到的隐式值作为sayName的参数值进行传递
需要注意:
隐式转换必须满足无歧义规则, 否则会报错:
ambiguous implicit values: both value a of type String and value name of type String match expected type String
在同一个作用域禁止声明两个类型一致的变量,防止在搜索的时候会犹豫不决
声明隐式参数的类型最好是自定义的数据类型,一般不要使用Int,String这些常用类型,防止碰巧冲突
隐式视图
隐式视图就是把一种类型自动转换为另一种类型 还是先来看代码:
object Lesson_Implicit2 { def main(args: Array[String]): Unit = { //声明隐式视图 implicit def stringToInt(num:String) = IntegerparseInt(num) println(addNum("1000")) } def addNum(num:Int) = { num + 1000 } }
这里addNum方法参数是String类型, 不符合定义要求, 此时编译器搜索作用域发现有个隐式方法, 正好这个方法的参数是String, 返回是Int 然后就会调用这个隐式方法, 返回一个Int值并将它传给addNum方法
隐式类
隐式类是指把一个对象自动转换为另一种类型的对象, 转换后可以调用原来不存在的方法
package comqbscala object Lesson_Implicit3 { def main(args: Array[String]): Unit = { //导入隐式类所在的包 import comqbscalaUtilStringLength println("qwer"getLength()) } } object Util { //定义一个隐式类,使用implicit关键字修饰 implicit class StringLength(val s : String){ def getLength() = slength } }
这里编译器在qwer对象调用getLength方法时, 发现该对象并没有getLength方法, 此时编译器发现在作用域范围内有隐式实体 发现有符合的隐式类可以用来转换成带有getLength方法的Util类, 进而就可调用getLength方法
需要注意:
隐式类所带的构造参数有且只能有一个
必须在类, 伴生对象和包对象中定义隐式类
隐式类不能是case class(样例类), case class 在定义时会自动生成伴生对象
作用域中不能有与隐式类同名的标识符
感谢大家支持,之后会持续输出技术干货!
在jsp页面获取session里的list集合,步骤如下:
1首先新建一个DTO(对象传输模型),用来测试数据:
public class User{
private String name;
private String password;
private String email;
}
2生成它们的get,set方法
然后 在处理业务逻辑的类中 User user = new User()。
3从登录页拿到用户信息,通通传入这个User对象(username="小江";userpassword="1234"),这样,一个user对象就表示一个人的登录信息了。
再,List<User> list = new ArrayList<User>,把User对象放入list(listadd(user)),
最后,把list加入>
以上就是关于java 中的 方法 总是调来调去的 求高人发题 专练习调方法的练习题 下下了 越多越好全部的内容,包括:java 中的 方法 总是调来调去的 求高人发题 专练习调方法的练习题 下下了 越多越好、c# 如何分割连续的 List 整形 集合、如何证明,在n个元素组成的集合中取n+1个不同的三元子集,求证必有两个子集,它们恰有一个公共元等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)