Java基础之集合

一、集合类概述

       Java的util保重提供了一些集合类,这些集合类又称为容器,一提到容器就会想到数组,可是集合跟数组是不同的,他们的不同之处是,数组的长度是固定的,而集合的长度是可变的,数组用来存放基本类型的数据,而集合除了这些之外还可以存放对象引用。常用的集合有List集合,Set集合,Map集合,其中List和Set集合继承了Collection接口,各个接口还提供了不同的类。集合类的关系图如下。


二、Collection接口

Collection接口是层次结构中的根接口。构成Collection的单位称为元素。Collection接口通常不能直接使用,但是该接口提供了添加元素,删除元素,管理数据的方法。由于List接口和 Set接口都继承了Collection接口,因此这些方法对Set和List都是通用的。

1、常见的操作方法如下:

add(E e)          确保此 collection 包含指定的元素(可选操作)。 
addAll(Collection<? extends E> c)           将指定 collection 中的所有元素都添加到此 collection 中(可选操作)。 
clear()           移除此 collection 中的所有元素(可选操作)。 
contains(Object o)           如果此 collection 包含指定的元素,则返回 true。 
containsAll(Collection<?> c)          如果此 collection 包含指定 collection 中的所有元素,则返回 true。 
equals(Object o)          比较此 collection 与指定对象是否相等。 
hashCode()           返回此 collection 的哈希码值。 
isEmpty()           如果此 collection 不包含元素,则返回 true。 
iterator()           返回在此 collection 的元素上进行迭代的迭代器。 
remove(Object o)          从此 collection 中移除指定元素的单个实例,如果存在的话(可选操作)。 
removeAll(Collection<?> c)           移除此 collection 中那些也包含在指定 collection 中的所有元素(可选操作)。 
retainAll(Collection<?> c)           仅保留此 collection 中那些也包含在指定 collection 的元素(可选操作)。 
size()           返回此 collection 中的元素数。 
toArray()           返回包含此 collection 中所有元素的数组。
toArray(T[] a)          返回包含此 collection 中所有元素的数组;返回数组的运行时类型与指定数组的运行时类型相同。 

2、迭代器的使用

迭代是在集合中遍历元素的方式。因为Collection中有iterator方法,所以每一个子类集合对象都具备迭代器。通常遍历集合,都是通过迭代器Iterate类实现的。Collection接口中的iterator()方法可以返回Collection进行迭代的迭代器。

Iterate的方法摘要如下:

hasNext()     返回值是 boolean 类型  如果仍有元素可以迭代,则返回 true。 

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

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


迭代器的两种使用方式:

1)、for(Iterator iter = iterator();iter.hasNext(); )

{

System.out.println(iter.next());

}

2)、Iterator iter = l.iterator();

while(iter.hasNext())

{

System.out.println(iter.next());

}


三、List集合

List集合中的元素是允许重复的,切元素是有序的,这里的有序是指存取的顺序是一致的。并且该集合体系中索引。

List:特有的常见方法。
有一个共性特点就是都可以操作角标。
1、添加
add(index,element);
addAll(index,collection);
2、删除
remove(index);
3、修改
set(index,element);
4、获取:
get(index);
indexOf(object);
lastIndexOf(object);
subList(from,to);
List集合可以完成对元素的增删改查。

List接口的实现类:

List接口的类有Arraylist   Linklist    Vector 

ArrayList:底层的数据结构使用的是数组结构。特点:查询速度很快。但是增删稍慢。线程不同步。
            LinkedList:底层使用的是链表数据结构。特点:增删速度很快,查询稍慢。
          Vector:底层是数组数据结构。线程同步。被ArrayList替代了。


ArrayList的示例:

import java.util.*;
class ArrayListDemo 
{
	public static void main(String[] args) 
	{
		List list=new ArrayList();
		list.add("zhangsan");
		list.add("lisi");
		list.add("wangwu");
		list.add("zhaoliu");
		int i=(int )(Math.random()*(list.size()-1));
		System.out.println("随机获得的元素是"+list.get(i));
		System.out.println("原始数组的元素是"+list);
		list.remove(2);
		System.out.println("移除索引值为2的元素后,数组中的元素为");
		Iterator it1 = list.iterator();
		while(it1.hasNext())
		{
				String str=(String)it1.next();
				System.out.println(str);

		}
	}
}

运行结果为:

由结果可以看出,集合跟数组相同,集合的索引号也是从0开始。

LinkList的示例:

