您的位置:首页 > 职场人生

黑马程序员--Java基础--集合、泛型、其他对象(System、Runtime、Math、Date)

2014-10-23 13:27 1061 查看
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------



1.集合类

1.1为什么出现集合类?

面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一 种方式。

1.2数组和集合类同是容器,有何不同?

数组虽然也可以存储对象,但长度是固定的;集合长度是可变的。数组中可以存储基本数据类型,集合只能存储对象。

1.3集合类的特点

1.用于存储对象的容器。

2.集合的长度是可变的。

3.集合中不可以存储基本数据类型值。

2.集合框架



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

3.框架的顶层Collection接口

Collection的常见方法:

1.添加

boolean add(Object obj):

boolean addAll(Collection coll):

2.删除

boolean remove(object obj):

boolean removeAll(Collection coll);

void clear();

3.判断

boolean contains(object obj):

boolean containsAll(Colllection coll);

boolean isEmpty():判断集合中是否有元素。

4.获取:

int size():

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

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

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

迭代是取出集合中元素的一种方式。

因为Collection中有iterator方法,所以每一个子类集合对象都具备迭代器。

5.其他:

boolean retainAll(Collection coll);取交集。

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



4.Collection的两大子接口

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

|-- Set(集):元素不能重复,无序。

4.1 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);

list集合是可以完成对元素的增删改查。

>>List集合包含:

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

vector 特有的方法:

1.添加

addElement(Object);

2.获取

Enumeration();

|--addElement(Object);

|--nextElement();

public class VectorDemo {

	public static void main(String[] args) {

		Vector v = new Vector();
		
		v.addElement("abc1");
		v.addElement("abc2");
		v.addElement("abc3");
		v.addElement("abc4");
		
		Enumeration en = v.elements();//vector特有的方法
		while(en.hasMoreElements()){
			System.out.println("nextelment:"+en.nextElement());
		}
		
		Iterator it = v.iterator();//共有迭代器
		
		while(it.hasNext()){
			System.out.println("next:"+it.next());
		}
		
	}

}


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

LinkedList一些常用方法:

1.添加

在此列表的开头插入指定的元素。

void addFirsrt(Object)

Boolean offerFirst(Object)

在此列表的结尾插入指定的元素。

void addLast(Object)

Boolean offerLast(Object)

2.修改

将此列表中指定位置的元素替换为指定的元素。

Object set(int index,Object obj)

3.获取

获取但不移除此列表的第一个元素

Object getFirst():如果此列表为空,则抛异常。

Object peakFirst():如果此列表为空,则返回 null。

获取但不移除此列表的最后一个元素

Object getLast():如果此列表为空,则抛异常。

Object peakLast():如果此列表为空,则返回 null。

4.删除

获取并移除此列表的第一个元素;

Object removeFirst():如果此列表为空,则抛异常。

Object pollFirst():如果此列表为空,则返回 null。

获取并移除此列表的最后一个元素;

Object removeLast():如果此列表为空,则抛异常。

Object pollLast():如果此列表为空,则返回 null。

/*
 * 请使用一个LinkedList来模拟一个堆栈或者队列数据结构
 * 堆栈:先进后出
 * 队列:先进先出
 * 创建一个容器
 */

class DuiLie {
	private LinkedList list;

	DuiLie() {
		list = new LinkedList();

	}

	void myAdd(Object obj) {
		list.addLast(obj);
	}

	public Object myGet() {

		return list.removeFirst();
	}

	public Boolean isNull() {
		return list.isEmpty();

	}

}

public class LinkedListTest {

	public static void main(String[] args) {

		DuiLie dl = new DuiLie();
		dl.myAdd("abc1");
		dl.myAdd("abc2");
		dl.myAdd("abc3");

		while (!dl.isNull()) {

			System.out.println(dl.myGet());

		}

	}

}


4.1.3 ArrayList:内部是数组数据结构,是不同步的。查询很快。

