6.1 常用对象
6.1.1 String、StringBuffer和StringBuilder
String类的特点:
字符串对象一旦被初始化就不会被改变。
示例1:
01. public class StringDemo{
02. public static void main(String[] args){
03. String s = "abc";
04. s = "nba";
05. System.out.println("s = " + s);
06. }
07. }
复制代码
运行结果:
原因分析:
"abc"字符串对象并没有被改变,只是引用变量s指向了新创建的字符串对象"nba"。
示例2:
01. public class StringDemo{
02. public static void main(String[] args){
03. String s1 = "abc";
04. String s2 = "abc";
05. System.out.println(s1 == s2);
06. }
07. }
复制代码
运行结果:
原因分析:
字符串创建的时候,有一个字符串常量池,s1创建后,"abc"放入其中。s2创建的时候,"abc"已经存
在于字符串常量池中,故引用变量s2直接指向了已经存在的"abc"字符串对象,故s1==s2。
示例3:
01. public class StringDemo{
02. public static void main(String[] args){
03. String s1 = "abc";
04. String s2 = new String("abc" );
05. System.out.println(s1 == s2);
06. }
07. }
复制代码
运行结果:
原因分析:
s1创建后,是在字符串常量池中创建了一个"abc"字符串对象。而s2是在堆内存中创建了另外一
个"abc"字符串对象。所以,两个对象不是同一个对象。
示例4:
01. public class StringDemo{
02. public static void main(String[] args){
03. String s1 = "abc";
04. String s2 = new String("abc" );
05. System.out.println(s1.equals(s2));
06. }
07. }
复制代码
运行结果:
原因分析:
String类复写了Object中的equals方法,建立了String类自己的判断字符串对象是否相同的依据。只
比较字符串内容,不比较地址。
String类的构造函数
构造函数:String(bytes[] bytes)
示例1:
01. public class StringConstructorDemo {
02. public static void main(String[] args){
03. StringConstructorDemo();
04. }
05.
06. public static void StringConstructorDemo(){
07. String s = new String();//等效于String s = "";不等效于String s = null;
08.
09. byte[] arr = {65,66,67,68};
10. String s1 = new String(arr);
11. System.out.println("s1 = " + s1);
12. }
13. }
复制代码
运行结果:
构造函数:String(bytes[] bytes)
示例2:
01. public class StringConstructorDemo {
02. public static void main(String[] args){
03. StringConstructorDemo();
04. }
05.
06. public static void StringConstructorDemo(){
07. char[] arr = {'w' ,'a' ,'p' ,'q' ,'x' };
08. String s = new String(arr);
09. System.out.println( "s = " + s);
10. }
11. }
复制代码
运行结果:
构造函数:String(bytes[] bytes)
示例3:
01. public class StringConstructorDemo{
02. public static void main(String[] args){
03. StringConstructorDemo();
04. }
05.
06. public static void StringConstructorDemo(){
07. char[] arr = {'w' ,'a' ,'p' ,'q' ,'x' };
08. String s = new String(arr,1,3);
09. System.out.println( "s = " + s);
10. }
11. }
复制代码
运行结果:
String类部分方法
1、获取
获取字符串中字符的个数(长度)
int length();
示例1:
01. public class StringMethodDemo {
02. public static void main(String[] args){
03. StringMethodDemo();
04. }
05.
06. public static void StringMethodDemo() {
07. String s = new String("abcde" );
08. System.out.println( "len = " + s.length());
09. }
10. }
复制代码
运行结果:
根据位置获取字符
char charAt(int index);
示例2:
01. public class StringMethodDemo{
02. public static void main(String[] args){
03. StringMethodDemo();
04. }
05.
06. public static void StringMethodDemo(){
07. String s = "abcde";
08. System.out.println( "char:" + s.charAt(2));
09. }
10. }
复制代码
运行结果:
根据字符获取在字符串中的位置
int indexOf(int ch);
indexO方法参数f类型为int是为了既可以支持字符,也可以支持字符在ASCII码中对应的数字。
从指定位置开始查找ch第一次出现的位置。
int indexOf(int ch,int fromIndex);
int indexOf(String str);
int indexOf(String str,int fromIndex);
根据字符串获取在字符串中第一次出现的位置。
int lastIndexOf(int ch);
int lastIndexOf(int ch,int fromIndex);
int lastIndexOf(String str);
int lastIndexOf(String str,int fromIndex);
示例3:
01. public class StringMethodDemo{
02. public static void main(String[] args){
03. StringMethodDemo();
04. }
05.
06. public static void StringMethodDemo(){
07. String s = "abcdae";
08. System.out.println( "index:" + s.indexOf('a' ));
09. System.out.println( "index:" + s.indexOf('k' ));
10. System.out.println( "lastIndex:" + s.lastIndexOf('a' ));
11. }
12. }
复制代码
运行结果:
P.S.
可以根据-1,来判断该字符或者字符串是否存在。
获取字符串中的一部分字符串,也叫子串。
String substring(int beginIndex,int endIndex);
String substring(int beginIndex);
示例4:
01. public class StringMethodDemo{
02. public static void main(String[] args){
03. StringMethodDemo();
04. }
05.
06. public static void StringMethodDemo(){
07. String s = "abcdae";
08. System.out.println( "substring:" + s.substring(2));
09. System.out.println( "substring:" + s.substring(2,4));
10. }
11. }
复制代码
运行结果:
2、转换
将字符串变成字符串数组(字符串的切割)
String[] split(String regex);涉及到正则表达式。
示例5:
01. public class StringMethodDemo {
02. public static void main(String[] args){
03. StringMethodDemo();
04. }
05.
06. public static void StringMethodDemo(){
07. String s = "张三,李四,王五" ;
08. String[] arr = s.split( ",");
09.
10. for(int i = 0; i < arr.length; i++){
11. System.out.println(arr[i]);
12. }
13. }
14. }
复制代码
运行结果:
示例6:
01. public class StringMethodDemo{
02. public static void main(String[] args){
03. StringMethodDemo();
04. }
05.
06. public static void StringMethodDemo(){
07. String s = "张三.李四.王五" ;
08. String[] arr = s.split( "\\.");
09.
10. for(int i = 0; i < arr.length; i++){
11. System.out.println(arr[i]);
12. }
13. }
14. }
复制代码
运行结果:
P.S.
点在正则表达式中是特殊符号,需要转义。
将字符串变成字符数组
char[] toCharArray();
示例7:
01. public class StringMethodDemo{
02. public static void main(String[] args){
03. StringMethodDemo();
04. }
05.
06. public static void StringMethodDemo(){
07. String s = "张三.李四.王五" ;
08. char[] chs = s.toCharArray();
09.
10. for(int i = 0; i < chs.length; i++){
11. System.out.println(chs[i]);
12. }
13. }
14. }
复制代码
运行结果:
将字符串变成字节数组
char[] getBytes();
示例8:
01. public class StringMethodDemo{
02. public static void main(String[] args){
03. StringMethodDemo();
04. }
05.
06. public static void StringMethodDemo(){
07. String s = "ab你" ;
08. byte [] bytes = s.getBytes();
09.
10. for (int i = 0; i < bytes.length; i++){
11. System.out.println(bytes[i]);
12. }
13. }
14. }
复制代码
运行结果:
将字符串中的字母转成大小写
String toUpperCase();大写
String toLowerCase();小写
示例9:
01. public class StringMethodDemo{
02. public static void main(String[] args){
03. StringMethodDemo();
04. }
05. 06. public static void StringMethodDemo(){
07. System.out.println( "Abc".toUpperCase());
08. }
09. }
复制代码
运行结果:
将字符串中的内容进行替换
String replace(char oldCh,char newCh);
String replace(String s1,String s2);
示例10:
01. public class StringMethodDemo{
02. public static void main(String[] args){
03. StringMethodDemo();
04. }
05.
06. public static void StringMethodDemo(){
07. String s1 = "java";
08. String s2 = s1.replace( 'a','o' );
09. String s3 = s1.replace( 'q','o' );
10.
11. System.out.println(s2);
12. System.out.println(s3);
13. System.out.println(s1 == s3);
14. }
15. }
复制代码
运行结果:
P.S.
replace方法如果没有找到要替换的内容,则返回的还是原字符串。
去除字符串两端空格
String trim();
示例11:
01. public class StringMethodDemo {
02. public static void main(String[] args){
03. StringMethodDemo();
04. }
05.
06. public static void StringMethodDemo(){
07. System.out.println( "-" + " ab c " .trim() + "-");
08. }
09. }
复制代码
运行结果:
将字符串进行连接
String concat(String str);
示例12:
01. public class StringMethodDemo{
02. public static void main(String[] args){
03. StringMethodDemo();
04. }
05.
06. public static void StringMethodDemo(){
07. System.out.println( "abc".concat("kk" ));
08. System.out.println( "abc" + "kk" );
09. }
10. }
复制代码
运行结果:
P.S.
concat效果与"+"连接符效果一致,但是效果更高一些。
将其他类型数据转换成字符串
示例13:
01. public class StringMethodDemo{
02. public static void main(String[] args){
03. StringMethodDemo();
04. }
05.
06. public static void StringMethodDemo(){
07. System.out.println(String.valueOf(4) + 1);
08. System.out.println( "" + 4 + 1);
09. }
10. }
复制代码
运行结果:
3、判断
两个字符串内容是否相同呢?
boolean equals(Object obj);
boolean equalsIgnoreCase(String str);忽略大小写比较字符串内容。
示例14:
01. public class StringMethodDemo {
02. public static void main(String[] args){
03. StringMethodDemo();
04. }
05.
06. public static void StringMethodDemo(){
07. String s = "abc";
08. System.out.println(s.equalsIgnoreCase("ABC" ));
09. }
10. }
复制代码
运行结果:
字符串中是否包含指定字符串
boolean contains(String str);
示例15:
01. public class StringMethodDemo{
02. public static void main(String[] args){
03. StringMethodDemo();
04. }
05.
06. public static void StringMethodDemo(){
07. String s = "abc";
08. System.out.println(s.contains( "bc"));
09. }
10. }
复制代码
运行结果:
3.3 字符串是否以指定字符串开头,是否以指定字符串结尾
boolean startsWith(String str);
boolean endsWith(String str);
示例16:
01. public class StringMethodDemo{
02. public static void main(String[] args){
03. StringMethodDemo();
04. }
05.
06. public static void StringMethodDemo(){
07. String str = "ArrayDemo.java";
08. System.out.println(str.startsWith( "Array"));
09. System.out.println(str.endsWith( "java"));
10. }
11. }
复制代码
运行结果:
4、比较
int compareTo(String str); 如果参数字符串等于此字符串,则返回值0;如果此字符串按字典顺序
小于字符串参数,则返回一个小于0的值;如果此字符串按字典顺序大于字符串参数,则返回一个大于0
的值。
示例17:
01. public class StringMethodDemo {
02. public static void main(String[] args){
03. StringMethodDemo();
04. }
05.
06. public static void StringMethodDemo(){
07. System. out.println("a" .compareTo("A"));
08. }
09. }
复制代码
运行结果:
示例18:
01. public class StringMethodDemo{
02. public static void main(String[] args){
03. StringMethodDemo();
04. }
05.
06. public static void StringMethodDemo(){
07. System.out.println( "abc".compareTo("aqz" ));
08. }
09. }
复制代码
运行结果:
P.S.
"abc"和"aqz"两个字符串比较,'a'和'a'相等,'b' - 'q' = -15,'c'和'z'也就没有必要比较。
5、返回字符串对象的规范化表示形式
String intern();
当调用intern方法时,如果池已经包含一个等于此String对象的字符串(用equals(Object)方法确
定),则返回池中的字符串。否则,将此String对象添加到池中,并返回此String对象的引用。
示例19:
01. public class StringMethodDemo{
02. public static void main(String[] args){
03. StringMethodDemo();
04. }
05.
06. public static void StringMethodDemo(){
07. String s1 = new String("abc" );
08. String s2 = s1.intern();
09.
10. System.out.println(s1 == s2);
11. }
12. }
复制代码
运行结果:
练习
1、给定一个字符串数组,按照字典顺序进行从小到大的排序。
{"nba","abc","cba","zz","qq","haha"}
思路:
①对数组排序,可以用选择,冒泡都行。
②for嵌套、比较以及换位。
③使用String类中提供的用于字符串比较的功能进行比较。
代码:
01. public class StringTest{
02. public static void main(String[] args){
03. String[] arr = { "nba","abc" ,"cba" ,"zz" ,"qq" ,"haha" };
04.
05. printArray(arr);
06. sortString(arr);
07. printArray(arr);
08. }
09.
10. public static void printArray(String[] arr){
11. System.out.print( "[");
12. for(int i = 0; i < arr.length; i++){
13. if(i != arr.length -1)
14. System.out.print(arr[i] + ",");
15. else
16. System.out.println(arr[i] + "]");
17. }
18. }
19.
20. public static void sortString(String[] arr){
21. for(int i = 0; i < arr.length - 1; i++){
22. for(int j = i + 1; j < arr.length; j++){
23. if(arr[i].compareTo(arr[j])>0){
24. swap(arr,i,j);
25. }
26. }
27. }
28. }
29.
30. private static void swap(String arr[],int i, int j){
31. String temp = arr[i];
32. arr[i] = arr[j];
33. arr[j] = temp;
34. }
35. }
复制代码
运行结果:
2、一个子串在整串中出现的次数 "nbaernbatynbauinbaopnba"
思路:
①要找的子串是否存在,如果存在获取其出现的位置,这个可以使用indexOf完成。
②如果找到了,那么就记录出现的位置并在剩余的字符串中继续查找该子串,而剩余字符串的起始位
是出现位置+子串的长度。
③以此类推,通过循环完成查找,如果找不到就是-1,并且每次找到用计数器记录。
代码:
01. public class StringTest{
02. public static void main(String[] args){
03. String str = "nbaernbatynbauinbaopnba";
04. String key = "nba";
05.
06. int count = getKeyStringCount(str,key);
07. System.out.println( "count = " + count);
08. }
09.
10. public static int getKeyStringCount(String str,String key){
11. //1、定义计数器
12. int count = 0;
13.
14. //2、定义变量记录key出现的位置
15. int index = 0;
16.
17. while((index = str.indexOf(key)) != -1){
18. str = str.substring(index + key.length());
19. count++;
20. }
21.
22. return count;
23. }
24. }
复制代码
运行结果:
3、两个字符串中最大相同的子串
"qwerabcdtyuiop"
"xcabcdvbn"
思路:
①既然取的是最大子串,先看短的那个字符串是否在长的那个字符串中。如果存在,短的那个字符串
就是最大子串。
②如果不是,那么就将短的那个子串进行长度递减的方式去子串,去子串中判断是否存在。如果存在
就已找到,就不用再找了。
代码:
01. public class StringTest{
02. public static void main(String[] args){
03. String s1 = "qwerabcdtyuiop";
04. String s2 = "xcabcdvbn";
05. String s = getMaxSubstring(s1,s2);
06. System.out.println( "s = " + s);
07. }
08.
09. public static String getMaxSubstring(String s1,String s2){
10.
11. String max = null,min = null;
12. max = (s1.length() > s2.length())?s1:s2;
13. min = max.equals(s1)?s2:s1;
14.
15. for(int i = 0; i < min.length(); i++){
16. for(int a = 0,b = min.length() - i; b != min.length() + 1;
a++,b++){
17. String sub = min.substring(a,b);
18. if(max.contains(sub))
19. return sub;
20. }
21. }
22. return null ;
23. }
24. }
复制代码
运行结果:
4、模拟一个trim功能方法,去除字符串两端的空白。
思路:
①定义两个变量。
一个变量作为从头开始判断字符串空格的角标,不断++。
一个变量作为从尾开始判断字符串空格的角标,不断--。
②判断到不是空格为止,取头部之间的字符串即可。 代码:
01. public class StringTest{
02. public static void main(String[] args){
03. String s = " ab c " ;
04.
05. s = myTrim(s);
06. System.out.println( "-" + s + "-" );
07. }
08.
09. public static String myTrim(String s){
10. int start = 0,end = s.length() - 1;
11.
12. while(start <= end && s.charAt(start) == ' '){
13. start++;
14. }
15.
16. while(start <= end && s.charAt(end) == ' '){
17. end--;
18. }
19. return s.substring(start,end + 1);
20. }
21. }
复制代码
运行结果:
StringBuffer
StringBuffer:就是字符串缓冲区,用于存储数据的容器。
特点:
1. 长度是可变的。
2. 可以存储不同类型数据。
3. 最终要转成字符串进行使用。
P.S.
StringBuffer的字符串缓冲区初始容量为16个字符,其实质还是数组。
StringBuffer既然是一个容器对象,应该具备什么功能呢?
1、添加
StringBuffer append(data);
StringBuffer insert(index,data);
示例:
01. public class StringBufferDemo{
02. public static void main(String[] args){
03. bufferMethodDemo();
04. }
05.
06. public static void bufferMethodDemo(){
07. //创建缓冲区对象
08. StringBuffer sb1 = new StringBuffer();
09. StringBuffer sb2 = sb1.append(4);
10.
11. System.out.println(sb1);
12. System.out.println(sb2);
13. System.out.println(sb1 == sb2);
14.
15. System.out.println(sb1.append(5));
16. System.out.println(sb1.append(6).append(7));
17. }
18. }
复制代码
运行结果:
原因分析:
sb1.append(4);语句是在缓冲区中添加4,然后将sb2引用变量指向了最终生成的字符串对象,sb1也
指向这个新生成的字符串对象,故两者指向的是同一个对象。
示例:
01. public class StringBufferDemo{
02. public static void main(String[] args){
03. bufferMethodDemo();
04. }
05.
06. public static void bufferMethodDemo(){
07. StringBuffer sb = new StringBuffer();
08. sb.append(4).append(5);
09. sb.insert(1, "haha");
10. System.out.println(sb.toString());
11. }
12. }
复制代码
运行结果:
P.S.
insert方法也可以对字符串进行修改。
2、删除
StringBuffer delete(int start,int end);包含头,不包含尾。
StringBuffer deleteCharAt(int index):删除指定位置的元素。
示例:
01. public class StringBufferDemo {
02. public static void main(String[] args){
03. bufferMethodDemo();
04. }
05.
06. public static void bufferMethodDemo(){
07. StringBuffer sb = new StringBuffer("abcd" );
08. sb.delete(1,3);
09. System.out.println(sb);
10.
11. //清空缓冲区
12. sb.delete(0,sb.length());
13. System.out.println(sb);
14. }
15. }
复制代码
运行结果:
3、查找
char charAt(int index);
int indexO(String str);
int lastIndexOf(String str);
4、修改
StringBuffer replace(int start,int end,String str);
void setCharAt(int index,char ch);
示例:
01. public class StringBufferDemo{
02. public static void main(String[] args){
03. bufferMethodDemo();
04. }
05.
06. public static void bufferMethodDemo(){
07. StringBuffer sb = new StringBuffer("abcd" );
08.
09. sb.replace(1,3,"nba");
10. System.out.println(sb);
11.
12. sb.setCharAt(2, 'q');
13. System.out.println(sb);
14. }
15. }
复制代码
运行结果:
5、其他方法
void setLength(int newLength);设置字符序列的长度
public StringBuffer reverse();将字符序列用其反转形式取代
示例:
01. public class StringBufferDemo{
02. public static void main(String[] args){
03. bufferMethodDemo();
04. }
05.
06. public static void bufferMethodDemo(){
07. StringBuffer sb = new StringBuffer("abcd" );
08.
09. sb.setLength(2);
10. System.out.println( "sb:" + sb);
11. System.out.println( "len" + sb.length());
12.
13. sb.setLength(10);
14. System.out.println( "sb:" + sb);
15. System.out.println( "len" + sb.length());
16.
17. System.out.println(sb.reverse());
18. }
19. }
复制代码
运行结果:
P.S.
1、使用setLength设置StringBuffer中字符序列的长度。
如果小于已有字符序列的长度,相当于清除缓冲区中的一部分内容。
如果大于已有字符序列的长度,相当于扩充缓冲区,扩充部门内容用空格字符填充。
2、当创建的StringBuffer内容长度大于16,将会新创建一个新数组,长度比旧数组要长。然后把就数
组的内容拷贝到新的数组,超出旧数组长度范围的内容将会放在新数组现在内容的后面,也可以通过
StringBuffer(int capacity);构造函数自己设置StringBuffer缓冲区长度。
StringBuilder
jdk1.5以后出现了功能和StringBuffer一模一样的对象,就是StringBuilder。
不同的是:
StringBuffer是线程同步的,通常用于多线程。
StringBuilder是线程不同步的,通常用于单线程,它的出现能够提高程序效率。
故StringBuilder多用于多个线程是不安全的,如果需要这样的同步,则建议使用StringBuffer。
P.S.
JDK一般升级目的:
1、简化书写。
2、提高效率。
3、增加安全性。
示例:将一个int数组变成字符串。
01. class StringBuilderTest{
02. public static void main(String[] args){
03. int[] arr = {3,1,5,4,8};
04. String s = arrayToString(arr);
05.
06. System.out.println(s);
07. }
08.
09. public static String arrayToString(int[] arr){
10. StringBuilder sb = new StringBuilder();
11. sb.append( "[");
12. for(int i = 0; i < arr.length; i++){
13. if(i != arr.length - 1)
14. sb.append(arr[i]).append( ",");
15. else
16. sb.append(arr[i]).append( "]");
17. }
18. return sb.toString();
19. }
20. }
6、集合
6.2 集合类
6.2.3 Vector、ArrayList、LinkedList
List:
|--Vector:内部是数组数据结构,是同步的。增删,查询都很慢。
|--ArrayList:内部是数组数据结构,是不同步的,替代了Vector。替代了Vector,查询的速度快。
|--LinkedList:内部是链表数据结构,是不同步的。增删元素的速度很快。
LinkedList方法:
addFirst();
addLast();
jdk1.6版本后新方法:
offerFirst();与addFirst方法没有区别。
offerLast();与addLast方法没有区别。
---------------------------------------------------------
getFirst();//获取但不移除,如果链表为空,抛出NoSuchElementException。
getLast();
jdk1.6版本后新方法:
peekFirst();//获取但不移除,如果链表为空,返回null。
peekLast();
--------------------------------------------------------
removeFirst();//获取并移除,如果链表为空,抛出NoSuchElementException。
removeLast();
jdk1.6版本后新方法:
pollFirst();//获取并移除,如果链表为空,返回null;
pollLast();
示例1:
01. import java.util.Enumeration;
02. import java.util.Iterator;
03. import java.util.Vector;
04.
05. public class VectorDemo{
06. public static void main(String[] args){
07. Vector v = new Vector();
08.
09. v.addElement( "abc1");
10. v.addElement( "abc2");
11. v.addElement( "abc3");
12. v.addElement( "abc4");
13.
14. Enumeration en = v.elements();
15.
16. while(en.hasMoreElements()){
17. System.out.println( "nextElement:" + en.nextElement());
18. }
19.
20. Iterator it = v.iterator();
21.
22. while(it.hasNext()){
23. System.out.println( "next:" + it.next());
24. }
25. }
26. }
复制代码
运行结果:
示例2:
01. import java.util.Iterator;
02. import java.util.LinkedList;
03.
04. public class LinkedListDemo{
05. public static void main(String[] args){
06. LinkedList link = new LinkedList();
07.
08. link.addFirst( "abc1");
09. link.addFirst( "abc2");
10. link.addFirst( "abc3");
11. link.addFirst( "abc4");
12.
13. Iterator it = link.iterator();
14. while(it.hasNext()){
15. System.out.println( "next:" + it.next());
16. }
17.
18. System.out.println(link);
19. System.out.println("getFirst:" + link.getFirst()); //获取第一个,但
是不删除。
20. System.out.println("getLast:" + link.getLast());
21.
22. System.out.println("removeFirst:" + link.removeFirst()); //获取第
一个,但是删除
23. System.out.println("removeLast:" + link.removeLast());
24.
25. //删除所有元素的方法
26. while(!link.isEmpty()){
27. System.out.println(link.removeFirst());
28. }
29. }
30. }
复制代码
运行结果:
请使用LinkedList来模拟一个堆栈或者队列数据结构。
堆栈:先进后出 First In Last Out FILO
队列:先进先出 First In First Out FIFO
我们应该描述这样一个容器,给使用者提供一个容器对象完成这两种结构中的一种。
代码:
01. import java.util.LinkedList;
02.
03. class DuiLie{
04. private LinkedList link;
05.
06. public DuiLie(){
07. link = new LinkedList();
08. }
09.
10. //队列的添加元素的功能。
11. public void myAdd(Object obj){
12. link.addLast(obj);
13. }
14.
15. public Object myGet(){
16. return link.removeFirst();
17. }
18.
19. public boolean isNull(){
20. return link.isEmpty();
21. }
22. }
23.
24. public class DuiLieTest{
25. public static void main(String[] args){
26. DuiLie dl = new DuiLie();
27.
28. dl.myAdd( "abc1");
29. dl.myAdd( "abc2");
30. dl.myAdd( "abc3");
31. dl.myAdd( "abc4");
32.
33. while(!dl.isNull()){
34. System.out.println(dl.myGet());
35. }
36. }
37. }
复制代码
运行结果:
示例3:
01. import java.util.ArrayList;
02. import java.util.Iterator;
03.
04. class Person{
05. private String name;
06. private int age;
07.
08. public Person(){
09. }
10.
11. public Person(String name,int age){
12. this.name = name;
13. this.age = age;
14. }
15.
16. public void setName(String name){
17. this.name = name;
18. }
19.
20. public String getName(){
21. return this .name;
22. }
23.
24. public void setAge(int age){
25. this.age = age;
26. }
27.
28. public int getAge(){
29. return this .age;
30. }
31. }
32.
33. public class ArrayListTest{
34. public static void main(String[] args){
35. ArrayList al = new ArrayList();
36. al.add( new Person("lisi1" ,21));
37. al.add( new Person("lisi2" ,22));
38. al.add( new Person("lisi3" ,23));
39. al.add( new Person("lisi4" ,24));
40.
41. Iterator it = al.iterator();
42. while(it.hasNext()){
43. Person p = (Person)(it.next());
44. System.out.println(p.getName() + ":" + p.getAge());
45. }
46. }
47. }
复制代码
运行结果:
Set:元素不可以重复,是无序。
Set接口中的方法和Collection一致。
|--HashSet:内部数据结构是哈希表,是不同步的。
|--TreeSet:可以对Set集合中的元素进行排序,是不同步的。
示例4:
01. import java.util.HashSet;
02. import java.util.Iterator;
03. import java.util.Set;
04.
05. public class HashSetDemo{
06. public static void main(String[] args){
07.
08. Set hs = new HashSet();
09.
10. hs.add( "hahah");
11. hs.add( "heihei");
12. hs.add( "hehe");
13. hs.add( "xixi");
14.
15. Iterator it = hs.iterator();
16.
17. while(it.hasNext()){
18. System.out.println(it.next());
19. }
20. }
21. }
复制代码
运行结果:
哈希表确定元素是否相同
1. 判断的是两个元素的哈希值是否相同。
如果相同,再判断两个对象的内容是否相同。
2. 判断哈希值相同,其实判断的是对象的HashCode方法。判断内容相同,用的是equals方法。
P.S.
如果哈希值不同,不需要判断equals。
往HashSet集合中存储Person对象。如果姓名和年龄相同,视为同一个人,视为相同元素。
示例5:
01. import java.util.HashSet;
02. import java.util.Iterator;
03.
04. class Person{
05. private String name;
06. private int age;
07.
08. public Person(){
09. }
10.
11. public Person(String name,int age){
12. this.name = name;
13. this.age = age;
14. }
15.
16. public void setName(String name){
17. this.name = name;
18. }
19.
20. public String getName(){
21. return this .name;
22. }
23.
24. public void setAge(int age){
25. this.age = age;
26. }
27.
28. public int getAge(){
29. return this .age;
30. }
31.
32. public int hashCode(){
33. return name.hashCode() + age * 39;
34. }
35.
36. public boolean equals(Object obj){
37. if(this == obj)
38. return true ;//同一个对象放两次,直接返回true
39.
40. if(!(obj instanceof Person))
41. throw new ClassCastException("类型错误");
42.
43. Person p = (Person)obj;
44.
45. return this .name.equals(p.name) && this.age == p.age;
46. }
47. }
48.
49. public class HashSetTest{
50. public static void main(String[] args){
51. HashSet hs = new HashSet();
52.
53. hs.add( new Person("lisi4" ,24));
54. hs.add( new Person("lisi7" ,27));
55. hs.add( new Person("lisi1" ,21));
56. hs.add( new Person("lisi9" ,29));
57. hs.add( new Person("lisi7" ,27));
58.
59. Iterator it = hs.iterator();
60.
61. while(it.hasNext()){
62. Person p = (Person)it.next();
63. System.out.println(p.getName() + "..." + p.getAge());
64. }
65. }
66. }
复制代码
运行结果:
定义功能去除ArrayList中的重复元素。
示例6:
01. import java.util.ArrayList;
02. import java.util.Iterator;
03.
04. public class ArrayListTest{
05. public static void main(String[] args){
06. ArrayList al = new ArrayList();
07. al.add( new Person("lisi1" ,21));
08. al.add( new Person("lisi2" ,22));
09. al.add( new Person("lisi3" ,23));
10. al.add( new Person("lisi4" ,24));
11. al.add( new Person("lisi3" ,23));
12. al.add( new Person("lisi4" ,24));
13.
14. System.out.println(al);
15.
16. al = getSingleElement(al);
17.
18. //remove底层用的还是equals方法
19. System.out.println(al.remove( new Person("lisi2" ,22)));
20. System.out.println(al);
21. }
22.
23. public static ArrayList getSingleElement(ArrayList al){
24. //1、定义一个临时容器
25. ArrayList temp = new ArrayList();
26.
27. //2、迭代al集合
28. Iterator it = al.iterator();
29.
30. while(it.hasNext()){
31. Object obj = it.next();
32.
33. //3、判断被迭代到的元素是否在临时容器存在
34. //contains方法依靠的是equals方法
35. if(!temp.contains(obj)){
36. temp.add(obj);
37. }
38. }
39. return temp;
40. }
41. }
复制代码 运行结果:
无序变有序,使用LinkHashSet。
示例7:
01. import java.util.HashSet;
02. import java.util.Iterator;
03. import java.util.LinkedHashSet;
04.
05. public class LinkedHashSetDemo{
06. public static void main(String[] args){
07. HashSet hs = new LinkedHashSet();
08.
09. hs.add( "hahaa");
10. hs.add( "hehe");
11. hs.add( "heihei");
12. hs.add( "xixii");
13.
14. Iterator it = hs.iterator();
15.
16. while(it.hasNext()){
17. System.out.println(it.next());
18. }
19. }
20. }
复制代码
运行结果:
TreeSet判断元素唯一性的方式:就是根据比较方法的返回结果是否是0,是0,就是相同元素,不存。
示例8:
01. import java.util.Iterator;
02. import java.util.TreeSet;
03.
04. class Person implements Comparable{
05. private String name;
06. private int age;
07.
08. public Person(){
09. }
10.
11. public Person(String name,int age){
12. this.name = name;
13. this.age = age;
14. }
15.
16. public void setName(String name){
17. this.name = name;
18. }
19.
20. public String getName(){
21. return this .name;
22. }
23.
24. public void setAge(int age){
25. this.age = age;
26. }
27.
28. public int getAge(){
29. return this .age;
30. }
31.
32. public int hashCode(){
33. return name.hashCode() + age * 39;
34. }
35.
36. public boolean equals(Object obj){
37. if(this == obj)
38. return true ;
39.
40. if(!(obj instanceof Person))
41. throw new ClassCastException("类型错误");
42.
43. Person p = (Person)obj;
44.
45. return this .name.equals(p.name) && this.age == p.age;
46. }
47.
48. public int compareTo(Object o){
49. Person p = (Person)o;
50.
51. //先按照年龄排序,再按照年龄排序,以免年龄相同的人,没有存进去。
52. int temp = this.age - p.age;
53. return temp == 0?this.name.compareTo(p.name):temp;
54. }
55. }
56.
57. public class TreeSetDemo{
58. public static void main(String[] args){
59. TreeSet ts = new TreeSet();
60.
61. //以Person对象年龄进行从小到大的排序
62. ts.add( new Person("zhangsan" ,28));
63. ts.add( new Person("wangwu" ,23));
64. ts.add( new Person("lisi" ,21));
65. ts.add( new Person("zhouqi" ,29));
66. ts.add( new Person("zhaoliu" ,25));
67.
68. Iterator it = ts.iterator();
69.
70. while(it.hasNext()){
71. Person p = (Person)it.next();
72.
73. System.out.println(p.getName() + ":" + p.getAge());
74. }
75. }
76. }
复制代码
运行结果:
TreeSet对元素进行排序的方式一: 让元素自身具备比较功能,元素就需要实现Comparable接口,
覆盖compareTo方法。
如果不要按照对象中具备的自然顺序进行排序。如果对象中不具备自然顺序。怎么办?
可以使用TreeSet集合第二种排序方式:
让集合自身具备比较功能,定义一个类实现Comparator接口,覆盖compare方法。
将该类对象作为参数传递给TreeSet集合的构造函数。
示例9:
01. import java.util.Comparator;
02. import java.util.Iterator;
03. import java.util.TreeSet;
04.
05. //创建了一个根据Person类的name进行排序的比较器。
06. class ComparatorByName implements Comparator{
07. public int compare(Object o1,Object o2){
08. Person p1 = (Person)o1;
09. Person p2 = (Person)o2;
10.
11. int temp = p1.getName().compareTo(p2.getName());
12. return temp == 0?p1.getAge()-p2.getAge() : temp;
13. }
14. }
15.
16. public class TreeSetDemo{
17. public static void main(String[] args){
18. TreeSet ts = new TreeSet(new ComparatorByName());
19.
20. //以Person对象年龄进行从小到大的排序
21. ts.add( new Person("zhangsan" ,28));
22. ts.add( new Person("wangwu" ,23));
23. ts.add( new Person("lisi" ,21));
24. ts.add( new Person("zhouqi" ,29));
25. ts.add( new Person("zhaoliu" ,25));
26.
27. Iterator it = ts.iterator();
28.
29. while(it.hasNext()){
30. Person p = (Person)it.next();
31.
32. System.out.println(p.getName() + ":" + p.getAge());
33. }
34. }
35. }
复制代码
运行结果:
P.S.
如果自定义类实现了Comparable接口,并且TreeSet的构造函数中也传入了比较器,那么将以比较器
的比较规则为准。
TreeSet集合的底层是二叉树进行排序的。
练习:对字符串进行长度排序。
代码:
01. import java.util.Comparator;
02. import java.util.Iterator;
03. import java.util.TreeSet;
04.
05. public class TreeSetTest{
06. public static void main(String[] args){
07. TreeSet ts = new TreeSet(new ComparatorByLen());
08.
09. ts.add( "aaaa");
10. ts.add( "zz");
11. ts.add( "nbag");
12. ts.add( "cba");
13. ts.add( "abc");
14.
15. Iterator it = ts.iterator();
16.
17. while(it.hasNext()){
18. System.out.println(it.next());
19. }
20. }
21. }
22.
23. class ComparatorByLen implements Comparator{
24. public int compare(Object o1,Object o2){
25. String s1 = (String)o1;
26. String s2 = (String)o2;
27.
28. int temp = s1.length() - s2.length();
29.
30. return temp == 0?s1.compareTo(s2):temp;
31. }
32. }
6、集合
6.2 集合类
6.2.5 Map、HashMap、TreeMap
Map:一次添加一对元素,Collection一次添加一个元素。
Map也称为双列集合,Collection集合称为单列集合。
其实Map集合中存储的就是键值对。
map集合中必须保证键的唯一性。
常用方法:
1、添加
value put(key,value):返回前一个和key关联的值,如果没有返回null。
2、删除
void clear():清空map集合。
value remove(Object key):根据指定的key删除这个键值对。
3、判断
boolean containsKey(key);
boolean containsValue(value);
boolean isEmpty();
4、获取
value get(key):通过键获取值,如果没有该键返回null。
当然可以通过返回null,来判断是否包含指定键。
int size():获取键值对个数。
示例1:
01. import java.util.HashMap;
02. import java.util.Map;
03.
04. public class MapDemo{
05. public static void main(String[] args){
06. Map<Integer,String> map = new HashMap<Integer,String>();
07. method(map);
08. }
09.
10. public static void method(Map<Integer,String> map){ //学号和姓名
11. //添加元素
12. System. out.println(map.put(8,"旺财" ));
13. System. out.println(map.put(8,"小强" ));
14. System. out.println(map);
15.
16. map.put(2, "张三");
17. map.put(7, "赵六");
18. System. out.println(map);
19.
20. //删除
21. System. out.println("remove:" + map.remove(2));
22.
23. //判断
24. System. out.println("containsKey:" + map.containsKey(7));
25.
26. //获取
27. System. out.println("get:" + map.get(7));
28. }
29. }
复制代码
运行结果:
获取Map集合元素并打印方式一:
示例2:
01. import java.util.HashMap;
02. import java.util.Iterator;
03. import java.util.Map;
04. import java.util.Set;
05.
06. public class MapDemo{
07. public static void main(String[] args){
08. Map<Integer,String> map = new HashMap<Integer,String>();
09. method(map);
10. }
11.
12. public static void method(Map<Integer,String> map){
13. map.put(8, "王五");
14. map.put(2, "赵六");
15. map.put(7, "小强");
16. map.put(6, "旺财");
17.
18. //取出map中的所有元素。
19. //原理,通过keySet方法获取map中所有的键所在的set集合,在通过set的迭代器获取到每一个键。
20. //再对每一个键通过map集合的get方法获取其对应的值即可。
21.
22. Set<Integer> keySet = map.keySet();
23. Iterator<Integer> it = keySet.iterator();
24.
25. while(it.hasNext()){
26. Integer key = it.next();
27. String value = map.get(key);
28. System.out.println(key + ":" + value);
29. }
30. }
31. }
复制代码
运行结果:
获取Map集合元素并打印方式二:
示例3:
01. import java.util.HashMap;
02. import java.util.Iterator;
03. import java.util.Map;
04. import java.util.Set;
05.
06. public class MapDemo{
07. public static void main(String[] args){
08. Map<Integer,String> map = new HashMap<Integer,String>();
09. method(map);
10. }
11.
12. public static void method(Map<Integer,String> map){
13. map.put(8, "王五");
14. map.put(2, "赵六");
15. map.put(7, "小强");
16. map.put(6, "旺财");
17.
18. /*
19. 通过Map转成Set就可以迭代。
20. 找到了另一个方法,entrySet。
21. 该方法将键和值的映射关系作为对象存储到了Set集合中,而这个映射关系的类型就是Map.Entry类型
22. */
23. Set<Map.Entry<Integer,String>> entrySet = map.entrySet();
24.
25. Iterator<Map.Entry<Integer,String>> it = entrySet.iterator();
26.
27. while(it.hasNext()){
28. Map.Entry<Integer,String> me = it.next();
29. Integer key = me.getKey();
30. String value = me.getValue();
31. System. out.println(key + ":" + value);
32. }
33. }
34. }
复制代码
运行结果:
获取Map集合元素并打印方式三:
示例4:
01. import java.util.Collection;
02. import java.util.HashMap;
03. import java.util.Iterator;
04. import java.util.Map;
05.
06. public class MapDemo{
07. public static void main(String[] args){
08. Map<Integer,String> map = new HashMap<Integer,String>();
09. method(map);
10. }
11.
12. public static void method(Map<Integer,String> map){
13. map.put(8, "王五");
14. map.put(2, "赵六");
15. map.put(7, "小强");
16. map.put(6, "旺财");
17.
18. Collection<String> values = map.values();
19.
20. Iterator<String> it = values.iterator();
21. while(it.hasNext()){
22. System. out.println(it.next());
23. }
24. }
25. }
复制代码
运行结果:
Map常用的子类:
|--Hashtable:内部结构是哈希表,是同步的。不允许null作为键,null作为值。
|--Properties:用来存储键值对型的配置文件的信息,可以和IO技术相结合。
|--HashMap:内部结构式哈希表,不是同步的。允许null作为键,null作为值。
|--TreeMap:内部结构式二叉树,不是同步的。可以对Map结合中的键进行排序。
hashSet实现Set接口,由哈希表(实际上是一个HashMap实例)支持。
示例5:
01. import java.util.HashMap;
02. import java.util.Iterator;
03.
04. class Student {
05. private String name;
06. private int age;
07.
08. public Student(){
09. }
10.
11. public Student(String name,int age){
12. this.name = name;
13. this.age = age;
14. }
15.
16. public void setName(String name){
17. this.name = name;
18. }
19.
20. public String getName(){
21. return this .name;
22. }
23.
24. public void setAge(int age){
25. this.age = age;
26. }
27.
28. public int getAge(){
29. return this .age;
30. }
31.
32. public int hashCode() {
33. final int prime = 31;
34. int result = 1;
35. result = prime * result + age;
36. result = prime * result + ((name == null) ? 0 : name.hashCode());
37. return result;
38. }
39.
40. public boolean equals(Object obj) {
41. if (this == obj)
42. return true ;
43. if (obj == null)
44. return false ;
45. if (getClass() != obj.getClass())
46. return false ;
47. Student other = (Student) obj;
48. if (age != other.age)
49. return false ;
50. if (name == null) {
51. if (other.name != null)
52. return false ;
53. } else if (!name.equals(other.name))
54. return false ;
55. return true ;
56. }
57. }
58.
59. public class HashMapDemo{
60. public static void main(String[] args){
61. //将学生对象和学生的归属地通过键与值存储到map集合中
62. HashMap<Student,String> hm = new HashMap<Student,String>();
63.
64. hm.put( new Student("lisi" ,38),"北京");
65. hm.put( new Student("zhaoliu" ,24),"上海");
66. hm.put( new Student("xiaoqiang" ,31),"沈阳");
67. hm.put( new Student("wangcai" ,28),"大连");
68. hm.put( new Student("zhaoliu" ,24),"铁岭");
69.
70. Iterator<Student> it = hm.keySet().iterator();
71.
72. while(it.hasNext()){
73. Student key = it.next();
74. String value = hm.get(key);
75. System.out.println(key.getName() + ":" + key.getAge() + "---" + value);
76. }
77. }
78. }
复制代码
运行结果:
P.S.
键有了判断依据,HashMap中的值就被覆盖。
示例6:
01. import java.util.Comparator;
02. import java.util.Iterator;
03. import java.util.Map;
04. import java.util.TreeMap;
05.
06. class ComparatorByName implements Comparator<Student>{
07. public int compare(Student s1,Student s2){
08. int temp = s1.getName().compareTo(s2.getName());
09. return temp == 0?s1.getAge() - s2.getAge():temp;
10. }
11. }
12.
13. public class HashMapDemo{
14. public static void main(String[] args){
15. //将学生对象和学生的归属地通过键与值存储到map集合中
16. TreeMap<Student,String> tm = new TreeMap<Student,String>(new ComparatorByName());
17.
18. tm.put( new Student("lisi" ,38),"北京");
19. tm.put( new Student("zhaoliu" ,24),"上海");
20. tm.put( new Student("xiaoqiang" ,31),"沈阳");
21. tm.put( new Student("wangcai" ,28),"大连");
22. tm.put( new Student("zhaoliu" ,24),"铁岭");
23.
24. Iterator<Map.Entry<Student,String>> it = tm.entrySet().iterator();
25.
26. while(it.hasNext()){
27. Map.Entry<Student,String> me = it.next();
28. Student key = me.getKey();
29. String value = me.getValue();
30. System.out.println(key.getName() + ":" + key.getAge() + "---" + value);
31. }
32. }
33. }
6、集合
6.2 集合类
6.2.5 Map、HashMap、TreeMap
使用LinkedHashMap则是跟原来存入的顺序是一致的。
示例7:
01. import java.util.HashMap;
02. import java.util.Iterator;
03. import java.util.LinkedHashMap;
04. import java.util.Map;
05.
06. public class LinkedHashMapDemo{
07. public static void main(String[] args){
08. HashMap<Integer,String> hm = new LinkedHashMap<Integer,String>();
09.
10. hm.put(7, "zhouqi");
11. hm.put(3, "zhangsan");
12. hm.put(1, "qianyi");
13. hm.put(5, "wangwu");
14.
15. Iterator<Map.Entry<Integer,String>> it =
hm.entrySet().iterator();
16.
17. while(it.hasNext()){
18. Map.Entry<Integer,String> me = it.next();
19.
20. Integer key = me.getKey();
21. String value = me.getValue();
22.
23. System.out. println(key + ":" + value);
24. }
25. }
26. }
复制代码
运行结果:
练习:
“fdqavcbsacdfs”获取该字符串中,每一个字母出现的次数。
要求打印结果是:a(2)b(1)...;
思路:
对于结果的分析发现,字母和次数之间存在着映射的关系,而且这种关系很多。
很多就需要存储,能存储映射关系的容器有数组和Map结合。
关系中没有编号!那就使用Map结合。
又发现可以保证唯一性的一方具备着顺序,如a、b、c...
所以可以使用TreeMap集合。
这个集合最终应该存储的是字母和次数的对应关系。
1. 因为操作的是字符串中的字母,所以先将字符串变成字符数组。
2. 遍历字符数组,用每一个字母作为键去查Map集合这个值。
如果该字母键不存在,就将该字母作为键,1作为值存储到map集合中。
如果该字母键存在,就将该字母键对应值取出并+1,再将该字母和+1后的值存储到map集合中。键
相同值会覆盖,这样就记录住了该字母的次数。
3. 遍历结果,map集合就记录所有字母的出现的次数。
代码:
01. import java.util.Iterator;
02. import java.util.Map;
03. import java.util.TreeMap;
04.
05. public class MapTest{
06. public static void main(String[] args){
07. String str = "fdqavcbsacdfs";
08.
09. String s = getCharCount(str);
10.
11. System.out.println(s);
12. }
13.
14. public static String getCharCount(String str){
15. //将字符串变为字符数组
16. char[] chs = str.toCharArray();
17.
18. //定义map集合表
19. Map<Character,Integer> map = new TreeMap<Character,Integer>();
20.
21. for(int i = 0; i < chs.length; i++){
22. if(!(chs[i] >= 'a' && chs[i] <= 'z' || chs[i] >= 'A' && chs[i] <= 'Z' ))
23. continue;
24.
25. //将数组中的字母作为键去查map表
26. Integer value = map.get(chs[i]);
27.
28. int count = 0;
29.
30. //判断值是否为null
31. if(value!=null){
32. count = value;
33. }
34. count++;
35.
36. map.put(chs[i],count);
37. }
38.
39. return mapToString(map);
40. }
41.
42. private static String mapToString(Map<Character,Integer> map){
43. StringBuilder sb = new StringBuilder();
44.
45. Iterator<Character> it = map.keySet().iterator();
46.
47. while(it.hasNext()){
48. Character key = it.next();
49. Integer value = map.get(key);
50.
51. sb.append(key + "(" + value + ")" );
52. }
53. return sb.toString();
54. }
55. }
复制代码
运行结果:
Map在有映射关系时,可以优先考虑,在查表法中的应用较为多见。
示例:
01. import java.util.HashMap;
02. import java.util.Map;
03.
04. public class MapTest{
05. public static void main(String[] args){
06. String week = getWeek(1);
07. System.out.println(week);
08.
09. System.out.println(getWeekByMap(week));
10. }
11.
12. public static String getWeekByMap(String week){
13. Map<String,String> map = new HashMap<String,String>();
14.
15. map.put( "星期一","Mon" );
16. map.put( "星期二","Tue" );
17. map.put( "星期三","Wes" );
18. map.put( "星期日","Sun" );
19. map.put( "星期天","Sun" );
20.
21. return map.get(week);
22. }
23.
24. public static String getWeek(int week){
25. if(week<1 || week>7)
26. throw new RuntimeException("没有对应的星期,请您重新输入" );
27.
28. String[] weeks = { "","星期一" ,"星期二" };
29.
30. return weeks[week];
31. }
32. }
复制代码
运行结果:
6.2.6 Collections工具类
Collections:是集合框架的工具类,里面的方法都是静态的。
示例1:
01. import java.util.ArrayList;
02. import java.util.Collections;
03. import java.util.Comparator;
04. import java.util.List;
05.
06. public class CollectionsDemo{
07. public static void main(String[] args){
08. demo1();
09. }
10.
11. public static void demo1(){
12. List<String> list = new ArrayList<String>();
13.
14. list.add( "abcde");
15. list.add( "cba");
16. list.add( "aa");
17. list.add( "zzz");
18. list.add( "cba");
19. list.add( "nbaa");
20.
21. //对list集合进行指定顺序的排序
22. Collections. sort(list);
23. System. out.println(list);
24.
25. Collections. sort(list,new ComparatorByLength());
26. System. out.println(list);
27.
28. mySort(list,new ComparatorByLength());
29. System. out.println(list);
30. }
31.
32. public static <T> void mySort(List<T> list,Comparator<? super T> comp)
{
33. for(int i = 0; i < list.size() - 1; i++){
34. for(int j = i + 1; j < list.size(); j++){
35. if(comp.compare(list.get(i),list.get(j))>0){
36. Collections. swap(list ,i,j);
37. }
38. }
39. }
40. }
41. }
42.
43. class ComparatorByLength implements Comparator<String>{
44. public int compare(String o1,String o2){
45. int temp = o1.length() - o2.length();
46. return temp == 0?o1.compareTo(o2):temp;
47. }
48. }
复制代码
运行结果:
示例2:
01. import java.util.ArrayList;
02. import java.util.Collections;
03. import java.util.Comparator;
04. import java.util.List;
05.
06. public class CollectionsDemo{
07. public static void main(String[] args){
08. demo2();
09. }
10.
11. public static void demo2(){
12. List<String> list = new ArrayList<String>();
13.
14. list.add( "abcde");
15. list.add( "cba");
16. list.add( "aa");
17. list.add( "zzz");
18. list.add( "cba");
19. list.add( "nbaa");
20.
21. Collections.sort(list);
22. System.out.println(list);
23.
24. int index = Collections.binarySearch(list,"aaa");
25. System.out.println( "index = " + index);//-2 -index-1
26.
27. //获取最大值
28. String max = Collections.max(list, new ComparatorByLength());
29. System.out.println( "max = " + max);
30. }
31. }
32.
33. class ComparatorByLength implements Comparator<String>{
34. public int compare(String o1,String o2){
35. int temp = o1.length() - o2.length();
36. return temp == 0?o1.compareTo(o2):temp;
37. }
38. }
复制代码
运行结果:
原因分析:
示例3:
01. import java.util.Collections;
02. import java.util.Comparator;
03. import java.util.TreeSet;
04.
05. public class CollectionsDemo{
06. public static void main(String[] args){
07. demo3();
08. }
09.
10. public static void demo3(){
11. TreeSet<String> ts = new TreeSet<String>
(Collections.reverseOrder());
12.
13. ts = new TreeSet<String>(Collections.reverseOrder(new
ComparatorByLength()));
14.
15. ts.add( "abc");
16. ts.add( "hahaha");
17. ts.add( "zzz");
18. ts.add( "aa");
19. ts.add( "cba");
20.
21. System.out.println(ts);
22. }
23. }
24.
25. class ComparatorByLength implements Comparator<String>{
26. public int compare(String o1,String o2){
27. int temp = o1.length() - o2.length();
28. return temp == 0?o1.compareTo(o2):temp;
29. }
30. }
复制代码
运行结果:
示例4:
01. import java.util.ArrayList;
02. import java.util.Collections;
03. import java.util.List;
04.
05. public class CollectionsDemo{
06. public static void main(String[] args){
07. demo4();
08. }
09.
10. public static void demo4(){
11. List<String> list = new ArrayList<String>();
12.
13. list.add( "abcde");
14. list.add( "cba");
15. list.add( "aa");
16.
17. System. out.println(list);
18. Collections. replaceAll(list,"cba", "nba");
19. System. out.println(list);
20. }
21. }
复制代码
运行结果:
示例5:
01. import java.util.ArrayList;
02. import java.util.Collections;
03. import java.util.List;
04.
05. public class CollectionsDemo{
06. public static void main(String[] args){
07. demo5();
08. }
09.
10. public static void demo5(){
11. List<String> list = new ArrayList<String>();
12.
13. list.add( "abcde");
14. list.add( "cba");
15. list.add( "zhangsan");
16. list.add( "zhaoliu");
17. list.add( "xiaoqiang");
18.
19. System. out.println(list);
20. Collections. shuffle(list);
21. System. out.println(list);
22. }
23. }
复制代码
运行结果:
原因分析:
练习:
给非同步的集合加锁。
代码:
01. import java.util.ArrayList;
02. import java.util.List;
03.
04. class MyCollections{
05. public List synList(List list){
06. return new MyList(list);
07. }
08.
09. private class MyList extends ArrayList{
10. private List list;
11.
12. private final Object lock = new Object();
13.
14. MyList(List list){
15. this.list = list;
16. }
17.
18. public boolean add(Object obj){
19. synchronized(lock){
20. return list.add(obj);
21. }
22. }
23.
24. public boolean remove(Object obj){
25. synchronized(lock){
26. return list.remove(obj);
27. }
28. }
29. }
30. }
31.
32. class Test{
33. public static void main(String[] args) {
34. List list = new ArrayList();//非同步的
35. list = new MyCollections().synList(list);//同步的
36. }
37. }
复制代码
6.2.7 Arrays工具类
Arrays:集合框架的工具类,里面的方法都是静态的。
示例1:
01. import java.util.Arrays;
02.
03. class ArraysDemo{
04. public static void main(String[] args){
05. int[] arr = {3,1,5,6,4,7};
06. System.out.println(Arrays.toString(arr));
07. }
08. }
复制代码
运行结果:
重点:List asList(数组)将数组转成集合。
好处:可以使用集合的方法操作数组。
示例2:
01. import java.util.Arrays;
02. import java.util.List;
03.
04. class ArraysDemo{
05. public static void main(String[] args){
06. String[] arr = { "abc","haha" ,"xixi" };
07.
08. List<String> list = Arrays. asList(arr);
09. boolean b = list.contains("xixi" );
10. System. out.println(b);
11. }
12. }
复制代码 运行结果:
P.S.
数组的长度是固定的,所以对于结合的增删方法是不可以使用的,否则,会发生
UnsupportedOperationException。
数组转集合,用asList方法。
如果数组中的元素是对象,那么转成集合时,直接将数组中的元素作为集合中的元素进行集合存储。
如果数组中的元素是基本类型数值,那么会将该数组作为集合中的元素进行存储。
示例3:
01. import java.util.Arrays;
02. import java.util.List;
03.
04. class ArraysDemo{
05. public static void main(String[] args){
06. int[] arr1 = {31,11,51,61};
07. List< int[]> list1 = Arrays.asList(arr1);
08. System.out.println(list1);
09.
10. Integer[] arr2 = {31,11,51,61};
11. List list2 = Arrays.asList(arr2);
12. System.out.println(list2);
13. }
14. }
复制代码
运行结果:
集合转数组
使用的就是Collection接口中的toArray方法。
集合转成数组,可以对集合中的元素操作的方法进行限定,不允许对其进行增删。
toArray方法需要传入一个指定类型的数组。
长度该如何定义呢?
如果长度小于集合的size,那么该方法会创建一个同类型并和集合相同的size的数组。
如果长度大于集合的size,那么该方法就会使用指定的数组,存储集合中的元素,其他位置默认为
null。
所以建议,最后长度就指定为,集合的size。
示例4:
01. import java.util.ArrayList;
02. import java.util.Arrays;
03. import java.util.List;
04.
05. public class ToArray{
06. public static void main(String[] args){
07. List<String> list = new ArrayList<String>();
08. list.add( "abc1");
09. list.add( "abc2");
10. list.add( "abc3");
11.
12. String[] arr = list.toArray( new String[2]);
13.
14. System.out.println(Arrays.toString(arr));
15. }
16. }
复制代码
运行结果:
~END~
~爱上海,爱黑马~