黑马程序员——Java语言--集合框架

———–android培训java培训、java学习型技术博客、期待与您交流!————

String类

String类是开发中非常最常用甚至不可缺少的好东西,用它可以做很多有趣的事情。

特点

  • 字符串是一个特殊的对象
  • 字符串一旦初始化就不可以被改变

小问题

String str = "abc";

String str1 = new String("abc");

这两个字符串的创建有何区别?

结合代码来解释:

class StringDemo 
{
	public static void main(String[] args) 
	{
		stringDemo1();
		stringDemo2();
	}

	public static void stringDemo1()
	{
		/*
		 * String类的特点:
		 * 字符串对象一旦被初始化就不会被改变。
		 */

		 // abc是一个对象,存储在字符串常量池中,abc这个本身不能被改变
		 String s1 = "abc";	
		 String s2 = "abc";
		 System.out.println(s1==s2); // true

		 /*
		  * 为什么输出的是 true呢?因为 首先==比较的是地址值
		  * "abc" 存储在字符串常量池中,当要赋值给s2时,要去字符串常量池中查找是否有"abc"
		  * 若有,则把"abc"的地址值赋给s2,其实字符串常量池是共享数据的,所以true
		  */
	}

	public static void stringDemo2()
	{
		String s1 = "abc"; // 创建了一个对象"abc",在字符串常量池中
		String s2 = new String("abc"); // 创建两个对象("abc",new String("abc")),在堆内存中
		System.out.println(s1==s2); // false
		// 地址不同,所以就是false
		System.out.println(s1.equals(s2)); // true
		// String的equals方法覆盖了Object的equals方法,用于判断字符串对象是否相同的依据
		// 其实就是比较字符串的内容。
	}

}


构造函数

class StringConstructorDemo 
{
	public static void main(String[] args) 
	{
		stringConstructorDemo_1();
		stringConstructorDemo_2();
	}

	public static void stringConstructorDemo_1()
	{
		// String s = new String(); // 等效于 String s = "";
		// 将字节数组通过String构造函数进行转换成字符串
		byte[] arr = {65, 78, 79, 83, 90};
		String s1 = new String(arr);
		System.out.println("s1="+s1); // s1=ANOSZ
		// why?首先byte编程字符串的话,byte元素要变成字符,因为字符是字符串的单元(字符组成字符串)
	}

	public static void stringConstructorDemo_2()
	{
		char[] chs = {'a','b','f','j','h','x','l'};
		//将字符数组通过String构造函数进行转换成字符串
		String s = new String(chs);
		System.out.println("s="+s); // abfjhxl
		// 还可以指定获取char数组中的某一部分转换成字符串
		// 从chs数组的角标为3开始取,往后取4个
		String s1 = new String(chs,3,4);  // jhxl
		System.out.println("s1="+s1);
	}

}

常用方法

class StringMethodDemo 
{
	public static void main(String[] args) 
	{
		stringMethodDemo_1();
		System.out.println();
		stringMethodDemo_2();
		System.out.println();
		stringMethodDemo_3();
	}

	public static void stringMethodDemo_1()
	{
		/*
		 * 1.获取
		 * 1.1 获取字符串中的字符的个数(长度)
		 *		int	length()
		 * 1.2 获取字符串中指定位置的字符
		 *		char charAt(int index)
		 * 1.3 获取字符串中指定字符第一次出现的位置
		 *		int indexOf(int ch)
		 *		int indexOf(int ch, int fromIndex) // 指定从哪个位置开始查找
		 * 1.4 获取字符串中指定的子字符串第一次出现的位置
		 *		int indexOf(String str)
		 *		int indexOf(String str, int fromIndex) // 指定从哪个位置开始查找
		 * 1.5 获取字符串中指定的字符或者子字符串最后一次出现的位置
		 *		int lastIndexOf(int ch)
		 *		int lastIndexOf(int ch, int fromIndex)
		 *		int lastIndexOf(String str)
		 *		int lastIndexOf(String str, int fromIndex)
		 * 1.6 获取字符串中一部分字符串,也叫子串。
		 *		String subString(int beginIndex) // 从beginIndex到最后都是
		 *		String substring(int beginIndex, int endIndex) // 包含beginIndex,不包含endIndex
		 */

		String s = "abcdefacg";
		System.out.println("length:" + s.length()); // 字符串长度
		System.out.println("char:" + s.charAt(0)); // 获取字符串角标为0的字符
		System.out.println("字符c第一次出现的角标为:" + s.indexOf('c'));
		System.out.println("从角标2开始查找字符c第一次出现的角标为:" + s.indexOf('e',2));
		System.out.println("子字符串bc第一次出现在:" + s.indexOf("bc"));
		System.out.println("从角标5开始查找子字符串ab第一次出现的位置:" + s.indexOf("ab",5));
		System.out.println("从后往前找a:" + s.lastIndexOf('a'));
		System.out.println("从后往前找ac:" + s.lastIndexOf("ac"));
		System.out.println("获取角标2到角标5的字符串:" + s.substring(2,5));
	}

	public static void stringMethodDemo_2()
	{
		/*
		 * 2.转换
		 * 2.1 将字符串转换成字符串数组(字符串的切割,大菜刀)
		 *		String[] split(String regex):设计到正则表达式
		 * 2.2 将字符串转换成字符数组(大锤子)
		 *		char[] toCharArray();
		 * 2.3 将字符串转换成字节数组
		 *		byte[] getBytes[];
		 * 2.4 将字符串的字母转成大小写
		 *		String toUpperCase();	大写
		 *		String toLowerCase();	小写
		 * 2.5 将字符串中的内容进行替换
		 *		String replace(char oldch, char newch);
		 *		String replace(String oldstr, String newstr);
		 * 2.6 将字符串两端的空格去除
		 *		String trim();
		 * 2.7 将字符串进行连接
		 *		String concat(String str)
		 */

		 // 演示一下
		 String s = "a,b,c ";
		 String[] splitResult = s.split(",");
		 System.out.print("split: ");
		 for(int x=0; x<splitResult.length; x++)
			 System.out.print(splitResult[x]+" ");
		 System.out.println();

		 char[] chs = s.toCharArray();
		 System.out.print("toCharArray: ");
		 for(int x=0; x<chs.length; x++)
			 System.out.print(chs[x]+" ");
		 System.out.println();

		 byte[] arr = s.getBytes();
		 System.out.print("getBytes: ");
		 for(int x=0; x<arr.length; x++)
			 System.out.print(arr[x]+" ");
		 System.out.println();

		 System.out.println("toUpperCase:"+s.toUpperCase());
		 System.out.println("toLowerCase:"+s.toLowerCase());

		 System.out.println("replace:" + s.replace('a','f'));
 		 System.out.println("replace:" + s.replace("a,b","j,x"));

		 System.out.println("trim:" + s.trim());
		 
		 System.out.println("concat:"+ s.concat("jhxl"));
	}