ArrayList()构造一个初始默然容量为 10 的空列表。

/*
 * 去除ArrayList中重复元素
 * 
 */
public class ArrayListTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//创建一个ArrayList容器
		ArrayList al=new ArrayList();
		
		al.add("abc1");
		al.add("abc2");
		al.add("abc1");
		al.add("abc1");
		al.add("abc3");
		System.out.println(al);
		al=getSingleElements(al);
		System.out.println(al);

	}

	public static ArrayList getSingleElements(ArrayList al) {
		// TODO Auto-generated method stub
		//新建一个ArrayList容器装
		ArrayList temp=new ArrayList();
		//获取迭代器
		Iterator it=al.iterator();
		
		while(it.hasNext()){
			Object obj=it.next();
			if(!temp.contains(obj))
				temp.add(obj);
		}
		return temp;
	}

}


4.2 Collection--->>set

set:集合中元素不可以重复。

set集合包含:

4.2.1 hashdSet:内部数据结构是哈希表,线程不安全,存取速度快。

HashSet:通过equals方法和hashCode 方法来保证元素的唯一性。

注:如果元素要存储到HashSet中,必须覆盖HashCode和equals方法。

public class HashSetDemo2 {

	public static void main(String[] args) {
		HashSet hs = new LinkedHashSet();

		hs.add(new Person("abc1", 21));
		hs.add(new Person("abc2", 22));
		hs.add(new Person("abc2", 23));
		hs.add(new Person("abc2", 24));
		hs.add(new Person("abc2", 22));// 会出现两个abc2
		Iterator it = hs.iterator();

		while (it.hasNext()) {
			Person p = (Person) it.next();
			System.out.println("name:" + p.getName() + ".." + "age:"
					+ p.getAge());
		}
	}
}


4.2.2TreeSet:线程不安全,可以对Set集合中的元素进行排序。

TreeSet:通过compareTo或者compare 方法中的来保证元素的唯一性。元素是以二叉树的形式存 放的。

TreeSet排序1:

让元素具备排序功能,元素就必须实现Comparable接口,覆盖compareTo方法。

TreeSet排序2:

用比较器的方法让集合自身具备比较功能,先定义一个类实现Comparator接口,覆盖compare方法,将该类对象作为参数传递给TreeeSet的构造函数。

/*
 *对字符串按长度排序 
 * 
 */
public class TreeSetTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		TreeSet ts = new TreeSet(new ComparatorByLength());
		ts.add("aaaa");
		ts.add("gdaa");
		ts.add("gd");
		ts.add("hjt");
		ts.add("zss");

		Iterator it = ts.iterator();

		while (it.hasNext()) {
			System.out.println(it.next());
		}

	}

}
 class ComparatorByLength implements Comparator{

	@Override
	public int compare(Object o1, Object o2) {
		// TODO Auto-generated method stub
		String st1=(String)o1;
		String st2=(String)o2;
		int temp=st1.length()-(st2.length());
		
		return temp==0?st1.compareTo(st2):temp;
	}
 }


4.3 Map

Map:一次添加一对元素,也叫双集合。其实Map集合中存储的是键值对。Map集合中必须保证键值的唯一性。

常用方法:

1.添加

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

2.判断

boolean containsKey(key)

boolean containsValue(value)

boolean isEmpty();

3.获取

value get(key):通过键获取值,如果没有该键则返回null;当然可以通过是否返回null来判断是否包含指定键。

4.删除

void clear();清空集合

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

注:Map存相同的键值会覆盖。

public class MapDemo {

		public static void main(String[] args) {
			
			Map<Integer,String> map = new HashMap<Integer,String>();
			map.put(8,"zhaoliu");
			map.put(2,"zhaoliu");
			map.put(7,"zhouqi");
			map.put(6,"niuba");
			method(map);
			method_2(map);
		}
		
