黑马程序员——java基础之数组与集合之间的点点滴滴

本文深入探讨了数组与集合的基本概念及特点,详细分析了数组的内存分配方式,并介绍了集合框架中的Map、Set、List的不同应用场景及其特点。通过对比数组与集合,帮助读者理解何时选择哪种数据结构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

------- android培训java培训、期待与您交流! ----------
                   数组与集合都是容器,那其中又有着哪些点点滴滴的故事呢?

一、数组

          1、特点

             (1)一旦创建,长度很难改变

             (2)内部元素全为指定的同一种类型

         2、数组的初始化内存分配

             数组是引用类型,存放在堆中,数组中的元素,无论是引用型变量,还是基本数据类型,均是保存在堆内存中。数组的初始化分为声明与创建过程,声明只是在栈内存中声明变量,而创建则实在堆空间开辟空间,内存分配图如下:

       

        3、多维数组

          在了解多维数组之前,先看一看下面一段代码的内存分配的图片

        

            多维数组的意思不过是数组中的元素仍是数组,以前学数组的时候int[][] ar = new int[3][],让我很不解,数组的初始化不是一点要先指定长度吗?其实这只不过是一个障眼法,我们将其与int[] arr比对,其实int[][] arr = new int[3][]只是一个数组声明的过程而已。

二、集合框架

      1、特点:

         (1)长度可变,不固定

           (2)其中的元素全是对象

           2、常用集合框架体系图

            

        3、具体剖析

         (1)Map(键值对)

            数据不只是单个出现的,许多总牵连着关系,例如,看电影买票,座位和你总存在着对应的关系,因此就有了Map的出现。         

           Map的特点

           Map是以键值对形式存在的,其中的键是关键,所以需要保证它的唯一性,由键能索引到值,因此可以把value看错key的附属物,故可将Map看做为一个关联数组。

          常用的Map实现类有HashMapHashtable,LinkedHashMap,Properties,TreeMap

          1)HashMap与Hashtable

            HashMap与Hashtable底层均是哈希表数据结构,用作键的对象必须实现hashCodeequals方法来保证键的唯一性,但其中却有着细微的区别                     

                                  HashMap                                     Hashtable     

                      不可以使用null键和null值       允许使用null键和null               

                        线程同步,效率低                     线程不同步,效率高 

      hashCode()的作用

      当数据存入以hash表结构的集合中时,加入的元素就会根据其hashCode()方法算出hash值,根据hash值就找到了其对应的存储区域,然后再用equals方法对其区域内元素依次进行。

     2)LinkedHashMap以链表为结构,适合于增删改,对于查找的效率相对比HashMap

     3)Properties特点为键值都是String类型,经常与流相结合应用,用于读取配置文件

     4)TreeMap以红黑树为结构,添加的key需实现Comprable,加入的数据会根据复写的compareTo方法进行自然排序,同时也可以根据指定条件排序,排序条件需实现Comparator接口,实现compare方法。    

     Map的遍历

     第一种:将Map中的key转化为Set集合,然后通过迭代Set取得key,再用keyValue

     第二种:将Map转化成Set集合,可获取key以及获取value

     第三种:通过将Map转化为Set集合后,通过迭代实现几个的遍历

     第四种:获取所有的value,然后对value进行遍历,但是无法遍历key 

     TreeMap,Properties的使用与遍历示例

           

package cn.itheima.blog3;

import java.util.Comparator;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.Map.Entry;

class PersonSortByName implements Comparator{

	@Override
	public int compare(Object o1, Object o2) {
		if(o1.getClass() != Person.class || o2.getClass() != Person.class)
			throw new RuntimeException("类型不是Person,不比!!!");
		Person p1 = (Person)o1;
		Person p2 = (Person)o2;
		int temp = p1.getName().compareTo(p2.getName());
		
		return temp == 0 ? p1.getAge() - p2.getAge() : temp;
	}
	
	
}

class Person implements Comparable{
	private String name;
	private int age;
	
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	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;
	}


	//重写hashCode与equals,保证键的唯一性。
	@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;
	}
	
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		final Person other = (Person) 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;
	}
	
	@Override
	//重写compareTo方法,按照年龄从大到小排序,若相当则按照姓名排序
	public int compareTo(Object o) {
		Person p = (Person)o;
		int  temp = this.age-p.age;
		return temp==0?this.name.compareTo(p.name):temp;
	}
	
	@Override
	//方便观看打印结果
	public String toString(){
		return  this.name + this.age + "岁";
	}
	
}

