关闭

黑马程序员—Java集合框架及Java中的几个工具类

标签: java语言
338人阅读 评论(0) 收藏 举报

9.集合类

 

特点:

1)对象封装数据,对象多了也需要存储。集合用于存储对象。

2)对象的个数确定可以使用数组,但是不确定怎么办?可以用集合。因为集合是可变长度的。

 

集合和数组的区别:

1)数组是固定长度的;集合可变长度的。

2)数组可以存储基本数据类型,也可以存储引用数据类型;集合只能存储引用数据类型。

3)数组存储的元素必须是同一个数据类型;集合存储的对象可以是不同数据类型。

 

对于集合容器,有很多种。因为每一个容器的自身特点不同,其实原理在于每个容器的内部数据结构(存储数据的方式)不同。

集合容器在不断向上抽取过程中。出现了集合体系。

 

 

 

9.1 共性方法

 

集合(collection)是接口,两个常见的子接口为List和Set

 

1)添加:

    add(object):  添加一个元素

    addAll(Collection) :添加一个集合中的所有元素。

2)删除:

    clear():  将集合中的元素全删除,清空集合。

    remove(obj) :  删除集合中指定的对象。注意:删除成功,集合的长度会改变。

    removeAll(collection) :  删除部分元素。部分元素和传入Collection一致。

3)判断:

    boolean contains(obj) :  集合中是否包含指定元素 。

    boolean containsAll(Collection) :  集合中是否包含指定的多个元素。

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

4)获取:

    int size():集合中有几个元素。

5)取交集:

    boolean retainAll(Collection) :对当前集合中保留和指定集合中的相同的元素。如果两个集合元素相同,返回flase;如果retainAll修改了当前集合,返回true。

6)获取集合中所有元素:

    Iterator  iterator():迭代器

7)将集合变成数组:

    toArray();

import java.util.*;                                 //需要导入包
class CollectionDemo 
{
	public static void base_method() 
	{
		//创建集合容器,使用Collection接口的子类ArrayList
		ArrayList al = new ArrayList();
		//添加元素
		al.add("java01");                   //add(Object obj);
		al.add("java02");
		al.add("java03");
		al.add("java04");
		//获取个数,集合长度
		sop("size:"+al.size());
		//打印集合
		sop(al);                           //结果为[java01, java02, java03, java04]
		//删除元素
		al.remove("java02");               //删除后,长度也变短了
		//清空集合
		al.clear();
		//判断元素
		sop("java03是否存在:"+al.contains("java03"));
		sop("集合是否为空"+al.isEmpty());
	}
	public static void method_2()
	{
		ArrayList al1 = new ArrayList();
		al.add("java01");
		al.add("java02");
		al.add("java03");
		al.add("java04");
		ArrayList al2 = new ArrayList();
		al2.add("java01");
		al2.add("java02");
		al2.add("java05");
		al2.add("java06");

		al1.retainAll(al2);                //取交集,al1中只会保留和al2中相同的元素
		al1.removeAll(al2);                //将al1中与al2中相同的元素去除
	}
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}

注意:

1)add方法的参数类型是object,以便于接收任意类型的对象

2)集合中存储的都是对象的引用(地址)


9.2 迭代器

 

迭代器(Iterator)是一个接口,是集合的取出元素的方式

 boolean

hasNext()  如果仍有元素可以迭代,则返回 true

 E

next()   返回迭代的下一个元素。

 void

remove()  从迭代器指向的 collection 中移除迭代器返回的最后一个元素(可选操作)。

每一个集合都有自己的数据结构,都有特定的取出自己内部元素的方式。为了便于操作所有的容器,取出元素。将容器内部的取出方式按照一个统一的规则向外提供,这个规则就是Iterator接口

public static void method_get()
	{
		Collection coll = new ArrayList();
		coll.add("java01");
		coll.add("java02");
		coll.add("java03");
		coll.add("java04");
<span style="white-space:pre">		</span>//方式一
		Iterator it = coll.iterator();         //调用集合实现类中的iterator()方法获取迭代器
		while(it.hasNext())                    //hasNext(),当仍有元素可以迭代,则返回true
		{
			sop(it.next());
		}
<span style="white-space:pre">		</span>//方式二
		for (Iterator it = coll.iterator();it.hasNext() ; ) //循环结束后对象it会释放,此代码更优
		{	
			sop(it.next());
		}
	}