		public static void method_2(Map<Integer,String> map){
			//通过值集合取值
			Collection<String> values = map.values();
			Iterator<String> it2 = values.iterator();
			while(it2.hasNext()){
				System.out.println(it2.next());
			}
			
			/*
			 * 通过Map转成set就可以迭代。
			 * 找到了另一个方法。entrySet。
			 * 该方法将键和值的映射关系作为对象存储到了Set集合中,而这个映射关系的类型就是Map.Entry类型
			 */
			Set<Map.Entry<Integer, String>> entrySet = map.entrySet();
			
			Iterator<Map.Entry<Integer, String>> it = 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);
				
			}
		}
			
			
	public static void method(Map<Integer,String> map){
			//取出map中的所有元素。
			//原理,通过keySet方法获取map中所有的键所在的Set集合,在通过Set的迭代器获取到每一个键,
			//在对每一个键通过map集合的get方法获取其对应的值即可。
			
			Set<Integer> keySet = map.keySet();
			Iterator<Integer> it = keySet.iterator();
			
			while(it.hasNext()){
				Integer key = it.next();
				String value = map.get(key);
				System.out.println(key+":"+value);
				
			}
			
		}
		
		
	}


4.4 Map常用的子类

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

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

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

Properties:用来存储键值对行的配置文件信息。

5.泛型(JDK1.5新特性)

5.1.1 泛型的特点

提高了程序的安全性
将运行期遇到的问题转移到了编译期
省去了类型强转的麻烦
泛型类的出现优化了程序设计

5.1.2 泛型的使用:

当操作的引用型数据类型不确定的时候就使用泛型<>,将要操作的引用数据类型传入即可,其实泛型<>就是一个用于接收具体引用数据类型的参数范围,在程序中只要用到带有<>的就要明确具体引用数据类型。

5.1.3 泛型的擦除:

泛型技术是给编译器使用的技术,在编译时使用确保了数据类型的安全,运行时会将泛型擦去,生成的class的文件中是不带泛型的,这个称为泛型的擦除(其实是为兼容以前的类加载器)。

5.1.4 泛型的补偿:

运行时通过获取元素的类型进行转换动作,不用使用者再强行转换。

注:当方法是静态的时候,不能访问类定义的泛型,如果静态方法使用泛型,只能将泛型定义在方法上。

5.1.5泛型的上限:

泛型的通配符:?

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

一般在存储元素时都是用上限,因为取出时都是按照上限类来运算的,不会出现安全隐患。

5.1.6泛型的下限:

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

通常在对元素进行取出操作时使用下限。

public class MapDemo {

		public static void main(String[] args) {
			
			Map<Integer,String> map = new HashMap<Integer,String>();//<>泛型的使用
			map.put(8,"zhaoliu");
			map.put(2,"zhaoliu");
			map.put(7,"zhouqi");
			map.put(6,"niuba");
	
			//通过值集合取值
			Collection<String> values = map.values();//<>泛型的使用
			Iterator<String> it2 = values.iterator();//<>泛型的使用
			while(it2.hasNext()){
				System.out.println(it2.next());
			}
		}
}


6.集合的使用技巧:

1.需要唯一性:Set

需要制定顺序:TreeSet

不需要制定顺序:HashSet

想要一个和存储一致的顺序(有序):LinkedHashSet

2.不需要唯一性:List

需要频繁增删:LinkedList

不需要频繁增删:ArrayList

7.集合框架工具类

7.1.1Collections:里面的方法都是静态的。

常用方法:

void sort(List<T> list);自然排序

int binarySearch(List<? extends Comparable<? super T>> list, T key):二分法查找

void reverseOrder(List<T> list):反转

void fill(List<? super T> list, T obj):全部替换

void shuffle(List<T> list):随机排列替换

7.1.2 Arrays:里面的方法都是静态的。

常用方法:

asList():将数组转成集合(以调用集合的方法)

注意:

1.如果数组中的元素是对象,那么转成集合时,直接将数组中的元素作为集合中的元素进行集合存储。