	public static void stringMethodDemo_3()
	{
		/*
		 * 3.判断
		 * 3.1 判断两个字符串的内容是否相同。
		 *		boolean equals(Object obj);
		 *		boolean equalsIgnoreCase(String str);	// 忽略大小写比较字符串内容
		 * 3.2 判断一个字符串是否包含指定的字符串
		 *		boolean contains(String str)
		 * 3.3 判断字符串是否以指定字符串开头,或者是以指定字符串为结尾。
		 *		boolean startsWith(String str)
		 *		boolean endsWith(String str)
		 */

		 String s = "abC";
		 System.out.println("equals:"+s.equals("abc"));
		 System.out.println("equalsIgnoreCase:"+s.equalsIgnoreCase("ABC"));
		 System.out.println("contains"+s.contains("ab"));
		 System.out.println("startsWith:"+s.startsWith("ab"));
		 System.out.println("endsWith:"+s.endsWith("bC"));

	}
}



字符串的练习

字符串数组的排序代码演示
/*
 * 需求:字符串数组 进行排序
 * 思路:可以使用冒泡排序,但是以往排的都是数据类型的,用的运算符是比较运算符,
 *			现在要比较的是字符串,那么需要使用compareTo来进行字符串之间的大小比较。
 */

class StringSortDemo 
{
	public static void main(String[] args) 
	{
		String[] arr = {"angle","abc","zero","two","one","haha","okok","a","xl","h"};
		printArray(arr); // 排序前
		sortArray(arr);	 // 排序
		printArray(arr); // 排序后
	}

	// 排序
	public static void sortArray(String[] arr)
	{
		for(int i=0;i<arr.length-1; i++)
		{
			for(int j=i+1; j<arr.length; j++)
			{
				if(arr[i].compareTo(arr[j]) > 0)
				{
					swap(arr,i,j);
				}
			}
		}
	}

	// 交换位置
	public static void swap(String[] arr, int i, int j)
	{
		String temp = arr[i];
		arr[i] = arr[j];
		arr[j] = temp;
	}

	// 打印
	public static void printArray(String[] arr)
	{
		for(int x=0; x<arr.length-1; x++)
			System.out.print(arr[x]+",");
		System.out.println(arr[arr.length-1]);
	}
}


子串在整串中的出现次数
/*
 * 需求,求一个子串在整串中出现的次数。
 * 思路:比如 abcdefabcfffabcabcxlxlh 当中出现abc多少次
 * 步骤:1、首先使用indexOf查找出第一个abc的位置,累计+1
 *		 2、从第一个abc出现位置加上abc长度的位置开始往后使用indexOf查找abc,相当defabcfffabcabcxlxlh里边找abc
 *		 3、不断重复上面的两个步骤,直到找不到,返回-1为止,即可。
 */

class SubStringCountDemo 
{
	public static void main(String[] args) 
	{
		String str = "abcdefabcfffabcabcxlxlh";
		String key = "abc";
		System.out.println(getSubStringCounts_2(str, key));
	}

	// 这方法并不是特别好,因为会产生很多个字符串对象,有点浪费内存
	public static int getSubStringCounts_1(String str, String key)
	{
		int count = 0; // 累计子串次数
		int index = 0; // 每一次通过indexOf查找返回的结果值

		// 当返回的不是-1,就说明找到了,还可以继续往后尝试
		while((index=str.indexOf(key))!=-1)
		{
			str = str.substring(index+key.length());
			count++;
		}
		return count;
	}

	public static int getSubStringCounts_2(String str, String key)
	{
		int count = 0;
		int index = 0;
		// 指定从index位置往后查找
		while((index=str.indexOf(key,index))!=-1)
		{
			index = index + key.length();
			count++;
		}
		return count;
	}
}
两个字符串中最长的相同的子串
/**
 * 需求:求出两个字符串中最长的相同的子串。
 * 思路:
 *		1、首先取较短的字符串,判断该字符串是不是较长字符串的子串,若是,则最长。
 *		2、若不是,那么对较短的字符串进行长度逐一递减的截取,再判断是不是较长的字符串的子串。
 *		3、不断循环以上两个步骤,直到找到为止,跳出。
 */

class BiggestSubStringDemo
{
	public static void main(String[] args) 
	{
		String str = "aabcdefffah";
		String key = "abcd";
		System.out.println(getBiggestSubString(str,key));
		System.out.println(getMaxSubString(str,key));
	}

	// 方法一
	public static String getBiggestSubString(String strone,String strtwo)
	{
		int maxlen = strtwo.length();	// 原本的长度
		int len = strtwo.length();		// 子串的长度
		int index = 0;					// 截取子串的开始位置
		String temp = strtwo;
		while(!strone.contains(temp))
		{
			if(index <= maxlen - len)
				temp = strtwo.substring(index++, len);	// 从index位置开始不断往后截取子串尝试
			else
			{
				// 如果len长度的没有,那么试试len-1的
				len = strtwo.length() - 1;
				index = 0;
			}
		}
		return temp;
	}

	// 方法二
	public static String getMaxSubString(String strone,String strtwo)
	{
		// 分辨最长最短字符串
		String max = "", min = "";
		if(strone.length()>strtwo.length())
		{
			max = strone;
			min = strtwo;
		}
		else
		{
			min = strone;
			max = strtwo;
		}

		// 枚举较短字符串的子串进行与较长字符串的匹配
		for(int i=0; i<min.length()-1 ; i++)
		{
			// 截取min字符串的角标j到k的长度
			for(int j=0,k=min.length()-i; k!=min.length()+1;j++,k++)
			{
				String temp = min.substring(j, k);
				if(max.contains(temp))
					return temp;
			}
		}
		return "";
	}
}

StringBuffer

什么是StringBuffer?

StringBuffer:就是字符串缓冲区。

用于存储数据的容器。

特点

  1. 长度是可变的。
  2. 可以存储不同类型的数据。
  3. 最终要转成字符串进行使用。
  4. 可以对字符串进行修改。

代码演示功能

class StringBufferDemo 
{
	public static void main(String[] args) 
	{
		bufferMethodDemo_1();
	}