9.3 List接口

 

List接口是Collection接口的子类

List:元素是有序的,元素可以重复,因为该集合体系有索引


特有方法:凡是可以操作角标的方法都是该体系特有的方法(以ArrayList为例)

1)  增

add(index,element);

addAll(index,Collection);

2)  删

remove(index);

3)  改

set(index,element);

4)  查

get(index);

subList(from,to);

listIterator();

public static void method()
	{
		List list = new ArrayList();
		//添加元素
		list.add("java01");
		list.add("java02");
		list.add("java03");
		//在指定位置添加元素
		list.add(1,"java09");                           //该index后的元素会向后顺延
		//删除指定位置的元素
		list.remove(2);
		//修改元素
		list.set(2,"java07");
		//通过角标获取元素
		list.get(1);
		//获取所有元素
		for (int x =0;x< list.size() ;x++ )             //集合子类用size()获取长度
		{
			System.out.println("list ("+")= "+ list.get(x));
		}
		Iterator it = list.iterator();
		while(it.hasNext())
		{
			sop("next:"+it.next());
		}
		//通过indexOf获取对象的位置
		sop("index="+ list.indexOf("java02"));
		List sub = list.subList(1,3);                   //含头不含尾
	} 


List集合特有的迭代器:ListIteratorIterator的子接口

在进行list列表迭代时,不可以通过集合对象的方法操作集合中的元素,比如添加新元素,因为会发生ConcurrentModificationException异常。

导致的原因是:集合引用和迭代器引用在同时操作元素,通过集合获取到对应的迭代器后,在迭代中,进行集合引用的元素添加,迭代器并不知道,所以会出现异常情况。

所以,在迭代器时,只能用迭代器的方法操作元素,可是Iterator方法时有限的,只能对元素进行判断,取出,删除的操作。

如果想要其他的操作(如添加,修改等),就需要使用其子接口,ListIterator。该接口只能通过List集合的listIterator方法获取

方法摘要

 void

add(E e) 将指定的元素插入列表(可选操作)。

 boolean

hasNext() 以正向遍历列表时,如果列表迭代器有多个元素,则返回 true(换句话说,如果 next 返回一个元素而不是抛出异常,则返回 true)。

 boolean

hasPrevious() 如果以逆向遍历列表,列表迭代器有多个元素,则返回 true

 E

next() 返回列表中的下一个元素。

 int

nextIndex() 返回对 next 的后续调用所返回元素的索引。

 E

previous() 返回列表中的前一个元素。

 int

previousIndex() 返回对 previous 的后续调用所返回元素的索引。

 void

remove() 从列表中移除由 nextprevious 返回的最后一个元素(可选操作)。

 void

set(E e) 用指定元素替换 nextprevious 返回的最后一个元素(可选操作)。



List子类对象:

1)  ArrayList

底层的数据结构使用的是数组结构,线程不同步

特点:查询速度很快,但是增删稍慢

2)  LinkedList

底层的数据结构使用的是链表数据结构

特点:增删速度很快,查询稍慢

3)  Vector

底层是数组数据结构,线程同步,被ArrayList替代


LinkedList特有方法:

addFirst();

addLast();

在JDK1.6中出现以上方法替代方法:

offerFirst()

offerLast()

 

getFirst();     //获取元素,但不删除元素

getLast();               //如果列表为空,此操作会抛出NoSuchElementException异常

在JDK1.6中出现以上方法替代方法:

peekFirst()     //获取但不移除此列表的第一个元素,如果列表为空,则返回null

peekLast()


removeFirst();  //获取元素,但是元素被删除

removeLast();  //如果列表为空,此操作会抛出NoSuchElementException异常

在JDK1.6中出现以上方法替代方法:

pollFirst();     //获取并移除此列表的第一个元素,如果列表为空,则返回null

pollLast()

