黑马程序员---Java集合框架

---------------------- Android开发java培训、期待与您交流! ----------------------

Java集合框架

集合我们都知道是用来储存对象的容器,那之前的数组不也可以储存对象么,为什么要出现集合呢?

面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,然而集合类中提供很多方便操作对象存储的方法,要比数组更容易操作对象,而且集合的长度是可变的,然而数组长度确实固定不变的,这样不利于对对象的间隔储存。

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

数组的长度是固定的,而集合的长度是可变的,集合只能存储对象,数组虽然既可以存储基本数据类型也可以存储对象,但对数组的操作过于麻烦不灵活也不方便

集合类的特点

集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。

集合框架为什么会出现这么多的容器呢?

因为每一个容器对数据的存储方式都有不同。这个存储方式称之为:数据结构。

Java集合框架常见类图

从图中可以看出,大部分的集合的父接口是Iterator,实际上它只是集合遍历的迭代器接口,最特殊的集合父接口是Collection。Collection下面还有常用的两个集合接口List和Set,它两实现了Collection中所有方法,并各自独具特色。

各个常用集合接口及集合类分布总结:

Collection

|——List:元素是有序的(存入的顺序和取出的顺序一致),元素可以重复。因为集合体系有索引。它的储存方式和数组有类似。

|—Vector:底层是数组数据结构。线程同步,所以效率较低,被ArrayList替代了。

|—ArrayList:底层数据结构式数组,所以它查询快,但增删相对慢,线程不同步。默认长度为10,当元素超出时,自动new一个数组对象并且按原来50%增长;

|—LinkedList:底层是链表数据结构,所以查询慢,但增删相对很快,线程不同步。

|——Set :元素是无序的(存入的顺序和取出的顺序有可能不同),元素不可以重复。

|—HashSet:数据结构是哈希表。线程是非同步的,保证元素唯一性的原理:判断元素的hashCode值是否相同。如果相同,还会继续判断元素的equals方法,是否为true。

|—TreeSet:底层数据结构是二叉树。二叉树默认取值顺序是从小到大。可以对set集合中的元素进行排序.(Ascll码排序)

Iterator-->它是集合的一个迭代器接口集成,Collection集合中定义专门的生成Iterator实例的方法来方便随时操作集合
Iterator<E> iterator() ;

Iterator迭代器的特点:

①迭代器其实就是集合元素的取出方式。

②每个集合的取出方式都不一样,所以对它们取出方式进行了抽取,抽取为一个接口Iterator,并抽取了3个共性方法hasnext(),next(),remove();

③迭代器降低了取出方式和数据结构之间的耦合性。

④集合的元素取出方式是集合内部的事,所以被定义为内部类,只提供了一个方法来获得取出方式,这个方法为iterator()。

⑤Iterator迭代器只能对集合进行判断,取出删除的操作,当用Iterator迭代时,不可以通过集合对象的方法操作集合中的元素不然会发生并发操作异常ConcurrentModificationException。

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