	public static void bufferMethodDemo_1()
	{
		/*
		 * 1、添加
		 *		StringBuffer append(data); // 追加数据
		 *		StringBuffer insert(index, data); // 指定位置插入数据
		 * 2、删除
		 *		StringBuffer delete(int start, int end); // 包含头,不包含尾
		 *		StringBuffer deleteCharAt(int index);	 // 删除指定位置的元素
		 * 3、查找
		 *		char charAt(int index);
		 *		int indexOf(String str);
		 *		int lastIndexIf(String str);
		 * 4、修改
		 *		StringBuffer replace(int start, int end, String str);
		 *		void setCharAt(int index, char ch);
		 */
		
		// 添加
		StringBuffer sb = new StringBuffer();
		sb.append(1).append("2").append('3').append(true).append(5l);
		System.out.println("append:"+sb);  // 123true5
		sb.insert(2,false);					
		System.out.println("insert:"+sb);	// 12false3true5

		// 删除
		sb.delete(2,7);
		System.out.println(sb);
		// 清除缓冲区
		// sb.delete(0, sb.length());

		// 查找
		System.out.println("charAt:"+sb.charAt(1));
		System.out.println("indexOf:"+sb.indexOf("true"));
		System.out.println("lastIndexOf:"+sb.lastIndexOf("5"));

		// 修改
		System.out.println("replace:"+sb.replace(0,2,"hahha"));
		sb.setCharAt(0,'a');
		System.out.println("setCharAt:"+sb);

	}

}


StringBuilder和StringBuffer的区别

jdk1.5以后出现了功能和StringBuffer一模一样的对象,就是StringBuilder。

不同的是:

  • StringBuffer是线程同步的,通常用于多线程。
  • StringBuilder是线程不同步的,通常用于单线程。它的出现提高效率。


基本数据类型对象包装类

作用:

为了方便操作基本数据类型值,将其封装成了对象,在对象中定义了属性和行为丰富了该数据的操作。

用于描述该对象的类就称为基本数据类型对象包装类。

byte  Byte , shrot  Short , int  Integer , long  Long , float  Float , double  Double , char  Character , boolean  Boolean


基本数据类型和字符串之间的转换

1、基本类型 ---> 字符串

  1. 基本数据类型+""
  2. 用String类中的静态方法valueOf(基本类型数值)

2、字符串 ---> 数据类型

  1. 使用包装类中的静态方法 xxx parseXxx("xxx类型的字符串"),只有Character包装类没有parse方法
  2. 如果字符串被Integer进行对象的封装,可以使用另一个非静态的方法,intValue()

进制的转换

         1. 十进制 ---> 其他进制

                  toBinaryString

                  toOctalString

                  toHexString

          2. 其他进制 ---> 十进制

                  parseInt("string", radix)

JDK1.5自动装箱拆箱

Integer i = 4; // i = new Integer(4); 自动装箱,简化书写

i = i + 6; // i = new Integer(i.intValue() + 6) ; // i.intValue();  自动拆箱

Integer a = new Integer(128);

Integer b = new Integer(128);

System.out.println(a==b); // false

System.out.println(a.equals(b)); // true

Integer x = 129; // jdk1.5以后,自动装箱,如果装箱的是一个字节,那么该数据会共享不会重新开辟空间

Integer y = 129;

System.out.println(x==y);

System.out.println(x.equals(y)); // true



集合框架由来

对象用于封装特有数据,对象多了需要存储,如果对象的个数不确定,就是用集合容器进行存储。

集合容器因为内部的数据结构不同,所以有多种具体容器,不断地向上抽取,就形成了集合框架体系。

特点

  1. 是用于存储对象的容器。
  2. 集合的长度是可变的。
  3. 集合中不可以存储基本数据类型值。

Collectuib接口

Collection接口是集合框架的顶层接口。

常见方法:

1,添加。

           boolean add(Object obj); // 添加元素

           boolean addAll(Collection coll); // 将集合coll里的所有元素添加到当前对象集合

2,删除。

           boolean remove(Object obj);  // 删除元素

           boolean removeAll(Collection coll); // coll和当前集合的交集部分,是当前集合的删除内容

           void clear(); // 清空集合里的所有元素

3,判断。

           boolean contains(Object obj); // 是否包含指定元素

           boolean containsAll(Collection coll); // coll是否是子集合

           boolean isEmpty(); // 判断集合是否有元素

4,获取。

           int size(); // 集合元素个数

           Iterator iterator(); // 取出元素的方式:迭代器

           该对象ixu依赖于具体容器,因为每一种容器的数据结构都不同。

           所以该迭代器对象是在容器中进行内部实现的。

           对于使用容器者而言,具体的实现不重要,只要通过容器获取到该实现的迭代器的对象即可,也就是iterator();。

           Iterator接口就是对所有的Collection容器进行元素取出的公共接口。

5,其他。

           boolean retainAll(Collection coll); // 取交集

           Object[ ] toArray(); // 将集合转成数组。

Demo

import java.util.Collection;
import java.util.ArrayList;
import java.util.Iterator;

class CollectionDemo 
{
	public static void main(String[] args) 
	{
		// Collection 是一个接口,所以...
		collectionMethodShow(new ArrayList());
		System.out.println("---------------------");
		collectionIterator(new ArrayList());
	}

	public static void collectionMethodShow(Collection coll)
	{
		// 添加
		coll.add("123a");	 // 添加元素
		coll.add("123b");
		coll.add("123c");
		coll.add("123d");
		System.out.println("coll-add:"+coll);

		Collection collTemp = new ArrayList();
		collTemp.add("123a");
		collTemp.add("123e");
		collTemp.add("123d");
		coll.addAll(collTemp);	// 将集合coll里的所有元素添加到当前对象集合
		System.out.println("coll-addAll:"+coll);

		// 删除
		coll.remove("123a");	 // 删除元素
		System.out.println("coll-remove:"+coll);
		coll.removeAll(collTemp);	// coll和当前集合的交集部分,是当前集合的删除内容
		System.out.println("coll-removeAll:"+coll);
		// coll.clear(); // 清空集合

		// 判断
		System.out.println("coll-contains:"+coll.contains("123a"));   // 是否包含指定元素
		collTemp.remove("123e");
		System.out.println("coll-containsAll:"+coll.containsAll(collTemp)); // collTemp是否是子集合
		System.out.println("coll-isEmpty:"+coll.isEmpty()); // 判断集合是否有元素

		// 获取
		System.out.println("coll:"+coll);
		System.out.println("coll-size:"+coll.size()); // 集合元素个数

		// 其他
		collTemp.add("123b");
		System.out.println("coll-retainAll:"+coll.retainAll(collTemp));  // 取交集
		Object[] arr = coll.toArray(); //  // 将集合转成数组。
		// 遍历数组
		for(int i=0; i<arr.length-1; i++)
			System.out.print(arr[i]+",");
		System.out.println(arr[arr.length-1]);
	}