public static void main(String[] args) 
	{
		LinkedList link = new LinkedList();
		link.addFirst("java01");
		link.addFirst("java02");
		link.addFirst("java03");
		link.addFirst("java04");
		sop(link);                        //输出结果为倒叙
	}

利用List接口特点,将自定义对象作为元素存到ArrayList集合中,并去除重复元素:

import java.util.*;
class ArrayListTest2 
{
	public static void main(String[] args) 
	{
		ArrayList al = new ArrayList();
		al.add(new Person("lisi01",30));
		al.add(new Person("lisi02",31));
		al.add(new Person("lisi02",31));
		al.add(new Person("lisi03",32));
		al.add(new Person("lisi04",33));
		al.add(new Person("lisi04",33));
		
		al = singleElement(al);
		Iterator it = al.iterator();
		while (it.hasNext())
		{
			Person p =(Person)it.next();         //it.next()得到是Object父类的多态,转型为Person类型才能调用Person中的方法
			sop(p.getName()+"::"+p.getAge());
		}
	}
	public static ArrayList singleElement(ArrayList al)
	{
		ArrayList newAl = new ArrayList();
		Iterator it = al.iterator();
		while(it.hasNext())
		{
			Object obj = it.next();
			if (!newAl.contains(obj))	     //contains的原理是调用equals方法
				newAl.add(obj);
		}
		return newAl;
	}
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}
class Person
{
	private String name;
	private int age;
	Person(String name,int age)
	{
		this.name = name;
		this.age = age;
	}
	public boolean equals(Object obj)     //默认方法对于对象,是判断对象的地址是否相同<span style="font-family: Arial, Helvetica, sans-serif;">所以要判断对象中内容时,需要重新定义</span>
	{                                 
		if(!(obj instanceof Person)) //判断输入的对象是否是Person类型的
			return false;
		Person p = (Person)obj;
		return this.name.equals(p.name) && this.age == p.age;
	}
	public String getName()
	{
		return name;
	}
	public int getAge()
	{
		return age;
	}
}

List集合判断元素是否相同,依据的是元素的equals方法。remove方法也调用了equals方法判断要删除的元素是否存在于集合中



9.4Set接口

 

Set:元素无序(存入和取出的顺序不一定一致),元素不可以重复

 

Set集合的功能和Collection是一致的, Set接口取出方式只有一种,迭代器。

 

Set 子类对象:

1)  HashSet

底层数据结构是哈希表,线程时非同步的,无序,高效

//往HashSet集合中存入自定义对象
import java.util.*;
class HashSetDemo 
{
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
	public static void main(String[] args) 
	{
		HashSet hs = new HashSet();
		hs.add(new Person("a1",11));
		hs.add(new Person("a2",12));
		hs.add(new Person("a3",13));
		hs.add(new Person("a2",12));
		Iterator it = hs.iterator();
		while (it.hasNext())
		{
			Person p = (Person)it.next();
			sop(p.getName()+"::"+p.getAge());   //相同元素不会存入
		}
	}
}
class Person
{
	private String name;
	private int age;
	Person(String name,int age)
	{
		this.name = name;
		this.age = age;
	}<pre name="code" class="java"><span style="white-space:pre">	</span>//HashSet存入时是先用哈希值判断是否有重复内容,<span style="font-family: Arial, Helvetica, sans-serif;">当存入对象时,各个对象的哈希值是根据地址值</span><span style="font-family: Arial, Helvetica, sans-serif;">计算的,所以要判断对象中的内容是否相同时, </span><span style="font-family: Arial, Helvetica, sans-serif;">需要重新定义给对象赋予哈希值的方法</span>
public int hashCode()
{ return name.hashCode()+age*63; } public boolean equals(Object obj) //hashCode相同时再调用equals方法判断对象{if(!(obj instanceof Person)) return false;Person p = (Person)obj;return this.name.equals(p.name) && this.age == p.age;}public String getName(){return name;}public int getAge(){return age;}}

HashSet是如何保证元素唯一性的?

是通过元素的两个方法,hashCodeequals来完成

如果元素的hashCode值相同,才会判断equals是否为true

如果元素的hashCode值不同,不会调用equals

对于判断元素是否存在(contains()),以及删除(remove())等操作,依赖的方法是元素的hashCode和equals方法


当一个对象被存储进HashSet集合中以后,就不能修改这个对象中的那些参与计算哈希值的字段了。否则,对象修改后的哈希值与最初存储进HashSet集合中的哈希值就不同了,在这种情况下,即使在contains方法使用该对象的当前引用作为的参数去HashSet集合中检索对象,也将返回找不到对象的结果,这也会导致无法从HashSet集合中单独删除当前对象,从而造成内存泄露。


2)  TreeSet