public class IteratorDemo {
	/**
	 * 迭代器演示
	 *   集合方法iterator()
	 *   Iterator接口方法hasNext(),next()
	 */
	public static void main(String[] args) {
		ArrayList<String> at = new ArrayList<String>();
		at.add("java01");
		at.add("java03");
		at.add("java02");
		at.add("java04");

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

Iterator迭代器对集合元素只能做取出,判断,删除操作,不然会发生并发异常,那对集合的修改平凡时,迭代器又该何去何从呢?

List集合中ListIterator迭代器:

从上面的图中可以看出Iterator还有一个子接口ListIterator,从字面一看就知道它也是集合迭代器,正是它才拟补了Iterator的不足之处。

List集合特有的迭代器。ListIterator是Interator的子接口。当用Iterator迭代时,不可以通过集合对象的方法操作集合中的元素。因为会发生并发操作异常ConcurrentModificationException。所以,在用迭代器时,只能用迭代器的方法操作元素,可是Iterator方法是有限的。只能对元素进行判断,取出,删除的操作,如果想要其他的操作如添加,修改等,就需要使用某子接口ListIterator。该接口只能通过List集合的listIterator方法获取。

(1)ArrayList类

数据结构为数组,具有查找快,增删慢等特点。

由图可看出它个元素都有相对应的索引,所以有利于查询,但每次增删时,需要对后续的元素进行前移或者后移较消耗资源,所以增删较慢。

(2)LinkedList类

数组结构为链表,具有增删快,查找慢等特点。

由图可以看出链表结构每一个元素都会记住后一个元素的索引,在修改时只需对前一个元素所记的索引进行修改即可,这样来看链表结构的增删速度是很快的。但当查找元素时,只会一个接一个的进行询问查找,在元素多的时候就会很慢了。

(3)HashSet类

数据结构为哈希表,可保持元素唯一性,依赖于hashCode()和equals().

                          

元素存入集合时会先比较之间的哈希值,如果哈希值相同,他就会比较对象是否相同,如果不同就会存入相同哈希值的顺延球下。不同哈希值的元素会存储在不同的顺延球下。

(4)TreeSet类

数据结构为二叉树,具有保持数据唯一性的特性。

                          

元素是以树形结构排列的,遵从左小右大的顺序进行悬挂,取出的默认顺序是从左往右去,也就是从小到大取出。

TreeSet集合具有两种排序方式:

①元素具备比较性,让元素类实现Comparable接口,覆盖CompareTo()方法,这种方式也称为自然顺序,或称为默认顺序。

import java.util.Iterator;
import java.util.TreeSet;
/**
 * TreeSet:可以对set集合元素进行排序,
 * 底层数据结构是二叉树(左边小,右边大)
 * 保证元素唯一性的依据
 * compareTo方法默认return 0;
 * 需要实现Comparable接口复写compareTo()方法。
 * */
public class TreeSetTest {
	public static void main(String[] args){
		TreeSet<Student> ts = new TreeSet<Student>();
		ts.add(new Student("sixi",20));
		ts.add(new Student("xiaowang",20));
		ts.add(new Student("lizhiyuan",18));
		ts.add(new Student("zenhanqing",16));
		ts.add(new Student("laomao",21));
		Iterator<Student> it = ts.iterator();
		while(it.hasNext()){
			Student s = it.next();
			System.out.println(s.name+"....."+s.age);
		}
	}
}
class Student implements Comparable<Student>{
	String name;
	int age;
	Student(String name,int age){
		this.name = name;
		this.age = age;
	}
	public String getName(){
		return name;
	}
	public int getAge(){
		return age;
	}
	@Override
	public int compareTo(Student o) {
		if(this.age>o.age)
			return 1;
		if(this.age==o.age){
			return(this.name.compareTo(o.name));
		}
		else
			return -1;
	}
}

②当元素自身不具备比较性,或者具备的比较性不是所需要的。这时需要让容器自身具备比较性。当集合初始化时,就有了比较方式。定义了比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。当两种排序都存在时,比较器为主。定义一个类,实现Comparator接口,覆盖compare方法。

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

public class TreeSetDemo {

	/**
	 * 定义比较器,让集合具备比较性。
	 * 比较器类需要实现Comparator接口,并覆盖Compare()方法。
	 * 并比较器对象传递给集合。
	 */
	public static void main(String[] args) {
		TreeSet<Person> ts = new TreeSet<Person>(new Comp());
		ts.add(new Person("sixi",20));
		ts.add(new Person("sixi",21));
		ts.add(new Person("laomao",20));
		ts.add(new Person("xiaohai",16));
		Iterator<Person> it = ts.iterator();
		while(it.hasNext()){
			Person p = it.next();
			System.out.println(p.getName()+">>>>>>"+p.getAge());
		}
	}
}
class Comp implements Comparator<Person>{//比较器

	@Override
	public int compare(Person p1, Person p2) {
		int num = p1.getName().compareTo(p2.getName());
		if(num==0)
			return new Integer(p1.getAge()).compareTo(new Integer(p2.getAge()));
		return num;
	}
}

在集合框架中还有一中特殊的集合Map集合。Map是一个接口,它与Collection接口没有关系。

Map集合:该集合存储键值对。一对一对往里存。而且要保证键的唯一性。

|——HashTable:底层是哈希表数据结构,不可以存入null键null值。该集合是线程同步的。jdk1.0出现,效率比较低。

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

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

Map集合和Set集合很像,其实Map集合底层就是用的Set集合。

Map集合的增删改查:

   1、添加。

put(K key,V value):添加键值对

putAll(Map<? extends K,? extends V>m):将一个Map集合中的所有元素存入另一个Map集合

2、删除。

clear():清空所有元素。

remove(Object key):删除指定键所对应的值。

3、判断。

containsValue(Object value):判断集合中存在的值。

containsKey(Object key):判断集合存在的键。

isEmpty():判断集合是否为空。

4、获取。

get(Object key):获取键所对应的值。

size():获取集合的大小。

values():将所有值存储到相应的Collection集合中。

entrySet():将Map集合中的元素以键值对关系类型的方式存储到Set集合中。

keySet():将集合中的所有的键存储到Set集合中。

Map集合有两种取出方式:

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

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
 * 迭代Map集合
 * 第一种方式:
 * 将Map集合中key取出保存到Set集合中,再通过Set集合具备的迭代器迭代出Map集合的key值,然后通过key值取出Map集合相应的value值。
 * */
public class MapDemo {
public static void main(String[] args){
	Map<String,String> map = new HashMap<String,String>();
	map.put("01", "sixi");
	map.put("02", "xiaohai");
	map.put("03", "xiaohe");
	//取出所有的键存入Set集合中。
	Set<String> st = map.keySet();
	Iterator<String> it = st.iterator();
	while(it.hasNext()){
		String key = it.next();
		String value = map.get(key);
		System.out.println(key+":"+value);
	}
    }
}

  Set<Map.Entry<k,v>> entrySet:将map集合中的映射关系存入到了 set集合中,而这个关系的数据类型就是:Map.Entry

Map.Entry其实Entry也是一个接口,它是Map接口中的一个内部接口。

//Map.Entry关系实例代码:
interface Map
{
	public static interface Entry
	{
		public abstract Object getKey();
		public abstract Object getValue();
	}
}
class HashMap implements Map
{
	class Hahs implements Map.Entry
	{
		public Object getKey(){}
		public Object getValue(){}
	}
}
//Map集合的第二种取出方式:
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class MapDemo1 {
	/**
	 * Map的第二种取出方式:
	 *将Map集合中Map.Entry关系映射到Set集合中,在通过迭代器取出。
	 */
	public static void main(String[] args) {
		Map<String,String> map = new HashMap<String,String>();
		map.put("01", "zhangsan1");
		map.put("02", "zhangsan3");
		map.put("03", "zhangsan2");

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

【练习】

每一个学生都有对应的归属地。

学生Student,地址String。

学生属性:姓名,年龄。

注意:姓名和年龄相同的视为同一个学生。

保证学生的唯一性。

1、描述学生。

2、定义map容器。将学生作为键,地址作为值。存入。

3、获取map集合中的元素。

import.java.util.*;
class Student implements Comparable<Student>//让元素具备比较性
{
	private String name;
	private int age;
	Student(String name,int age)
	{
		this.name = name;
		this.age = age;
	}
        //
        public int compareTo(Student s)
	{
  		int num = new Integer(this.age).compareTo(new Integer(s.age));
 		if(num==0)
                   return this.name.compareTo(s.name);
                return num;
	}

	public int hashCode()
	{
		return name.hashCode()+age*34;
	}
	public boolean equals(object obj)
	{
		if(!(obj instanceof Student))
			throw new ClassCastException("类型不匹配");
		Student s = (Student)obj;
		return this.name.equals(s.name) && this.age == s.age;
	}
	public String getName()
	{
		return name;
	}
	public int getAge()
	{
		return age;
	}
	public String  toString()
	{
		return name+":"+age;
	}

}

class MapTest
{
	public static void main(String[] args)
	{
		HashMap<Student,String> hm = new HashMap<Student,String>();

		hm.put(new Student("Lisi1",21),"beijing");
		hm.put(new Student("Lisi2",22),"shanghai");
		hm.put(new Student("Lisi3",23),"shanghai");
		hm.put(new Student("Lisi4",24),"wuhan");

		//第一种取出方式keySet
		Set<Student> keySet = hm.keySet();
		Iterator<Student> it = keySet.iterator();

		while(it.hasNext())
		{
			Student stu = it.next();
			String addr = hm.get(stu);
			System.out.println(stu+":"+addr);
		}
		//第二种取出方式entrySet
		Set<Map.Entry<Student,String>> entryset = hm.entrySet();
		Iterator<Map.Entry<Student,String>> iter = entryset.iterator();

		while(iter.hasNext())
		{
			Map.Entry<Student,String> me  = iter.next();
			Student stu = me.getKey();
			String addr = me.getValue();
			System.out.println(stu+"......."+addr);
		}
	}
}

【总结】

       整个Java集合框架分为Collection集合和Map集合,实际它们都有个共同特性,它们的取出方式都最终依赖于Collection集合中的迭代器,Map集合实现将Map.Entry关系存入到Set集合,再用Set集合的迭代器取出。Collection接口延续的集合接口最常用的又分为List和Set,List又分为ArrayList、LinkedList和Vector集合,Vector集合是线程同步的,比较低效,所以Vector集合被ArrayList集合给替代了。ArrayList与LinkedList都各具自己的特点,当需要频繁的增删时选择用LinkedList集合,当需要频繁的查询时选用ArrayList集合,它们具有不同的数据结构才使得它们各有不同的特点。Set集合分为HashSet和TreeSet集合,它们的数据结构分别为哈希表和二叉树各具个的特色,不能存储相同的元素,通过hashCode()和equals()方法进行操作,让它们具有比较性。TreeSet集合中具有两种方式的比较性,第一种让元素就有表性,让元素类去实现Comparator接口,在Compare()方法中定义比较关系。第二种让集合具有比较性,给TreeSet集合传递一个Comparable接口实例,并在被覆盖CompareTo()方法中定义比较关系.Map集合中又分为HashTable、HashMap和TreeMap集合,HashTable集合数据结构为哈希表,但不可以存入null键null值,线程同步并且低效,所以不常用。HashMap集合也为哈希表结构,但可以存入null键null值,线程不同步,所以比较高效。TreeMap集合是二叉树结构,线程不同步,也是比较高效的。Map集合和Set很像,实际上Map集合的底层就是用Set集合,HashMap底层用的是HashSet集合,TreeSet集合底层用的是TreeMap集合。

---------------------- Android开发java培训、期待与您交流! ----------------------详细请查看:www.itheima.com

黑马程序员---Java集合框架

时间: 2024-10-07 11:09:02

黑马程序员---Java集合框架的相关文章

黑马程序员——JAVA集合框架学习总结

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- www.itheima.com 要学好java的集合框架,必须掌握此图: Java集合框架很全面,从大的来说.它包括两种类型: 1.一种是以collection为根接口的集合. 2.另一种是由map为根接口的<key,value>的“图”. 而collection之下的set接口和list接口又有不同: 1.Set 接口继承 Collection,但不允许重复,使用自己内部的一个排列机制.

黑马程序员------Java集合框架学习总结

Java培训.Android培训.iOS培训..Net培训.期待您的交流 一.综述 所有集合类都位于java.util包下.集合中只能保存对象(保存对象的引用变量).(数组既可以保存基本类型的数据也可以保存对象). Java的集合类主要由两个接口派生而出:Collection和Map,Collection和Map是Java集合框架的根接口,这两个接口又包含了一些接口或实现类. 二.Collection接口 Collction: List:有序(元素存入集合的顺序和取出的顺序一致),元素都有索引.

黑马程序员——java集合框架之List,Set

集合框架  1.数组与集合的不同    数组长度是固定的,集合长度是可变的    数组中可以存储基本数据类型,集合只存储对象    集合可以存储不同类型的对象        2.java集合类中有两个顶层接口Collection和Map,下面是对Collection的一些总结: 集合中常用方法:     add方法的参数类型为Object,以便于接受任意类型的对象     集合中存储的都是对象的引用(或者说地址) 迭代器是集合取出元素的方式,此方法是定义在集合的内部,这样取出方式就可以直接访问集

黑马程序员——java集合框架(Map和工具类)

1.Map体系下有三个子类: HashMap    底层是哈希表数据结构,可以存入null键和null值,不同步---TreeMap    底层是二叉树数据结构,线程同步,可以用于给map集合中的键进行排序 和Set很像,Set底层是Map  添加元素时,如果出现相同键,那么厚添加的值会覆盖原有键对应的值,并且put方法会返回被覆盖的值 2.map集合的两种取出方式:  (1) keySet():将map中所有的键存入到Set集合,因为set具备迭代器                 可以以迭代

黑马程序员_Java集合框架

- - - - - android培训.java培训.期待与您交流! - - - - - - 集合框架:用于存储数据的容器. 特点: 对象封装数据,对象多了也需要存储.集合用于存储对象. 对象的个数确定可以使用数组.如果不确定可以用集合.因为集合是可变长度的. 集合和数组的区别: 数组是固定长度的:集合可变长度的. 数组可以存储基本数据类型,也可以存储引用数据类型:集合只能存储引用数据类型. 数组存储的元素必须是同一个数据类型:集合存储的对象可以是不同数据类型. 数据结构:就是容器中存储数据的方

黑马程序员——Java集合基础知识之Collection

集合基础知识--Collection Java中集合框架由常用的Collection接口和Map接口组成,而Collection接口又有两个子接口,是List接口和Set接口,常用的集合框架由这三个类组成. List接口的功能方法 List的使用最为简单,创建集合,通过add方法添加元素,get方法获取元素,通过迭代器获取元素.List接口存放的数据无序的,添加速度快,但是查询速度慢,因为查询的时候必须遍历,每次都重头开始,效率较低.常用实现类有ArrayList,LinkedList. Lis

黑马程序员——Java集合工具类和泛型

Collections工具类和泛型 Collections和Collection Collections和Collection是不同的,Collections是工具类,用来操作集合的,而Collection是集合接口.Collections中有一系列的静态方法用来操作集合,但是不能更改集合内容.比如不能set()不能remove()元素,可以替换全部元素或者添加同一个元素. static List<String> list =Arrays .asList("one Two three

黑马程序员——Java集合基础知识之Map

Map概念 要同时存储两个元素Key和Value,他们之间有映射关系,每个键不能重复,每个键只能映射到一个值. 当数据之间存在映射关系的时候,考虑使用Map集合. Map常用方法 如果添加的键原来有值,后添加的值会覆盖前面的值,并返回之前的值.put会返回来先添加的值,后添加的值会覆盖原有的值. Map tm =new TreeMap(); tm.put (key, value);//MAP没有add tm.remove (key) ;//去除一个key和对应的value,若不存在key返回nu

黑马程序员__集合框架总结

------Java培训期待与您交流! ------- 前言: 本文是对Java集合框架做了一个概括性的解说,目的是对Java集合框架体系有个总体认识,如果你想学习具体的接口和类的使用方法,请参看Java API文档. 一.概述 数据结构对程序设计有着深远的影响,在面向过程的C语言中,数据库结构用struct来描述,而在面向对象的编程中,数据结构是用类来描述的,并且包含有对该数据结构操作的方法. 在Java语言中,Java语言的设计者对常用的数据结构和算法做了一些规范(接口)和实现(具体实现接口