	// 遍历获取集合元素,并输出
	public static void collectionIterator(Collection coll)
	{
		// 添加
		coll.add("123a");	 // 添加元素
		coll.add("123b");
		coll.add("123c");
		coll.add("123d");

		// 通过迭代器迭代,枚举出所有数据,it.hasNext():判断是否拥有下一个元素
		for(Iterator it = coll.iterator(); it.hasNext();)
		{
			System.out.println(it.next());
		}
	
	}
}


List和Set的特点

List:有序(存入和取出的顺序一致),元素都有索引(角标),并且元素可以重复。

Set:无序,元素不可以重复。

List特有的常见方法:

与Collection不同的是,List可以操作角标,并且还有修改元素的功能。所以,List是可以完成对元素的增删改查的。

1,添加。

      void add(index, element); // 往指定位置添加一个元素

      void add(index,collection); // 往指定位置添加一个集合里的所有元素

2,删除。

      Object remove(index); // 删除指定位置的元素

3,修改。

      Object set(index,element); // 修改指定位置的元素

4,获取。

      Object get(index); // 获取指定位置的元素

      int indexOf(Object); // 获取指定元素的角标位置

      int lastIndexOf(Object); // 同上,只不过是从后边开始找

      List subList(from, to); // 获取指定部分的元素(子列表),包含头,不包含尾

Demo

import java.util.List;
import java.util.ArrayList;
class ListDemo 
{
	public static void main(String[] args) 
	{
		List list = new ArrayList();
		showListMethod(list);
	}

	public static void showListMethod(List list)
	{
		// 添加元素。
		list.add("abc1");
		list.add("abc1"); // 可以重复元素
		list.add("abc2"); 
		list.add("abc3"); 
		System.out.println("list-add(obj) : " + list);

		// 插入元素。
		list.add(1,"abc8"); // 往角标为1的位置添加一个指定的元素"abc8"
		System.out.println("list-add(index,obj): " + list);

		// 删除元素。
		System.out.println("list-remove(index):" + list.remove(2));
		System.out.println("list:" + list);

		// 修改元素。
		list.set(1,"abc18"); // 修改角标为1的元素
		System.out.println("list-set(index,obj):"+list);

		// 获取元素
		System.out.print("list-get(index):");
		for(int i=0; i<list.size()-1; i++)
			System.out.print(list.get(i)+" ");
		System.out.println(list.get(list.size()-1));

		System.out.println("list-indexOf:"+list.indexOf("abc2"));
		System.out.println("list-lastIndexOf:"+list.lastIndexOf("abc2"));
		System.out.println("list-subList(from,to):"+list.subList(0,2));

	}
}


迭代器使用注意事项

集合可以使用迭代器进行元素的迭代输出,但是在迭代过程中最好不要对集合进行操作,因为容易出现异常。

比如,通过集合对象调用了iterator()方法来获取了迭代器对象了,然后要迭代,此时迭代器是明确了集合的元素个数的,如果在迭代过程中,需要往集合添加元素的话,这样迭代器是不知道的,但是集合的长度发生了变化,新添加的元素不知道是否迭代获取还是怎么样,所以此时会抛出并发异常,所以建议使用Iterator的过程中不要对集合进行操作。

当然,对于List来说也有解决的方法,在List中有一个方法:listIterator();返回的类型是ListIterator,它可以解决上面的问题。但是并不是说在迭代过程中可以用集合操作,而是使用迭代器对象进行操作,使用迭代器进行元素的增删改查,作用于集合上。

ListIterator迭代器的演示

import java.util.List;
import java.util.ArrayList;
import java.util.ListIterator;

class ListIteratorDemo 
{
	public static void main(String[] args) 
	{
		List list = new ArrayList();
		list.add("abc1");
		list.add("abc2");
		list.add("abc3");
		System.out.println(list);
		ListIterator it = list.listIterator();
		while(it.hasNext())
		{
			Object obj = it.next();
			if(obj.equals("abc2"))
			{
				it.add("abc8");
			}
		}
		System.out.println(list);
	}
}


List常用的子类

Vector:内部是数组数据结构,是同步的。增删,查询都很慢。

ArrayList:内部是数据数据结构,是不同步的。替代了Vector。查询的速度快。

                    增删慢,因为每增加或者删除一个元素,都会让很多元素进行移位。

LinkedList:内部是链表数据结构,是不同步的。增删元素的速度很快。


演示LinkedList

import java.util.LinkedList;

class LinkedListDemo 
{
	public static void main(String[] args) 
	{
		LinkedList ll = new LinkedList();
		ll.addFirst("abc1"); // 往头添加
		ll.addFirst("abc1");
		ll.addFirst("abc2");
		ll.addFirst("abc3");

		for(int i=0; i<ll.size(); i++)
			System.out.print(ll.get(i)+" "); // abc3 abc2 abc1 abc1
		System.out.println();

		System.out.println("getFirst:"+ll.getFirst());		 // 获取第一个
		System.out.println("removeFirst:"+ll.removeFirst());	 // 删除第一个
		System.out.println("ll:"+ll);
	}
}


使用LinkedList实现队列的数据结构

import java.util.LinkedList;

class DuiLie
{
	private LinkedList ll ;

	DuiLie()
	{
		ll = new LinkedList();
	}

	public void myAdd(Object obj)
	{
		ll.addLast(obj);	
	}

	public Object myGet()
	{
		return ll.removeFirst();
	}

	public boolean isNull()
	{
		return ll.isEmpty();
	}

}

class LinkedListTest 
{
	public static void main(String[] args) 
	{
		DuiLie dl = new DuiLie();
		dl.myAdd("android01");
		dl.myAdd("android02");
		dl.myAdd("android03");
		dl.myAdd("android04");
		dl.myAdd("android05");

		while(!dl.isNull())
		{
			System.out.println(dl.myGet());
		}
	}
}


演示ArrayList存储自定义对象

import java.util.ArrayList;
import java.util.Iterator;

/* 需求:演示ArrayList集合存储自定对象 */

class Person
{
	private String name;
	private int age;

	public Person(){}

	public Person(String name, int age)
	{
		this.name = name;
		this.age = age;
	}

	public void setName(String name)
	{
		this.name = name;
	}

	public String getName()
	{
		return name;
	}

	public void setAge(int age)
	{
		this.age = age;
	}

	public int getAge()
	{
		return age;
	}
}

class ArrayListDemo 
{
	public static void main(String[] args) 
	{
		// 演示ArrayList集合存储自定对象		
		ArrayList al = new ArrayList();
		al.add(new Person("haha",20));
		al.add(new Person("lala",21));
		al.add(new Person("小明",22));
		al.add(new Person("Java",23));

		// 迭代
		for(Iterator it = al.iterator(); it.hasNext();)
		{
			Person p = (Person)it.next();
			System.out.println(p.getName()+"--"+p.getAge());
		}
	}
}