可以对Set集合中的元素进行排序,排序需要依据元素自身具备的比较性。如果元素不具备比较性,在运行时会发生ClassCastException异常。

底层数据结构是二叉树。

//往TreeSet集合中存入自定义对象
import java.util.*;
class TreeSetDemo 
{
	public static void main(String[] args) 
	{
		TreeSet ts = new TreeSet();

		ts.add(new Student("lisi02",22));
		ts.add(new Student("lisi07",20));
		ts.add(new Student("lisi09",19));
		ts.add(new Student("lisi01",40)); 

		Iterator it = ts.iterator();
		while (it.hasNext())
		{
			Student s = (Student)it.next();
			System.out.println(s.getName()+"::"+s.getAge());
		}
	}
}
class Student implements Comparable       //该接口强制让Student具备比较性
{
	private String name;
	private int age;
	Student(String name,int age)
	{
		this.name = name;
		this.age = age;
	}
	public String getName()
	{
		return name;
	}
	public int getAge()
	{
		return age;
	}<pre name="code" class="java"><span style="white-space:pre">	</span>//TreeSet会对传入的元素自然排序,<span style="font-family: Arial, Helvetica, sans-serif;">排序是调用compareTo方法来比较</span><span style="font-family: Arial, Helvetica, sans-serif;">,因此要在自定义对象中重写compareTo方法</span>

	public int compareTo(Object obj)        <span style="font-family: Arial, Helvetica, sans-serif;">
</span>
	{								   
		if(!(obj instanceof Student))		   
			throw new RuntimeException("不是学生对象");
		Student s = (Student)obj;
		if(this.age>s.age)
			return 1;
		if(this.age==s.age)
		{
			return this.name.compareTo(s.name);     //当age相同时,比较字符串顺序
		}
		return -1;
	}
}

TreeSet是如何保证元素唯一性的?

compareTo方法return 0

 

TreeSet排序的第一种方式:让元素自身具备比较性,元素需要实现Comparaable接口,覆盖compareTo方法。这种方式也称为元素的自然顺序,或者叫做默认顺序。

TreeSet排序的第二种方式:当元素自身不具备比较性时,或者具备的比较性不是所需要的,这时就需要让集合自身具备比较性(Comparator)。在集合初始化时,就有了比较方式。

当两种排序都存在时,以比较器为主。

定义比较器:定义一个类,实现Comparator接口,覆盖compare方法。

//按照字符串长度排序
import java.util.*;
class TreeSetTest 
{
	public static void main(String[] args) 
	{
		TreeSet ts = new TreeSet(new StrLenComparator());

		ts.add("abcd");
		ts.add("cc");
		ts.add("cba");
		ts.add("aaa");
		ts.add("z"); 
		ts.add("hahaha"); 

		Iterator it = ts.iterator();
		while (it.hasNext())
		{
			System.out.println(it.next());
		}
	}
}
class StrLenComparator implements Comparator
{
	public int compare(Object o1,Object o2)
	{
		String s1 = (String)o1;
		String s2 = (String)o2;
		int num = new Integer(s1.length()).compareTo(new Integer(s2.length()));
		if(num==0)
			return s1.compareTo(s2);       //长度相同比较内容
		return num;
	}
}



9.5 泛型

 

JDK1.5版本后出现的新特性,用于解决安全问题,是一个安全机制。

ArrayList<String> al = newArrayList<String>();           //泛型就是指定容器内元素的类型

Iterator<String> it = al.iterator();

 

好处:

1)  将运行时期出现的问题ClassCastException转移到了编译时期,方便于程序员解决问题,

让运行时期问题减少,安全

2)  避免了强制转换的麻烦

 

泛型格式:通过<>来定义要操作的引用数据类型

在使用java提供的对象时,什么时候写泛型?

通常在集合框架中很常见,只要见到<>就要定义泛型。其实<>就是用来接收类型的。

当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可

 

class LenComparator  implements Comparator<String>          //使用泛型,避免了强转

{

         publicint compare(String s1,String s2)

         {

                   int num = s1.length()-s2.length();

                   if(num==0)

                            returns1.compareTo(s2);

                   return num;

         }

}


1泛型类

 

什么时候定义泛型类?

当类中要操作的引用数据类型不确定的时候,早期定义Object来完成扩展,现在定义泛型来完成扩展。

class GenericDemo3 
{
	public static void main(String[] args) 
	{
		Utils<Worker> u = new Utils<Worker>();
		u.setObject(new Worker());             //无需强转,且如果传入Student类时<span style="font-family: Arial, Helvetica, sans-serif;">会在编译时报错</span>
		Worker w = u.getObject();              
		/*  
		Tool t = new Tool();
		t.setObject(new Worker());
		Worker w = (Worker)t.getObject();
		*/
	}
}
class Worker
{
}
class Student
{
}
//泛型前做法
class Tool
{
	private Object obj;
	public void setObject(Object obj)
	{
		this.obj = obj;
	}
	public Object getObject()
	{
		return obj;
	}
}
//泛型后做法
class Utils<Q>                                   //泛型类
{
	private Q q;
	public void setObject(Q q)
	{
		this.q = q;
	}
	public Q getObject()
	{
		return q;
	}
}

2泛型方法

 

泛型类定义的泛型,在整个类中有效,如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所有方法要操作的类型就已经固定了

为了让不同方法可以操作不同类型,而且类型还不确定,那么可以将泛型定义在方法上。

class GenericDemo4 
{
	public static void main(String[] args) 
	{
		/*
		Demo<String> d = new Demo<String>;
		d.show("haha");
		d.print(5);               //编译时将会报错,因为对象已经指定了String类型
		*/
		Demo d = new Demo();
		d.show("haha");
		d.show(new Integer(4));
		d.print("heihei");         //泛型定义在方法上就可以在一个对象中操作不同类型
	}
}
class Demo
{
	public <T> void show(T t)
	{
		System.out.println("show:"+t);
	}
	public <Q> void print(Q q)
	{
		System.out.println("print:"+q);
	}
}
/*
class Demo<T>
{
	public void show(T t)
	{
		System.out.println("show:"+t);
	}
	public void print(T t)
	{
		System.out.println("print:"+t);
	}
}
*/

特殊之处:

静态方法不可以访问类上定义的泛型,如果静态方法操作的引用数据类型不确定,可以将泛型定义在方法上


3泛型限定

public static void printColl(ArrayList<? extends Person> al)    //接收Person类型及其子类
	{
		Iterator<? extends Person> it = al.iterator();
		while (it.hasNext())
		{
			System.out.println(it.next().getName());
		}
	}

? 通配符,也可以理解为占位符

泛型的限定:

? extends E:可以接收E类型或者E的子类型。上限

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



9.6Map

 

Map<K,V>集合是一个接口,该集合存储键值对,一对一对往里存,而且要保证键的唯一性。

Map集合存储和Collection有着很大不同:

Collection一次存一个元素;Map一次存一对元素。

Collection是单列集合;Map是双列集合。

Map中的存储的一对元素:一个是键,一个是值,键与值之间有对应(映射)关系。

特点:要保证map集合中键的唯一性。

 

Map集合共性方法:

1)添加。
  put(key,value):当存储的键相同时,新的值会替换老的值,并将老值返回。如果键没有重复,返回null。