2.如果数组中的元素是基本类型数值,那么会将该数组作为集合中的元素进行存储。

3.数组的长度是固定的,所以对于集合的增删方法是不可以使用的否则会发生UnsupportedOperationException

7.1.3 Collection:

Object[ ]
toArray():将集合转成数组(可以对集合中的元素操作的方法进行限定。不允许对其进行增删。)

<T>[ ] toArray(T[] a):将集合转成数组(可以对集合中的元素操作的方法进行限定。不允许对其进行增删。)

toArray方法需要传入一个指定类型的数组。

如何确认数组长度?

1.如果长度小于集合的size(),那么该方法就创建一个与集合相同size()的数组。

2.如果长度大于集合的size(),难么该方法就使用指定的数组存储集合的元素,其他位置默认为null。

8.增强for(JDK1.5新特性)

8.1 格式:

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

8.2 传统for和高级for的区别?

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

2.高级for是传统for一种简化形式。

3.它必须有被遍历的目标。该目标要是数组,要么是Collection单列集合。

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

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

注:不可以直接使用高级for遍历map,但是如果可以将map转成单列的set,就可以用了。

public class ForeachDemo {
	public static void main(String[] args) {
		Map<Integer, String> map = new HashMap<Integer, String>();

		map.put(3, "zhagsan");
		map.put(1, "wangyi");
		map.put(7, "wagnwu");
		map.put(4, "zhagsansan");

		for (Integer key : map.keySet()) {// 高级for
			String value = map.get(key);
			System.out.println(key + "..." + value);
		}

		for (Map.Entry<Integer, String> me : map.entrySet()) {// 高级for
			Integer key = me.getKey();
			String value = me.getValue();
			System.out.println(key + ":" + value);
		}

	}
}


9.可变参数函数(JDK1.5新特性)

函数的可变参数:

其实就是一个数组,但是接收的是数组的元素。自动将这些元素封装成数组。简化了调用者的书写。

注意:可变参数类型,必须定义在参数列表的结尾。

public class ParemterDemo {

	public static void main(String[] args) {
		int sum = newAdd(5,1,4,7,3);
		System.out.println("sum="+sum);
		int sum1 = newAdd(5,1,2,7,3,9,8,7,6);
		System.out.println("sum1="+sum1);
		
	}

	public static int newAdd(int a,int...  arr){//可变参数类型
		
		int sum = 0;
		for (int i = 0; i < arr.length; i++) {
			sum+=arr[i];
		}
		return sum;
	}
}


10.静态导入

静态导入:其实导入的是类静态中的静态成员。

import static java.util.Collections.*;//静态导入
import static java.lang.System.*;//静态导入
public class StaticImportDemo {

		public static void main(String[] args) {

			List<String> list = new ArrayList<String>();
			
			list.add("abc3");
			list.add("abc7");
			list.add("abc1");
			
			out.println(list);//可省掉类名System的书写
			
			sort(list);//可省掉类名Collections的书写
			
			System.out.println(list);
			
			
			String max = max(list);
			System.out.println("max="+max);
			
		}

	}


11.其他对象

11.1System:类中的方法和属性都是静态的。

常见的方法:

long currentTimeMillis();获取当前时间的毫秒值。

getProperties():获取系统信息

String getProperty(String key):获取指定系统信息

setProperties(Properties props):设置系统信息

String setProperty(String key, String value):设置指定键的系统信息

gc():运行垃圾回收器。

public class SystemDemo {
	//获取line.separator的系统信息并把它作为一个常量使用
		private static final String LINE_SEPARATOR = System.getProperty("line.separator");//获取line.separator
		public static void main(String[] args) {
			
			long l = System.currentTimeMillis();//获取当前时间的毫秒值
			System.out.println(l);
			System.out.println("hello-"+LINE_SEPARATOR+" world");
			//给系统设置一些属性信息。这些信息是全局,其他程序都可以使用。 
			System.setProperty("myclasspath", "D:\\myclass");
			demo_1();
			
		}
		//获取系统信息并遍历
		public static void demo_1(){
		
			Properties prop = System.getProperties();//获取系统信息
			
			Set<String> nameSet = prop.stringPropertyNames();
			
			for(String name : nameSet){
				String value = prop.getProperty(name);
				
				System.out.println(name+":"+value);
			}
			
		}
		
}