ArrayList存储内存图解

ArrayList去重元素

import java.util.ArrayList;
import java.util.Iterator;

/**
 * 需求:将集合中重复对象进行去重处理。
 */

class Person
{
	private String name;
	private int age;

	public Person(){}

	public Person(String name, int age)
	{
		this.name = name;
		this.age = age;
	}

	// 比较两个对象的内容,如果相同则返回true,表明集合里有该对象
	public boolean equals(Object obj)
	{
		// 如果是同一个对象
		if(this==obj)
			return true;

		// 必须是人与人比
		if(!(obj instanceof Person))
			throw new ClassCastException("类型不对!");

		Person p = (Person)obj;
		// System.out.println(this.name+"...equlas..."+p.name);
		return this.name.equals(p.name) && this.age == p.age;
	}

	public void setName(String name)
	{
		this.name = name;
	}

	public String getName()
	{
		return name;
	}

	public void setAge(int age)
	{
		this.age = age;
	}

	public int getAge()
	{
		return age;
	}

	// 覆写toString方法
	public String toString()
	{
		return this.name+"..."+this.age;
	}

}

class ArrayListTest2 
{
	public static void main(String[] args) 
	{
		ArrayList al = new ArrayList();
		al.add(new Person("haha",21));
		al.add(new Person("okok",22));
		al.add(new Person("haha",21));
		al.add(new Person("Java",23));
		al.add(new Person("lalllala",24));
	
		System.out.println(al);
		al = getSingleElements(al);
		System.out.println(al);

	}

	// 去重
	public static ArrayList getSingleElements(ArrayList al)
	{
		ArrayList temp = new ArrayList();

		for(Iterator it = al.iterator();it.hasNext();)
		{
			Person p = (Person)it.next();
			// 如果集合中没有该元素就将其添加到集合中
			if(!temp.contains(p))
			{
				temp.add(p);
			}
		}
		return temp;
	}
}



Set接口

元素不可以重复,是无序的。

Set接口中的方法和Collection中的方法一致。

有两个常用的子类:

  1. HashSet:内部数据结构是哈希表,是不同步的。
  2. TreeSet:
HashSet简单演示

import java.util.HashSet;
import java.util.Iterator;

class HashSetDemo 
{
	public static void main(String[] args) 
	{
		HashSet hs = new HashSet();
		hs.add("lala");
		hs.add("haha");
		hs.add("lala");
		hs.add("xixi");
		hs.add("java");

		for(Iterator it = hs.iterator();it.hasNext();)
		{
			System.out.println(it.next());
		}
	}
}


HashSet存储原理

HashSet比List的内部结构复杂些,HashSet内部使用的数据结构是哈希表。

在添加元素的时候,通过哈希算法(以及元素自身的特点)算出该元素的位置,然后把该元素存储到算出的位置,但是如果当前位置已有元素占有,

那么,有多种处理方式, 可以顺延,也就是往后判断是否为空位,是的话,就存储在该位置。

具体步骤:

哈希表确定元素是否相同

  1. 判断的是两个元素的哈希值是否相同。如果相同,再判断两个对象的内容是否相同。
  2. 判断哈希值相同,其实就是判断对象的hashCode的方法。判断内容是否相同,用的是equals方法。

注意:如果哈希值不同,是不需要判断equals的。


HashSet存储自定义对象

import java.util.HashSet;
import java.util.Iterator;

/**
 * 需求:演示HashSet存储自定义对象,如果姓名和年龄相同,那么视为同一个人。 
 */

class Person
{
	private String name;
	private int age;

	public Person(){}

	public Person(String name, int age)
	{
		this.name = name;
		this.age = age;
	}

	// 尽可能的让哈希值唯一
	public int hashCode()
	{
		// 因为姓名是字符串,字符串也有自己的哈希值
		return this.name.hashCode() + this.age * 38;
	}

	// 如果两个对象的哈希值相同,那么比较两个对象的内容
	public boolean equals(Object obj)
	{
		// 如果是同一个对象
		if(this==obj)
			return true;

		// 必须是人与人比
		if(!(obj instanceof Person))
			throw new ClassCastException("类型不对!");

		Person p = (Person)obj;
		// System.out.println(this.name+"...equlas..."+p.name);
		return this.name.equals(p.name) && this.age == p.age;
	}

	public void setName(String name)
	{
		this.name = name;
	}

	public String getName()
	{
		return name;
	}

	public void setAge(int age)
	{
		this.age = age;
	}

	public int getAge()
	{
		return age;
	}
}

class HashSetTest 
{
	public static void main(String[] args) 
	{
		HashSet hs = new HashSet();
		hs.add(new Person("haha",21));
		hs.add(new Person("okok",22));
		hs.add(new Person("haha",21));
		hs.add(new Person("Java",23));
		hs.add(new Person("lalllala",24));

		for(Iterator it = hs.iterator();it.hasNext();)
		{
			Person p = (Person)it.next();
			System.out.println(p.getName()+"..."+p.getAge());
		}
	}
}


简单介绍一下LinkedHashSet集合

具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现。

跟HashSet的用法一样,只不过HashSet是无序的,而它是有序的,当然也是元素唯一的。

如果仅需要唯一的话,用HashSet即可解决。


TreeSet

可以对Set集合中的元素进行排序,是不同步的。

如果存储的是字符串对象的话,默认是以字典序排序的。

判断元素唯一性的方式:就是根据比较方法的返回结果是不是0,是0的话,那就视为相同元素,不存入集合。

TreeSet对元素进行排序的方式一:

              让元素自身具有比较的功能,元素就需要实现Comparable接口,并覆盖compareTo方法,自定义自己的比较方法。

如果不要按照对象中具备的自然顺序进行排序。如果对象中不具备自然排序,怎么办呢?

TreeSet对元素进行排序的方式二:

              可以让TreeSet集合自身具备比较功能。

TreeSet存储对象并自定义排序

import java.util.TreeSet;
import java.util.Iterator;

class Person implements Comparable
{
	private String name;
	private int age;

	public Person(){}

	public Person(String name, int age)
	{
		this.name = name;
		this.age = age;
	}

	// 实现了Comparable就要覆盖CompareTo方法
	public int compareTo(Object obj)
	{
		Person p = (Person)obj;
		// 先判断年龄是否相等,如果想到那么判断姓名
		int temp = this.age - p.age;
		return temp == 0?this.name.compareTo(p.name) : temp;
	}