void putAll(Map);
2)删除。
void clear():清空
value remove(key) :删除指定键。
3)判断。
boolean isEmpty():
boolean containsKey(key):是否包含key
boolean containsValue(value) :是否包含value
4)取出。
int size():返回长度
value get(key) :通过指定键获取对应的值。如果返回null,可以判断该键不存在。当然有特殊情况,就是在hashmap集合中,是可以存储null键null值的。
Collection values():获取map集合中的所有的值。
5)想要获取map中的所有元素:
原理:map中是没有迭代器的,collection具备迭代器,只要将map集合转成Set集合,可以使用迭代器了。之所以转成set,是因为map集合具备着键的唯一性,其实set集合就来自于map,set集合底层其实用的就是map的方法。

map集合特有的两种取出方式:

1)  Set<k> keySet:将map中所有的键存入到Set集合。因为Set具备迭代器,所以可以通过迭代方式取出所有的键,再根据get方法,获取每一个键对应值。

import java.util.*;
class MapDemo2 
{
	public static void main(String[] args) 
	{
		Map<String,String> map = new HashMap<String,String>();
		map.put("01","zhangsan1");
		map.put("02","zhangsan2");
		map.put("03","zhangsan3");
		map.put("04","zhangsan4");

		//先获取Map集合的所有键的Set集合,keySet()
		Set<String> keySet = map.keySet();

		//有了Set集合,就可以获取其迭代器
		Iterator<String> it = keySet.iterator();
		while (it.hasNext())
		{
			String key = it.next();
			//有了键可以通过Map集合的get方法获取其对应的值
			String value = map.get(key);
			System.out.println("key:"+key+",value:"+value);
		}
	}
}
//Map集合的取出原理:将Map集合转成Set集合,再通过迭代器取出

2)  Set<Map.Entry<K,V>> entrySet:将Map集合中的映射关系存入到了Set集合中,而这个关系的数据类型就是Map.Entry

import java.util.*;
class MapDemo2 
{
	public static void main(String[] args) 
	{
		Map<String,String> map = new HashMap<String,String>();
		map.put("01","zhangsan1");
		map.put("02","zhangsan2");
		map.put("03","zhangsan3");
		map.put("04","zhangsan4");

		//将Map集合中的映射关系取出,存入到Set集合中
		Set<Map.Entry<String,String>> entrySet = map.entrySet();
		Iterator<Map.Entry<String,String>> it = entrySet.iterator();
		while (it.hasNext())
		{
			Map.Entry<String,String> me = it.next();
			String key = me.getKey();
			String value = me.getValue();
			System.out.println(key+":"+value);
		}
	}
}
//Map.Entry :其实Entry也是一个接口,它是Map接口中的一个内部接口(静态的)

Map 子类对象:

1)  Hashtable

底层是哈希表数据结构,不可以存入null键null值。该集合是线程同步的,效率低

2)  HashMap

底层是哈希表数据结构,并允许使用null值和null键,该集合是不同步的,效率高

3)  TreeMap

底层是二叉树数据结构,线程不同步。可以用于给map集合中的键进行排序

 

Map集合和Set集合很像,其实Set底层就是使用了Map集合

当数据之间存在着映射关系时,就要想到map集合


9.7Utilities

 

1)  Collections

Collections是专门用于对集合进行操作的工具类,其内部的方法都是静态的。

 

sort:对指定列表进行排序

Collections.sort(List<T> list);

Collections.sort(List<T> list,Comparator<? super T> comp);

 

max:返回给定 collection 的最大元素

Collections.max(Collection<? extends T> coll)

Collections.max(Collection<?extends T> coll,Comparator<? super T> comp)

 

binarySearch:使用二分搜索法搜索指定列表,获得指定对象

Collections.binarySearch(List<? extendsComparable<? super T>> list, T key)    List中元素自身有比较性时使用

Collections.binarySearch(List<? extendsT> list, T key,  Comparator<? superT> c)  List中元素自身无比较性时调用比较器


fill:使用指定元素替换指定列表中的所有元素

Collections.fill(List<? super T>list,T obj)

 

replaceAll:使用另一个值替换列表中出现的所有某一指定值

Collections.replaceAll(List<T> list,ToldVal,T newVal)

 

reverse:反转指定列表中元素的顺序

Collections.reverse(List<?> list)

reverseOrder:返回一个比较器,它强行逆转指定比较器的顺序