import java.util.*;
public class LinkedListDemo {
	public static void main(String[] args)
	{
		LinkedList list=new LinkedList();
		LinkedList list1=new LinkedList();

		list.addFirst("java01");
		list.addFirst("java02");
		list.addFirst("java03");
		list.addFirst("java04");
		list1.add("java01");
		list1.add("java02");
		list1.add("java03");
		list1.add("java04");
		Iterator it1=list.iterator();
		System.out.println(list);
		System.out.println(list1);
		while(it1.hasNext())
		{
			System.out.println(it1.next());
		}
		list.removeAll(list);
		if(!list.isEmpty())
		{
			System.out.println("集合不为空");
		}
		else{
			System.out.println("空集合");
			
		}
		
		
	}

}
运行结果为:


三、Set集合

Set集合中的对象不按照特定的方式排序,只是简单的把对象加入集合中,但是Set集合中不能包含重复的元素或对象,Set继承了Collection接口,所以包含Collection中的所有方法。

Set接口的实现类

HashSet:内部数据结构是哈希表,是不同步的。
TreeSet:可以对Set集合中的元素进行排序,是不同步的。

1、HashSet 

HashSet的线程不安全但是,存取速度很快。

HashSet确定元素的唯一性是通过hashCode和equals方法来实现的。原理是如果元素的HashCode值相同,才会判断equals是否为true。如果元素的hashCode值不同,不会调用equals。

示例:

import java.util.*;

import org.omg.CORBA.CTX_RESTRICT_SCOPE;
class Student
{
	private String name;
	private int age;
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Student other = (Student) obj;
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	
	
}
public class HashSetDemo {

	/**
	 * @param args
	 */
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		HashSet hs=new HashSet();
		hs.add(new Student("zhangsan", 20));
		hs.add(new Student("zhaoliu", 22));
		hs.add(new Student("wangwu", 23));
		hs.add(new Student("hetong", 24));
		hs.add(new Student("zhangsan", 21));
		Iterator it=hs.iterator();
		while(it.hasNext())
		{
			Student st=(Student)it.next();
			System.out.println(st.getName()+"............."+st.getAge());
		}

	}

}

运行结果:

当最后以后数据的年龄为21时,数据可以添加进去,当为20时就不能添加进去


2、TreeSet

TreeSet的特点:

1、底层结构是二叉树结构

2、可以通过比较器对TreeSet类实现的集合中的对象进行排序,排序的方式有两种,第一种是让元素自身具备比较功能,元素就需要实现Comparable接口,覆盖compareTo方法。如果不要按照对象中具备的自然顺序进行排序。如果对象中不具备自然顺序。怎么办?可以使用TreeSet集合第二种排序方式:让集合自身具备比较功能,定义一个类实现Comparator接口,覆盖compare方法。将该类对象作为参数传递给TreeSet集合的构造函数。

当主要条件排序一样时,就要考虑次要条件。

TreeSet的第一种排序方式示例(实现Comparable接口):