	public void setName(String name)
	{
		this.name = name;
	}

	public String getName()
	{
		return name;
	}

	public void setAge(int age)
	{
		this.age = age;
	}

	public int getAge()
	{
		return age;
	}

	// 覆写toString方法
	public String toString()
	{
		return this.name+"..."+this.age;
	}
}

class TreeSetDemo 
{
	public static void main(String[] args) 
	{
		TreeSet ts = new TreeSet();
		ts.add(new Person("haha",21));
		ts.add(new Person("okok",22));
		ts.add(new Person("haha",21));
		ts.add(new Person("hahahahha",21));
		ts.add(new Person("Java",23));
		ts.add(new Person("lalllala",24));

		for(Iterator it = ts.iterator();it.hasNext();)
		{
			Person p = (Person)it.next();
			System.out.println(p.getName()+"..."+p.getAge());
		}
	}
}


Comparator比较器

自定义一个比较器,实现Comparator接口,覆盖compare方法,自定义排序。在实例化集合的时候,new一个比较器作为参数来构建集合对象,使其拥有比较功能。

import java.util.TreeSet;
import java.util.Iterator;
import java.util.Comparator;

class Person
{
	private String name;
	private int age;

	public Person(){}

	public Person(String name, int age)
	{
		this.name = name;
		this.age = age;
	}

	public void setName(String name)
	{
		this.name = name;
	}

	public String getName()
	{
		return name;
	}

	public void setAge(int age)
	{
		this.age = age;
	}

	public int getAge()
	{
		return age;
	}

	// 覆写toString方法
	public String toString()
	{
		return this.name+"..."+this.age;
	}
}

// 自定义比较器
class MyComparator implements Comparator/*比较器*/
{
	public int compare(Object o1, Object o2)
	{
		Person p1 = (Person)o1;
		Person p2 = (Person)o2;
		// 主条件
		int temp = p1.getName().compareTo(p2.getName());
		return temp == 0 ? p1.getAge() - p2.getAge() : temp;
	}
}

class TreeSetTest 
{
	public static void main(String[] args) 
	{
		TreeSet ts = new TreeSet(new MyComparator());
		ts.add(new Person("haha",21));
		ts.add(new Person("okok",22));
		ts.add(new Person("haha",21));
		ts.add(new Person("hahahahha",21));
		ts.add(new Person("Java",23));
		ts.add(new Person("lalllala",24));

		for(Iterator it = ts.iterator();it.hasNext();)
		{
			Person p = (Person)it.next();
			System.out.println(p.getName()+"..."+p.getAge());
		}
	}
}

泛型

泛型:jdk1.5出现的安全机制。

好处:
  1. 将运行时期的问题ClassCastException转到了编译时期。
  2. 避免了强制转换的麻烦。
何时使用?

当操作的引用数据类型不确定的时候,就使用<>,其实就是靠我们程序员主观判断的啦。将要操作的引用数据类型传入即可。其实<>就是一个用于接收具体引用数据类型的参数范围。

在程序中,只要用到了带有<>的类或者接口,就要明确传入的具体引用数据类型。

Demo

import java.util.ArrayList;
import java.util.Iterator;

class GenericDemo 
{
	public static void main(String[] args) 
	{
		// <Integer> 泛型,指明这个集合存入的数据类型
		ArrayList<Integer> al = new ArrayList<Integer>();

		al.add(1); // 自动装箱
		al.add(2);
		al.add(3);
		al.add(8); 

		Iterator<Integer> it = al.iterator();
		while(it.hasNext())
		{
			System.out.println(it.next());
		}
	}
}

泛型技术是给编译器使用的技术,用于编译时期,确保了类型的安全。

运行时,会将泛型去掉,生成的class文件中是不带泛型的,这个称为泛型的擦除。

为什么要擦除呢?因为为了兼容运行的类加载器。

泛型的补偿:在运行时,通过获取元素的类型进行转换动作。不用使用者再强制转换了。


泛型在集合中的应用

import java.util.TreeSet;
import java.util.Comparator;
import java.util.Iterator;

class Person
{
	private String name;
	private int age;

	Person(){}

	Person(String name, int age)
	{
		this.name = name;
		this.age = age;
	}

	public void setName(String name)
	{
		this.name = name;
	}

	public String getName()
	{
		return name;
	}

	public void setAge(int age)
	{
		this.age = age;
	}

	public int getAge()
	{
		return age;
	}
}

class ComparatorByName implements Comparator<Person>
{
	public int compare(Person p1, Person p2)
	{
		int temp = p1.getName().compareTo(p2.getName());
		return temp == 0 ? p1.getAge() - p2.getAge() : temp;
	}
	
}

class GenericDemo2 
{
	public static void main(String[] args) 
	{
		TreeSet<Person> ts = new TreeSet<Person>(new ComparatorByName());
		ts.add(new Person("abc",25));
		ts.add(new Person("adc",22));
		ts.add(new Person("abe",20));
		ts.add(new Person("abcde",23));
		ts.add(new Person("jhxl",21));

		Iterator<Person> it = ts.iterator();
		while(it.hasNext())
		{
			Person p = it.next();
			System.out.println(p.getName()+" ... "+p.getAge());
		}
	}
}

泛型类

在jdk1.5后,使用泛型来接收类中要操作的引用数据类型,称之为泛型类。

什么时候使用呢?当类中操作的引用数据类型不确定的时候,就使用泛型来表示。

class Tool<T>
{
	private T t;

	public void setT(T t)
	{
		this.t = t;
	}

	public T getT()
	{
		return t;
	}
}

class GenericClassDemo
{
	public static void main(String[] args) 
	{
		// 指定要操作的引用数据类型
		Tool<String> tool = new Tool<String>();
		tool.setT("abc");	// 编译时期不报错
		// tool.setT(4);	// 编译时期报错
		System.out.println(tool.getT());
	}
}

泛型方法

class Tool<T>
{
	private T t;

	public void setT(T t)
	{
		this.t = t;
	}

	public T getT()
	{
		return t;
	}

	// 将泛型定义在方法上.
	public <W> void show(W w)
	{
		System.out.println("show:"+w);
	}

	public void print(T t)
	{
		System.out.println("print:"+t);
	}

	/**
	 * 当方法静态时,不能访问类上定义的泛型。如果静态方法使用泛型,只能将泛型定义在方法上。
	 */
        // 泛型定义在修饰符后面 , 返回值类型的前面
	public static <Y> void method(Y y)
	{
		System.out.println("metohd:"+y);
	}

}