Collections.reverseOrder()                             逆转自然顺序

Collections.reverseOrder(Comparator<T>comp)           逆转comp比较器的顺序


shuffle:使用默认随机源对指定队列进行置换(随机排序)

Collections.shuffle(List<?> list)

 

将非同步集合转成同步集合的方法:Collections中的  XXX synchronizedXXX(XXX);

List synchronizedList(list);

Map synchronizedMap(map);

原理:定义一个类,将集合所有的方法加同一把锁后返回。

 

Collection 和 Collections的区别:

Collections是个java.util下的类,是针对集合类的一个工具类,提供一系列静态方法,实现对集合的查找、排序、替换、线程安全化(将非同步的集合转换成同步的)等操作。

Collection是个java.util下的接口,它是各种集合结构的父接口,继承于它的接口主要有Set和List,提供了关于集合的一些操作,如插入、删除、判断一个元素是否其成员、遍历等。


2)  Arrays

用于操作数组的工具类,里面都是静态方法

 

asList:将数组变成list集合

Arrays.asList(arr)

把数组变成集合可以使用集合的思想和方法来操作数组中的元素,比如用contains方法判断元素是否存在。将数组变成集合,不可以使用集合的增删等会改变数组长度的功能方法,因为数组的长度是固定的。(否则会报不支持操作异常UnsupportedOperationException

 

如果数组中的元素都是对象,那么变成集合时,数组中的元素就直接转成集合中的元素

如果数组中的元素都是基本数据类型,那么会将该数组作为集合中的元素存在。


3)集合转成数组

Collection.toArray(T[ ] arr):返回包含此collection中所有元素的数组(T类型的数组)

import java.util.*;
class CollectionToArray 
{
	public static void main(String[] args) 
	{
		ArrayList<String> al = new ArrayList<String>();
		al.add("abc1");
		al.add("abc2");
		al.add("abc3");

		String[] arr = al.toArray(new String[5]);
		System.out.println(Arrays.toString(arr));       //输出:[abc1, abc2, abc3, null, null]
		String[] arr = al.toArray(new String[al.size()]);   //最优
	}
}

指定类型的数组到底要定义多长?

当指定类型的数组长度小于了集合的size,那么该方法内部会创建一个新的数组,长度为集合的size。

当指定类型的数组长度大于了集合的size,就不会新创建数组,而是使用传递进来的数组。

所以创建一个刚刚好的数组最优。

 

为什么要将集合变成数组?

为了限定对元素的操作,不需要进行增删了


4)增强for循环

格式:

for(数据类型 变量名:被遍历的集合(Collection)或者数组){}

 

对集合进行遍历,只能获取元素,但是不能对集合进行操作。

迭代器除了遍历,还可以进行remove集合中元素的动作。如果是用ListIterator,还可以在遍历过程中对集合进行增删改查的动作。

 

传统for和高级for有什么区别?

高级for有一个局限性,必须有被遍历的目标。这个目标,可以是Collection集合或者数组,如果遍历Collection集合,在遍历过程中还需要对元素进行操作,比如删除,需要使用迭代器。

建议在遍历数组的时候,还是希望使用传统for,因为传统for可以定义角标。

 

高级for循环可以遍历map集合吗?不可以。但是可以将map转成set后再使用foreach语句。

import java.util.*;
class ForEachDemo 
{
	public static void main(String[] args) 
	{
		ArrayList<String> al = new ArrayList<String>();
		al.add("abc1");
		al.add("abc2");
		al.add("abc3");
		for (String s : al)
		{
			System.out.println(s);
		}
	
		HashMap<Integer,String> hm = new HashMap<Integer,String>();
		hm.put(1,"a");
		hm.put(2,"b");
		hm.put(3,"c");
		for (Integer i : hm.keySet() )                  //利用高级for替代Iterator
		{
			System.out.println(i+"::"+hm.get(i));
		}
		for(Map.Entry<Integer,String> me : hm.entrySet())
		{
			System.out.println(me.getKey()+"---"+me.getValue());
		}
	}
}


5)可变参数

方法的可变参数在使用时,可变参数一定要定义在参数列表的最后面。