public class TreeMapDemo {

	/**
	 * 演示TreeMap的应用,以及Map的遍历
	 * TreeMap中排序的方式有两种,
	 * 1、自然排序,添加的元素需实现Comparable接口
	 * 2、自定义排序规则,实现Comparatoe接口
	 * 
	 */
	public static void main(String[] args) {
		//先自然排序
		System.out.println("自然排序,keySet遍历---------------------------");
		TreeMap<Person, Integer> map1 = new TreeMap<Person, Integer>();
		map1.put(new Person("xiaowang", 19), 1);
		map1.put(new Person("xiaobai", 22), 4);
		map1.put(new Person("xiaoli", 21), 3);
		//将key转换成Set集合
		for(Person p : map1.keySet()){
			System.out.println("key=" + p +"---->" +"value=" +map1.get(p));
		}
		System.out.println();
		System.out.println("加入重复key后,Map2Set后使用foreach语句遍历------------------");
		//加入key重复的值,对以前进行覆盖
		map1.put(new Person("xiaobai",22), 5);
		//将Map转化为Set集合
		for(Map.Entry<Person, Integer> entry : map1.entrySet()){
			System.out.println(entry.getKey() + "---->" + entry.getValue());
		}
		System.out.println();

		//用自定义的排序条件进行排序
		System.out.println("采用自定义条件排序,Map2Set后使用Iterator迭代遍历--------------");
		TreeMap<Person, Integer> map2 = new TreeMap<Person, Integer>(new PersonSortByName());
		map2.put(new Person("A", 19), 2);
		map2.put(new Person("B", 18), 3);
		map2.put(new Person("C", 20), 4);
		Set<Map.Entry<Person, Integer>> set = map2.entrySet();
		Iterator it = set.iterator();
		while(it.hasNext()){
			Map.Entry<Person, Integer> en = (Entry<Person, Integer>) it.next();
			System.out.println(en.getKey() + "---->" + en.getValue());
		}
	}

}

                     

package cn.itheima.blog3;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

public class PropertiesDemo {

	/**
	 * Properties应用的演示
	 * 需求:将("黑马程序员", "就是牛")存入property.properties文件中
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
        //新建Properties集合
		Properties prop = new Properties();
		//将所需配置信息存入Properties集合中
		prop.setProperty("黑马程序员", "就是牛");	
		//新建文件输出流对象
		FileOutputStream fos = new FileOutputStream("property.properties");
		//将prop存储到流中
		prop.store(fos, "");
		if(fos != null)
			fos.close();
	}

}

 

    (2)Set集合

     Set的底层是依靠Map来实现的,Set中的元素是不可重复的,如同Map中的key一般

     常用实现子类HashSetTreeSetLinkedHashSet,其中的用法与Map相似,HashSetTreeSet中添加的元素不按照正常插入顺序排列,而LinkedHashSet是按照正常插入顺序排列的。Set的实现子类与Map的子类用法相似,在此不赘述。

 

     (3)List集合

     List几个可以装重复的元素,而且数据的顺序按照存放顺序排列

     常用实现类有ArrayList, LinkedList, Vector

     1)ArrayList底层以数组维护,可以实现随机访问查询,但是在进行元素增删改方面,效率低下,因为需要移动大量的元素

     2)LinkedList底层以双端队列链表为结构,既具有先进先出的队列性质,也有后进先出的栈的性质,其非常适合对匀速进行增删改操作

     3)Vector是出现较早的一个集合,他与ArrayList的差别并不大,只是Vector是线程安全的,而ArrayList非线程安全

   

     (4)Map,Set,List之间的联系

       Map中分为keyvalue,我们将value集合起来,从某种意义上说,他就像一个List集合,List相当于所有的key都是IntegerMap;Set依靠Map实现,Map与Set可以相互转换。

    

     (5)Iterator接口:实现该接口并复写iterator后,可使用迭代器,ListSet均实现该接口,所以可以通过迭代器进行遍历,还有一种便是通过for循环

  

三、数组与集合的总结

   当计算机中的数据一多,就需要存储,要存储就需要容器,容器有很多,如对象,数据,集合等,面对不同的数据就需要不同的容器。

   数组与集合的区别:

   1、数组为定长,而集合为不定长

    2、数据可以存储基本数据类型与引用数据类型数据,而集合只能存储对象

    3、数组声明时需指定数据类型,而集合不需要

  

 

 

 

 

      

 

 

                    

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值