class GenericMethodDemo 
{
	public static void main(String[] args) 
	{
		Tool<String> tool = new Tool<String>();
		tool.show(new Integer(8)); // 可以传入任意引用数据类型,因为泛型定义在方法上
		tool.print("abc"); // 只能是字符串类型的,因为是传入类指定的泛型类型
		Tool.method(new Integer(9));
		Tool.method("hahahha");
	}
}


泛型接口

interface Inter<T>
{
	public void show(T t);
}

class InterImpl <A> implements Inter<A>
{
	public void show(A a)
	{
		System.out.println("show:"+a);
	}
}

class GenericInterfaceDemo 
{
	public static void main(String[] args) 
	{
		// 在实例化的时候,才明确类型
		InterImpl<Integer> ii = new InterImpl<Integer>();
		ii.show(new Integer(111));
	}
}

泛型限定

可以对类型进行限定。

? extends E:接收E类型或者E的子类型对象。上限。

? super E :接收E类型或者E的父类型对象。下限。

一般在存储元素的时候都是用上限的,因为这样取出都是按照上限类型运算的。不会出现类型安全隐患。其实上限用的比较多一些。

什么时候用下限?通常对集合中的元素进行取出操作时,可以使用下限。

在这里演示一下上限,那么下限自然也就明白了!

import java.util.ArrayList;
import java.util.Iterator;

class Person
{
	private String name;	// 名字
	private int age;		// 年龄

	Person(){}

	Person(String name, int age)
	{
		this.name = name;
		this.age = age;
	}

	public void setName(String name)
	{
		this.name = name;
	}

	public String getName()
	{
		return name;
	}

	public void setAge(int age)
	{
		this.age = age;
	}

	public int getAge()
	{
		return age;
	}
}

// 学生类
class Student extends Person
{
	Student(){}

	Student(String name, int age)
	{
		super(name, age);
	}
}

// 工人类
class Worker extends Person
{
	Worker(){}

	Worker(String name, int age)
	{
		super(name, age);
	}

}

class GenericAdvanceDemo 
{
	public static void main(String[] args) 
	{
		// 指定泛型,该集合只存Student类型的元素
		ArrayList<Student> al1 = new ArrayList<Student>();
		al1.add(new Student("stu_one", 11));
		al1.add(new Student("stu_two", 16));
		
		// 指定泛型,该集合只存Worker类型的元素
		ArrayList<Worker> al2 = new ArrayList<Worker>();
		al2.add(new Worker("worker_one", 25));
		al2.add(new Worker("worker_two", 28));

		advanceDemo(al1);
		advanceDemo(al2);
	}

	/**
	 * <? extends Person> 泛型限定,高级货,其实写单写“?”也可以的,但是为了避免传错类型
	 * 比如传入了String的话,就会存在出错的可能,所以,指定是Person或者其子类可以
	 * ?:就是一个通配符
	 */
	public static void advanceDemo(ArrayList<? extends Person> al)
	{
		Iterator<? extends Person> it = al.iterator();
		while(it.hasNext())
		{
			Person p = it.next();
			System.out.println(p.getName()+"---"+p.getAge());
		}
	}
}


Map集合

一次添加一对元素。Collection一次添加一个元素。

Map也称为双列集合,Collection集合称为单列集合。

其实map集合中存储的就是键值对。map集合中必须保证键的唯一性。


常用方法

1,添加。

      value  put(key, value); 返回前一个和key关联的值,如果没有,则返回null


2,删除。

      void  clear(); 清空map集合

      value  remove(key);  根据指定的key删除这个键值对。

3,判断。

      boolean containsKey(key);  根据指定的key判断是否存在这个key

      boolean  containsValue(value);  根据指定的value判断是否存在这个value

      boolean isEmpty();  判断map集合是否为null

4,获取。

      value get(key);  根据key获取值,如果没有该键,则返回null

      int  size();  获取键值对有多少对


import java.util.Map;
import java.util.Set;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Collection;

class MapDemo
{
	public static void main(String[] args) 
	{
		showMapMethod(new HashMap<Integer,String>());
	}

	public static void showMapMethod(Map<Integer,String> map)
	{
		// put方法,返回原来的值
		System.out.println("put:"+map.put(6,"haha")); // null
		System.out.println("put:"+map.put(6,"xixi")); // haha
		map.put(2,"xiaoming");
		map.put(8,"xiaoming");
		map.put(142,"coffeecat");

		// 删除
		System.out.println("remove:"+map.remove(2)); // xiaoming
		System.out.println("map:"+map); //{6=xixi, 142=coffeecat, 8=xiaoming}

		// 判断
		System.out.println("containsKey:"+map.containsKey(8)); // true

		// 获取
		System.out.println("get:"+map.get(142)); // coffeecat
		System.out.println("map:"+map);//{6=xixi, 142=coffeecat, 8=xiaoming}

		/*
		 * 通过Map转成Set可以迭代。
		 * 使用keySet方法,可以获取key的set集合,迭代该集合,就可以取出map中的所有元素。
		 */
		Set<Integer> keySet = map.keySet();
		Iterator<Integer> it = keySet.iterator();
		while(it.hasNext())
		{
			int key = it.next();
			String value = map.get(key);
			System.out.println("key="+key+", value="+value);
		}

		/*
		 * 将Map转成set,还有方法entrySet<Map.Entry<K,V>>;
		 * 该方法将键和值的映射关系作为对象存储到了Set集合中,而这个映射关系的类型就是Map.Entry<K,V>。
		 */
		Set<Map.Entry<Integer,String>> entrySet = map.entrySet();
		Iterator<Map.Entry<Integer,String>> it2 = entrySet.iterator();
		while(it2.hasNext())
		{
			Map.Entry<Integer,String> me = it2.next();
			System.out.println(me.getKey()+"..."+me.getValue());
		}

		Collection<String> values = map.values();
		Iterator<String> it3 = values.iterator();
		while(it3.hasNext())
		{
			System.out.println(it3.next());
		}
	}
}



Map常用的子类:

        |-- HashTable:内部结构是哈希表,是同步的。不允许null作为键,null作为值。

             |--Properties:用来存储键值对型的配置文件的信息,可以和IO技术相结合。

        |--HashMap:内部结构是哈希表,不是同步的。允许null作为键值。

        |--TreeMap:内部结构是二叉树,不是同步的。可以对Map集合中的键进行排序。


TreeMap的演示

import java.util.Map;
import java.util.TreeMap;
import java.util.Iterator;

class Student implements Comparable
{
	private String name;
	private int age;

	Student(){}

	Student(String name, int age)
	{
		this.name = name;
		this.age = age;
	}

	// 覆盖compareTo方法
	public int compareTo(Object obj)
	{
		Student stu = (Student)obj;
		// 优先根据姓名的字典序比较
		int temp = this.name.compareTo(stu.name);
		return temp==0?this.age-stu.age:temp;
	}