class ParamMethodDemo 
{
	public static void main(String[] args) 
	{
		show("haha",2,3,4,5);
	}
	public static void show(String str,int...arr)
	{
		System.out.println(arr.length);
	}
}


10.其他对象

 

10.1System类

 

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

out:标准输出,默认是控制台

in:标准输入,默认键盘

 

获取系统属性信息:System.getProperties()  返回的是Properties类(Hashtable的子类)

设置自定义信息:System.setProperty(K,V)

获取指定属性信息:System.getProperty(K)  返回的是对应键的值(String类)

import java.util.*;
class SystemDemo 
{
	public static void main(String[] args) 
	{
		Properties prop = System.getProperties();
		//在系统中自定义一些特有信息
		System.setProperty("mykey","myvalue");

		/*
		因为Properties是Hashtable的子类,也就是Map集合的一个子类对象
		那么可以通过map的方法取出该集合中的元素
		该集合中存储的都是字符串,没有泛型定义
		*/
		for ( Object obj : prop.keySet())
		{
			String value = (String)prop.get(obj);           //没有指定泛型要强转
			System.out.println(obj+"---"+value);
		}

		//获取指定属性信息
		String value = System.getProperty("os.name");

		/*在jvm启动时,动态加载一些属性信息
		  在cmd中:java -Dxxx -yyyy SystemDemo
		  则在SystemDemo.java中
		  System.getProperty("xxx")得到的结果为yyyy
		*/
	}
}

10.2 Runtime类

 

该类中并没有提供构造函数,说明不可以new对象。该类中提供了静态方法来获取本类对象,返回值类型是本类类型:static Runtime getRuntime() 。 此类为单例设计模式。

 

打开应用程序:exec(String command)

class RuntimeDemo 
{
	public static void main(String[] args) throws Exception
	{
		Runtime r = Runtime.getRuntime();
		Process p = r.exec("c:\\Windows\\notepad.exe SystemDemo.java");    
		//系统根目录下的应用程序可以省略目录。可以用notepad程序打开与程序相关联的SystemDemo.java文件
		Thread.sleep(4000);
		//p.destroy();                         //杀掉子进程
	}
}


10.3Date类

import java.util.*;
import java.text.*;
class DateDemo 
{
	public static void main(String[] args) 
	{
		Date d = new Date();
		System.out.println(d);

		//将模式封装到SimpleDateFormat对象中
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日E HH:mm:ss");

		//调用format方法让模式格式化指定Date对象
		String time = sdf.format(d);
		System.out.println(time);
	}
}


10.3Calendar类

import java.util.*;
import java.text.*;
class CalendarDemo 
{
	public static void main(String[] args) 
	{
		Calendar c = Calendar.getInstance();
		String[] mons = {"一月","二月","三月","四月",
				 "五月","六月","七月","八月",
				 "九月","十月","十一月","十二月"};
		String[] weeks = {"","星期日","星期一","星期二","星期三",
				  "星期四","星期五","星期六"};
		int index = c.get(Calendar.MONTH);
		int index1 = c.get(Calendar.DAY_OF_WEEK);
		sop(c.get(Calendar.YEAR)+"年");
		//sop((c.get(Calendar.MONTH)+1)+"月"); //Calender中的Month是从0开始的
		sop(mons[index]);
		sop(c.get(Calendar.DAY_OF_MONTH)+"日");
		//sop("星期"+c.get(Calendar.DAY_OF_WEEK));//Calender中是将星期日作为一个星期的第一天
		sop(weeks[index1]);
	}
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}

set(int year,int month,int date):将日历设置为指定日期

add(int field,int amount):为给定的日历添加或减去指定的时间量


10.4Math类

 

Math.ceil(double d):返回大于指定数据的最小整数。

Math.floor(double d):返回小于指定数据的最大整数。

Math.round(double d):四舍五入。返回值类型为long。

Math.pow(double a,double b):返回a的b次方。

Math.random():返回大于等于0.0且小于1.0的double随机数。



0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:2866次
    • 积分:132
    • 等级:
    • 排名:千里之外
    • 原创:11篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章存档