import java.util.*;
class Student1 implements Comparable{
	private String name;
	private int age;
	public Student1(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	@Override
	public int compareTo(Object o) {
		// TODO Auto-generated method stub
		Student1 stu= (Student1)o;
		//当主要条件相同时要判断次要条件,字符串利用自带的比较函数
		return age>stu.age?1:(age==stu.age?(name.compareTo(stu.name)):-1);
		
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
	
	
}
public class TreeSetDemo1 {
	public static void main(String[] args) {
		TreeSet ts=new TreeSet();
		ts.add(new Student1("zhangsan",18));
		ts.add(new Student1("zhangsan1",18));
		ts.add(new Student1("zhangsan",20));
		ts.add(new Student1("zhangsan",19));
		Iterator it=ts.iterator();
		while(it.hasNext())
		{
			Student1 s= (Student1)it.next();
			System.out.println(s.getName()+"..........."+s.getAge());
		}
	}

}

运行结果:



TreeSet的第二种排序方式示例(实现Comparator接口):

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

class Student2 implements Comparable{
	private String name;
	private int age;
	public Student2(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	@Override
	public int compareTo(Object o) {
		// TODO Auto-generated method stub
		Student2 stu= (Student2)o;
		//当主要条件相同时要判断次要条件,字符串利用自带的比较函数
		return age>stu.age?1:(age==stu.age?(name.compareTo(stu.name)):-1);
		
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
	
	
}
class ComparatorByName implements Comparator{

	@Override
	public int compare(Object o1, Object o2) {
		// TODO Auto-generated method stub
		Student2 s1=(Student2)o1;
		Student2 s2=(Student2)o2;
		int temp=s1.getName().compareTo(s2.getName());
		return temp==0?s1.getAge()-s2.getAge():temp;
		
		
		
	}
	
	
}
public class TreeSetDemo2 {
	public static void main(String[] args) {
		TreeSet ts=new TreeSet(new ComparatorByName());
		ts.add(new Student2("zhangsan",18));
		ts.add(new Student2("zhangsan1",18));
		ts.add(new Student2("zhangsan",20));
		ts.add(new Student2("zhangsan",19));
		Iterator it=ts.iterator();
		while(it.hasNext())
		{
			Student2 s= (Student2)it.next();
			System.out.println(s.getName()+"..........."+s.getAge());
		}
		
	}

}

运行结果是:



三、Map集合

1、Map集合的概述

Map集合没有继承Collection接口,其提供的是key到value的映射。Map中不能包含相同的key,每一个key只能映射到一个value。key中还决定了存储对象在映射中的存储位置,但不是由key对象本身决定的,而是通过一种”散列技术“进行处理,产生一个散列码的整数值,散列码通常用左一个偏移量,该偏移量对应分配给映射的内存区域的起始位置,从而确定存储对象在映射中的存储位置。

2、Map集合中常用的方法

clear()           从此映射中移除所有映射关系(可选操作)。 

containsKey(Object key)           如果此映射包含指定键的映射关系,则返回 true。 

containsValue(Object value)           如果此映射将一个或多个键映射到指定值,则返回 true。   

equals(Object o)           比较指定的对象与此映射是否相等。 

get(Object key)           返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。 

hashCode()           返回此映射的哈希码值。 

isEmpty()           如果此映射未包含键-值映射关系,则返回 true。

put(K key, V value)           将指定的值与此映射中的指定键关联(可选操作)。 

putAll(Map<? extends K,? extends V> m)           从指定映射中将所有映射关系复制到此映射中(可选操作)。 

remove(Object key)           如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。 

size()           返回此映射中的键-值映射关系数。 

values()           返回此映射中包含的值的 Collection 集合。 

3、Map集合中的子类

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

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

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

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

4、Map集合的两种取值方式:

Set<Map.Entry<K,V>> entrySet()           返回此映射中包含的映射关系的 Set 集合。

原理是将Map中所以的键存入到Set集合。因为Set具备迭代器。所以可以通过迭代方式取出所以键的值,再通过get方法。获取每一个键对应的值。

Set<K> keySet()           返回此映射中包含的键的 Set 集合。

原理是将Map集合中的映射关系存入到Set集合中,而这个关系的数据类型就是:Map.Entry。其实,Entry也是一个接口,它是Map接口中的一个内部接口。

下面就两个取值方式做出示例:

(1)Set<K> keySet()  方式示例:

import java.util.*;
class Student3 implements Comparable{
	private String name;
	private int age;
	public Student3(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	@Override
	public int compareTo(Object o) {
		// TODO Auto-generated method stub
		Student3 stu= (Student3)o;
		//当主要条件相同时要判断次要条件,字符串利用自带的比较函数
		return age>stu.age?1:(age==stu.age?(name.compareTo(stu.name)):-1);
		
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return name+"........"+age;
	}
	
	
	
}
public class HashMapDemo {
	public static void main(String[] args) {
		HashMap<Student3,String> ts=new HashMap();
		Student3 stu1=new Student3("zhangsan",18);
		Student3 stu2=new Student3("zhangsan1",18);
		Student3 stu3=new Student3("zhangsan",20);
		Student3 stu4=new Student3("zhangsan",19);
		ts.put(stu1,"beijing");
		ts.put(stu2,"tianjin");
		ts.put(stu3,"chongqing");
		ts.put(stu4,"shanghai");
		keySet(ts);
		
		
	}

	private static void keySet(HashMap<Student3, String> ts) {
		// TODO Auto-generated method stub
		Iterator<Student3> it=ts.keySet().iterator();
		while(it.hasNext())
		{
			Student3 s=it.next();
			String address=ts.get(s);
			System.out.println(s+":"+address);
			
		}
	}

}

运行结果为:


(2)Set<Map.Entry<K,V>> entrySet()  方式示例:

取出方式的主要代码是:

private static void entrySet(HashMap<Student3, String> ts) {
		// TODO Auto-generated method stub
		Iterator<Map.Entry<Student3, String>> it=ts.entrySet().iterator();
		while(it.hasNext())
		{
			Map.Entry<Student3, String> me=it.next();
			Student3 s=me.getKey();
			String address=me.getValue();
			System.out.println(s+":::"+address);  
		}
	}

运行结果与上示例结果一样。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值