	public String toString()
	{
		return name+"..."+age;
	}
}

class TreeMapDemo 
{
	public static void main(String[] args) 
	{
		TreeMap<Student,String> tm = new TreeMap<Student,String>();
		method(tm);
	}

	public static void method(TreeMap<Student,String> tm)
	{
		tm.put(new Student("haha",25),"北京");
		tm.put(new Student("hazy",21),"珠海");
		tm.put(new Student("coffeecat",22),"上海");
		tm.put(new Student("aaa",20),"广州");

		// 迭代
		Iterator<Map.Entry<Student,String>> it = tm.entrySet().iterator();
		while(it.hasNext())
		{
			Map.Entry<Student,String> me = it.next();
			Student key = me.getKey();
			String value = me.getValue();
			System.out.println(key+"::"+value);
		}
	}
}

LinkedHashMap演示

LinkedHashMap,是有序,就是存入的顺序和取出的顺序一致。

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Iterator;

class LinkedHashMapDemo 
{
	public static void main(String[] args) 
	{
		method(new LinkedHashMap<Integer,String>());
	}

	public static void method(LinkedHashMap<Integer,String> lhm)
	{
		lhm.put(5,"Coffee");
		lhm.put(3,"Cat");
		lhm.put(6,"Hazy");
		lhm.put(8,"Color");

		Iterator<Map.Entry<Integer,String>> it = lhm.entrySet().iterator();
		while(it.hasNext())
		{
			Map.Entry<Integer,String> me = it.next();
			Integer key = me.getKey();
			String value = me.getValue();
			System.out.println(key+"..."+value);
		}
	}
}


集合框架工具类——Collections

import java.util.ArrayList;
import java.util.Collections;
import java.util.TreeSet;

class CollectionsDemo
{
	public static void main(String[] args) 
	{
		sortMethod();
		System.out.println();
		mySortMethod();
		System.out.println();
		reverseOrderMethod();
		System.out.println();
		binarySearchMethod();
		System.out.println();
		methodMaxMin();
		System.out.println();
		replaceMethod();
		System.out.println();
		otherMethod();
	}

	// 排序
	public static void sortMethod()
	{
		ArrayList<String> al = new ArrayList<String>();
		al.add("Hazy");
		al.add("Coffee");
		al.add("Hui");
		al.add("Color");
		// 排序前
		System.out.println("排序前:"+al);
		// 排序
		Collections.sort(al);
		// 排序后
		System.out.println("排序后:"+al);
	}

	// 自定义排序
	public static void mySortMethod()
	{
		ArrayList<String> al = new ArrayList<String>();
		al.add("Hazy");
		al.add("Coffee");
		al.add("Hui");
		al.add("Color");

		// 排序前
		System.out.println("排序前:"+al);

		// 排序
		for(int i=0; i<al.size()-1; i++)
		{
			for(int j=i+1; j<al.size(); j++)
			{
				if(al.get(i).compareTo(al.get(j))>0)
				{
					// 方式一
					String temp = al.get(i);
					al.set(i,al.get(j));
					al.set(j,temp);

					// 方式二,指定集合和该集合中两个需要交换位置的元素角标
					// Collections.swap(al,i,j);
				}
			}
		}
		// 排序后
		System.out.println("排序后:"+al);
	}

	// 反转集合
	public static void reverseOrderMethod()
	{
		// TreeSet默认以字典序排序,指定Collections.reverseOrder()后,集合将被反转
		TreeSet<String> ts = new TreeSet<String>(Collections.reverseOrder());
		ts.add("Hazy");
		ts.add("Coffee");
		ts.add("Hui");
		ts.add("Color");
		System.out.println(ts);
	}

	// 获取最大值和最小值
	public static void methodMaxMin()
	{
		ArrayList<Integer> al = new ArrayList<Integer>();
		al.add(12);
		al.add(1);
		al.add(45);
		al.add(88);
		al.add(68);
		int max = Collections.max(al);
		int min = Collections.min(al);
		System.out.println(al);
		System.out.println("max:"+max+"...min:"+min);
	}

	// 折半查找元素
	public static void binarySearchMethod()
	{
		ArrayList<String> al = new ArrayList<String>();
		al.add("Hazy");
		al.add("Coffee");
		al.add("Hui");
		al.add("Color");
		Collections.sort(al);
		// 折半查找字符串"Hui",返回角标
		int index = Collections.binarySearch(al,"Hui");
		System.out.println("Hui的角标:"+index);
	}
	
	public static void replaceMethod()
	{
		ArrayList<String> al = new ArrayList<String>();
		al.add("Hazy");
		al.add("Coffee");
		al.add("Hui");
		al.add("Color");
		al.add("good");
		System.out.println("替换前:"+al);
		Collections.replaceAll(al,"good","Best");
		System.out.println("替换后:"+al);
	}

	public static void otherMethod()
	{
		ArrayList<String> al = new ArrayList<String>();
		al.add("Hazy");
		al.add("Coffee");
		al.add("Hui");
		al.add("Color");
		System.out.println(al);
		Collections.shuffle(al); // 打乱顺序
		System.out.println(al);
	}
}


foreach语句

格式:

for(类型  变量  :  Collection集合|数组)


传统for和高级for的区别?

传统for可以完成对语句执行很多次,因为可以定义控制循环的增量和条件。

高级for是一种简化形式。它必须有被遍历的目标,该目标要么是数组,要么是Collection单例集合。


对数组的遍历如果仅仅是获取数组中的元素,可以使用高级for。

如果要对数组的角标进行操作,建议使用传统for。

import java.util.List;
import java.util.Arrays;

class ForeachDemo 
{
	public static void main(String[] args) 
	{
		String arr[] = {"abc","abcd","abcde"};
		for(String str : arr)
		{
			System.out.println(str);
		}

		System.out.println();

		List<String> list = Arrays.asList(arr); // 将数组转成集合
		for(String str : list)
		{
			System.out.println(str);
		}
	}
}

函数的可变参数和静态导入

import static java.lang.System.*; // 静态导入

class ParamterDemo
{
	public static void main(String[] args) 
	{
		int sum = add(3,14,4,5,6,2,1);
		out.println("sum="+sum);
	}

	/* 
	 * 传入的参数个数不确定
	 * 函数的可变参数。
	 * 其实就是一个数组,但是接受的是数组的元素。
	 * 自动将这些元素封装成数组,简化了调用者的书写。
	 */

	public static int add(int... arr)
	{
		int sum = 0;
		for(int i : arr)
		{
			sum += i;
		}
		return sum;
	}
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值