11.2 Runtime

Runtime:没有构造方法摘要,说明该类不可以创建对象。

又发现还有非静态的方法。说明该类应该提供静态的返回该类对象的方法。

而且只有一个,说明Runtime类使用了单例设计模式。

常用的方法:

runtime getRuntime():返回与当前 Java 应用程序相关的运行时对象。

exec("指定程序路径或名称"):执行某个程序

public class RuntimeDemo {

	public static void main(String[] args) throws IOException, InterruptedException {

		Runtime rt = Runtime.getRuntime();
		
		Process p = rt.exec("qq.exe");//执行某某程序
		Thread.sleep(4000);//线程等待
		p.destroy();//杀掉程序
	}

}


11.3 Math

Math:提供了操作数学运算的方法。都是静态的。

常用的方法:

abs():返回一个数的绝对值。

ceil():返回大于参数的最小整数。

floor():返回小于参数的最大整数。

round():返回四舍五入的整数。

pow(a,b):a的b次方。

random():0.0-1.0之间的随机数。

randomDouble():随机数

randomInt():随机数

public class MathDemo {

	public static void main(String[] args) {

		double d1 = Math.ceil(12.56);// 12.0
		double d2 = Math.floor(12.56);// 13.0
		double d3 = Math.round(12.46);// 12.0
		System.out.println(d3);

		Random r = new Random();
		for (int i = 0; i < 10; i++) {
			double d = Math.ceil(Math.random() * 10);
			System.out.println(d);
		}
	}

}


11.4 Date

1.日期对象和字符串之间的转换

1.1.将日期格式的字符串-->日期对象。

使用的是DateFormat类中的parse()方法。

1.2.将日期对象-->日期格式的字符串。

使用的是DateFormat类中的format方法。

2.日期对象和毫秒值之间的转换。

2.1毫秒值-->日期对象 :

1.通过Date对象的构造方法 new Date(timeMillis);

2.还可以通过setTime设置。

因为可以通过Date对象的方法对该日期中的各个字段(年月日等)进行操作。

2.2 日期对象-->毫秒值:

getTime方法。

因为可以通过具体的数值进行运算。

public class DateDemo {

		public static void main(String[] args) throws ParseException {
			methodDemo_1();
			methodDemo_2();
			methodDemo_3();
		}
		
	/*将日期格式的字符串-->日期对象。
	*使用的是DateFormat类中的parse()方法。 
	*/
		public  static void methodDemo_3() throws ParseException {
			
			String str_date = "2013---8---21";
					
			DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.LONG);
			
			dateFormat = new SimpleDateFormat("yyyy---MM---dd");
			
			Date date = dateFormat.parse(str_date);//将日期格式的字符串-->日期对象。
			
			System.out.println(date);
			long time = date.getTime();//日期对象的毫秒值
			System.out.println(time);
			
		}

		public static void methodDemo_2() {
			
			Date date = new Date();
			
			//获取日期格式对象。具体着默认的风格。 FULL LONG等可以指定风格。
			DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.LONG);
			dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG,DateFormat.LONG);
			
			//自定义风格
			dateFormat = new SimpleDateFormat("yyyy:MM:dd");
			
			String str_date = dateFormat.format(date);
			
			System.out.println(str_date);
		}

		public static void methodDemo_1() {
			long time = System.currentTimeMillis();//将日期转换成毫秒值

			Date date = new Date();//将当前日期和时间封装成Date对象。
			System.out.println(date);
			
			Date date2 = new Date(time);//将指定毫秒值封装成Date对象。
			System.out.println(date2);
		}
		
	}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