Map集合,其他集合,扩容机制

Map集合

  • Map类型的集合称为键值对集合。
    在这里插入图片描述

Map分为 HashMap,TreeMap ,Hashtable 。

a. HashMap:线程不安全,按照hash码的值进行排序并允许使用 null 值和 null 键 ,hashmap的执行速度要高于TreeMap.

b. TreeMap:键不能为null, 根据键的值使用自然排序的方式升序排序,可以使用Comparator进行手动设置排序方式。

c. Hashtable:线程安全,不允许使用null,键值都不能为null 。

  • 键值对 : 一个建对应一个值(键值都是object) ,键不能重复 。

一.HashMap(hashset)

  • HashMap ,初始容量16,加载因子0.75,扩容倍数2倍

1.构造方法

  1. HashMap() 构造一个具有默认初始容量 (16) 和默认加载因子 (0.75) 的空 HashMap。
  2. HashMap(int initialCapacity) 构造一个带指定初始容量和默认加载因子 (0.75) 的空 HashMap。
  3. HashMap(int initialCapacity, float loadFactor) 构造一个带指定初始容量和加载因子的空 HashMap。
  4. HashMap(Map<? extends K,? extends V> m) 构造一个映射关系与指定 Map 相同的 HashMap。

2.常用方法

  1. V
    put(K key, V value) =修改,将指定的值与此映射中的指定键相关联(可选操作)。
  2. V
    remove(Object key) 如果此映射中存在该键的映射关系,则将其删除。
  3. Collection
    values() 返回此映射所包含的值的 collection 视图。
  4. Set
    keySet() 返回此映射中所包含的键的 set 视图。
  5. V
    get(Object key) 返回指定键在此标识哈希映射中所映射的值,如果对于此键来说,映射不包含任何映射关系,则返回 null。
  6. Set<Map.Entry<K,V>>
    entrySet() 返回此映射所包含的映射关系的 collection 视图。
  7. boolean
    isEmpty() 如果此映射不包含键-值映射关系,则返回 true。
  8. int
    size() 返回此映射中的键-值映射关系数。
  9. boolean
    containsKey(Object key) 如果此映射包含对于指定的键的映射关系,则返回 true。
  10. boolean
    containsValue(Object value) 如果此映射将一个或多个键映射到指定值,则返回 true。

接口 Map.Entry<K,V>

  • 在遍历时候的时候使用到了

在这里插入图片描述

a .存储基本类型

//HashMap实例化
	@Test
	void map() {
		//实例化map集合,先存储基本类型
		HashMap<String,Integer> stus=new HashMap<String,Integer>();
		// 添加数据,根据键来判断是否更新:有就更新,没有就不更新 
		//键不能重复,可以为null,值也可以重复可以为null 
		//按照hash码来存放
		stus.put("01",11);
		stus.put("02",22);
		stus.put("03",33);
		stus.put("01",88);//更新数据
		stus.put("03",33);
		stus.put(null,null);
		stus.put("04",null);
		System.out.println(stus);
		//删除,可以通过键删除,也可以通过键值删除
		System.out.println("删除前"+stus);
		Integer remove = stus.remove("01");
		System.out.println(remove);//返回值是删除的元素的值
		//根据键和值同时判断,键有值不相同返回false,只有两个同时相同才返回true 
		boolean remove2 = stus.remove("01",22);
		System.out.println(remove2);
		System.out.println("删除后"+stus);
		//遍历
		//遍历值
		//将map集合中的所有的value值保存到一个collection集合中
		Collection<Integer> values = stus.values();
		for (Integer integer : values) {
			System.out.println(integer);
		}
		//遍历所有的键
		Set<String> keySet = stus.keySet();
		for (String string : keySet) {
			System.out.println(string);
			//stus.get(string)根据键获取对应的值
			System.out.println("键:"+string+"值:"+stus.get(string));
		}
		//entry整体遍历
		// 使用entry进行遍历,将map集合的键值对关系保存为entry,存放到set集合中
		Set<Entry<String,Integer>> entrySet = stus.entrySet();
		for (Entry<String, Integer> entry : entrySet) {
			System.out.println("键"+entry.getKey()+"值:"+entry.getValue());
		}
		//判断map和map进行比较
		System.out.println(stus.equals(33));
		//键值对的个数
		System.out.println("集合的长度:"+stus.size());
		//判断键值对是否为空
		System.out.println(stus.isEmpty());
		//判断有没有
		System.out.println(stus.containsKey("02"));
		System.out.println(stus.containsValue(22));
	}

在这里插入图片描述

b.存储对象类型

	@Test
	void map01() {
		//实例化map集合,存储对象类型
		HashMap<String,Student> stus=new HashMap<String,Student>();
		stus.put("java01", new Student("zs"));
		stus.put("java02", new Student("ls"));
		stus.put("java03", new Student("ww"));
		stus.put("java04", null);
		System.out.println(stus);//{java04=null, java03=Student [name=ww], java02=Student [name=ls], java01=Student [name=zs]}
		//HashMap允许有null值和null键,要注意null值的获取
		Collection<Student> values = stus.values();
		for (Student student : values) {
			if(student!=null) {
				System.out.println(student.name);// ww ls  zs
			}
		}
	}
}
class Student{
	String name;

	public Student(String name) {
		super();
		this.name = name;
	}

	public Student() {
		super();
		// TODO Auto-generated constructor stub
	}

	@Override
	public String toString() {
		return "Student [name=" + name + "]";
	}
	
}

c.存储集合类型

//  hashmap  集合类型    
// 一个学校有三个班级,每个班级有三个学生 
	@Test
	void map02() {
		HashMap<String,ArrayList<Student>> comp=new HashMap<String,ArrayList<Student>>();
		//保存数据,班级
		ArrayList<Student> cs=new ArrayList<Student>();
		//第一个集合为班级,里面嵌套的为学生,若这样存,班级没办法起名字
		//ArrayList<ArrayList<Student>> ass=new ArrayList<ArrayList<Student>>();
		//存学生
		cs.add(new Student("zs"));
		cs.add(new Student("ls"));
		cs.add(new Student("ww"));
		comp.put("001", cs);
		comp.put("002", cs);
		comp.put("003", cs);
		//遍历
		Set<String> keySet = comp.keySet();
		for (String cname : keySet) {
			System.out.println("班级名字:"+cname);
			//获取每一个班级的集合
			ArrayList<Student> arrayList = comp.get(cname);
			//遍历每一个班级集合中的元素
			for (Student stu : arrayList) {
				System.out.println(stu);
			}
			System.out.println("**********************************");
			}
	}
}
class Student{
	String name;

	public Student(String name) {
		super();
		this.name = name;
	}

	public Student() {
		super();
		// TODO Auto-generated constructor stub
	}

	@Override
	public String toString() {
		return "Student [name=" + name + "]";
	}
	
}

二.Hashtable

  • 键和值都不能为null,键和值可以是任意对象类型(自定义对象)
  • 为了成功地在哈希表中存储和检索对象,用作键的对象必须实现 hashCode 方法和 equals 方法。
  • 如果hashtable的键是对象,该对象重写实现 hashCode 方法和 equals 方法。
  • Hashtable的初始默认容量11,加载因子0.75,扩容机制2倍+1。

1.构造方法

  1. Hashtable() 用默认的初始容量 (11) 和加载因子(0.75)构造一个新的空哈希表。
  2. Hashtable(int initialCapacity) 用指定初始容量和默认的加载因子(0.75)构造一个新的空哈希表。
  3. Hashtable(int initialCapacity, float loadFactor) 用指定初始容量和指定加载因子构造一个新的空哈希表。
  4. Hashtable(Map<? extends K,? extends V> t) 构造一个与给定的 Map 具有相同映射关系的新哈希表。
  • 方法使用,以及底层容量获取(反射机制 )
    在这里插入图片描述

2.常用方法

  • 方法与HashMap基本相似

a.键是基本类型 (封装类 )

	//hashtable,键是基本类型 (封装类 )
	@Test
	void hashteble() {
		//实例化
		Hashtable<Integer,String> nums=new Hashtable<Integer,String>(20);
		//循环保存数据
		for (int i = 0; i < 20; i++) {
			nums.put(i, i+"");
		}
		//打印数据
		System.out.println(nums);
		getCp(nums);//集合的容量41
		
	}

	private void getCp(Hashtable<Integer, String> map) {
		// TODO Auto-generated method stub
		Class c = map.getClass();
		try {
			Field declaredField = c.getDeclaredField("table");
			declaredField.setAccessible(true);
			//进行强转
			Entry[] entry = (Entry[]) declaredField.get(map);
			System.out.println("集合的容量"+entry.length);
			} catch (IllegalArgumentException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
		} catch (NoSuchFieldException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

b. 键是对象类型

  • Key是对象类型的 ,重写person的hashcode值之后,有可能导致集合的key值重复。
//键是对象类型  
	//如果hashtable的键是对象,该对象重写实现 hashCode方法和 equals方法。   
	@Test
	void hashteble01() {
		//实例化
		Hashtable<Person,String> persons=new Hashtable<Person,String>();
		persons.put(new Person("zs",20), "中国人");
		persons.put(new Person("ls",14), "外国人");
		persons.put(new Person("ww",14), "外国人");
		persons.put(new Person("ww",14), "外国人");
		System.out.println(persons);
		System.out.println(persons.size());
		System.out.println(persons.toString());
		//persons.put(null,null);//不可以存储null键和值 ,会报空指针异常
	}
}
class Person{
	String name;
	int age;
	public Person() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + 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;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		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;
	}
}

三.TreeMap(treeset) 自然排序

  • TreeMap是根据键进行自然排序的键值对集合,可以使用自定义比较器来改变排序规则 。
  • TreeMap 键不可以为null,值可以是null。

1.构造函数

  1. TreeMap() 构造一个新的空映射,该映射按照键的自然顺序排序。
  2. TreeMap(Comparator<? super K> c) 构造一个新的空映射,该映射根据给定的比较器进行排序。
  3. TreeMap(Map<? extends K,? extends V> m) 构造一个新映射,包含的映射关系与给定的映射相同,这个新映射按照键的自然顺序 进行排序。
  4. TreeMap(SortedMap<K,? extends V> m) 构造一个新的映射,包含的映射关系与给定的 SortedMap 相同,该映射按照相同的排序方式进行排序。

2.代码

  • 方式一
@Test
	void treemap01() {
	//实例化,键不能为null,值可以为null
	TreeMap<Integer,String> nums=new TreeMap<Integer,String>(new Comparator<Integer>() {

		@Override
		public int compare(Integer o1, Integer o2) {
			// TODO Auto-generated method stub
			if(o1>o2) {
				return -1;//逆序
			}else if(o1<o2) {
				return 1;
			}else {
			return 0;
			}
		}
		
	});
	nums.put(19, "zs");
	nums.put(20, "ls");
	nums.put(18, "ww");
	System.out.println(nums);
	}
  • 方式二
@Test
	void treemap02() {
	//实例化,键不能为null,值可以为null
	TreeMap<Integer,String> nums=new TreeMap<Integer,String>(new AscComparator());
	nums.put(10, "张三");
	nums.put(2, "张三");
	nums.put(34, "张三");
	nums.put(22, "张三");
	nums.put(8, "张三");
	System.out.println(nums);//{34=张三, 22=张三, 10=张三, 8=张三, 2=张三}
	}
//自定义比较器,比较器可以有多个    逆序
class AscComparator implements Comparator<Integer>{

	@Override
	public int compare(Integer o1, Integer o2) {
		// TODO Auto-generated method stub
		if(o1>o2) {
			return -1;//逆序
		}else if(o1<o2) {
			return 1;
		}else {
		return 0;
		}
	}
}
	//正序
class DscComparator implements Comparator<Integer>{

		@Override
		public int compare(Integer o1, Integer o2) {
			// TODO Auto-generated method stub
			if(o1>o2) {
				return 1;
			}else if(o1<o2) {
				return -1;
			}else {
			return 0;
			}
		}
}

其他集合

一.Queue

  • 队列集合,先进先出FIFO。 Queue队列集合使用的是LinkedList操作。
    在这里插入图片描述

1.常用方法

  1. E
    element() 检索,但是不移除此队列的头。
  2. boolean
    offer(E o) 如果可能,将指定的元素插入此队列。
  3. E
    peek() 检索,但是不移除此队列的头,如果此队列为空,则返回 null。
  4. E
    poll() 检索并移除此队列的头,如果此队列为空,则返回 null。
  5. E
    remove() 检索并移除此队列的头。
// 队列集合
	@Test
	void queue() {
		Queue<String> strs = new LinkedList<String>();	
		strs.add("1111");
		strs.add("2222");
		strs.add("3333");
		strs.add("4444");
		System.out.println(strs);//[1111, 2222, 3333, 4444]
		for (String string : strs) {
			System.out.println(string);// 1111  2222  3333  4444 
		}
		//queue常用方法
		System.out.println(strs.peek());//查找第一个元素        1111
		System.out.println(strs.poll());//移除第一个元素  并得到第一个元素   1111
		System.out.println(strs);//[2222, 3333, 4444]
		System.out.println(strs.element());//得到第一个元素    2222
		System.out.println(strs);//[2222, 3333, 4444]
	}

二.Properties

在这里插入图片描述

  • Properties是键值对集合,该集合可以使用IO流的操作与properties类型的文件进行数据交互。
  • properties文件是以properties后缀的文件。该文件中的数据全是字符串的,并且是键值对形式的。
  • Stu01=zs-10-java01, 该文件在日常使用中大多数用来保存账号密码, 保存的是不重复的数据信息。
    properties类型文件的标准写法:
  • user-name=admin
  • password=123456
    在eclipse中可以直接创建properties文件,该文件必须保存到项目根目录下(此时不允许将文件保存到src下,src是资源文件夹 )

1.构造方法

  1. Properties() 创建一个无默认值的空属性列表。
  2. Properties(Properties defaults) 创建一个带有指定默认值的空属性列表。

2.常用方法

  1. String
    getProperty(String key) 用指定的键在此属性列表中搜索属性。
  2. String
    getProperty(String key, String defaultValue) 用指定的键在属性列表中搜索属性。
  3. Object
    setProperty(String key, String value) 调用 Hashtable 的方法 put。
// properties集合   键值对都是String的,键不能重复 
		@Test
		void properties() {
			//实例化Properties对象
			Properties pt=new Properties();
			//存储数据
			pt.put("a","100");
			pt.setProperty("b", "200");
			pt.setProperty("c", "300");
			pt.setProperty("d", "500");
			pt.setProperty("c", "400");
			System.out.println(pt);//{b=200, a=100, d=500, c=400}
			//通过键获取
			System.out.println(pt.get("c"));//400
		}
  1. void
    store(OutputStream out, String comments) 以适合使用 load 方法加载到 Properties 表中的格式,将此 Properties 表中的属性列表(键和元素对)写入输出流。
@Test
		void properties01() {
			Properties pt=new Properties();
			//加载外部文件,将外部文件的内容保存到properties对象中,用load方法 
			// 参数是InputStream字节输入流 
			FileInputStream inputstream;
			try {
				inputstream = new FileInputStream(new File("user.properties"));
				pt.load(inputstream);//读取
				// 修改数据,此时是properties内存中的数据
				pt.setProperty("username", "张三");
				pt.setProperty("username1", "zhangsan");
				System.out.println(pt);
				// 将内存中对象中的数据持久化保存到properties文件中 
				FileOutputStream outputstream=new FileOutputStream(new File("user.properties"));
				pt.store(outputstream, "修改后的账户信息");
				System.out.println("数据持久化保存成功");
			} catch (FileNotFoundException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		//读取
		@Test
		void propertiesReader() {
			Properties pt=new Properties();
			FileInputStream inputstream;
			try {
				inputstream = new FileInputStream(new File("user.properties"));
				pt.load(inputstream);//读取
				System.out.println(pt);
			} catch (FileNotFoundException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		@Test
		void propertiesWriter() {
			Properties pt=new Properties();
			pt.setProperty("username", "张三");
			pt.setProperty("username1", "zhangsan");
			pt.setProperty("password", "111111");
			pt.setProperty("password1", "222222");
			try {
				// 将内存中对象中的数据持久化保存到properties文件中 
				FileOutputStream outputstream=new FileOutputStream(new File("user.properties"));
				pt.store(outputstream, "修改后的账户信息");
				System.out.println("数据持久化保存成功");
			} catch (FileNotFoundException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

Properties总结

  • Properties是我们接触第一个持久化数据的技术,该对象中的所有的键值对都是String类型的。
  • load方法用来获取流中的数据并保存到properties对象中 。
  • store方法是用来将properties对象中的数据写到properties文件中 。每一次写数据到properties文件中,都会将原有文件中的数据全部覆盖。
  • 键不能重复, 在properties文件中不要使用username键,可以写user_name

扩容机制

1. Vector 集合扩容机制

  • 默认容量为10
  • 扩容:扩容因子1,扩容机制 *2
    自定义:自定义容量,扩容因子是1,扩容机制,使用构造方法定义

2. ArrayList

  • 默认容量是10
  • 使用Java反射机制来获取集合中的容量大小
  • 扩容:扩容因子是1,扩容机制是原容量* 1.5
public static void main(String[] args) {
		
		ArrayList<Integer> nums=new ArrayList<Integer>(2);
		nums.add(100);
		nums.add(100);
		nums.add(100);//3
		nums.add(100);//4.5  4 
		nums.add(100); 
		nums.add(100);
		nums.add(100);
		// 反射 
		Class c = nums.getClass();
		try {
		//获取属性对象 
		Field declaredField = c.getDeclaredField("elementData");
		// 获取权限,不是public的属性
		declaredField.setAccessible(true);
		//从哪个集合中获取,指定的属性内容
		Object[]  object = (Object[] )declaredField.get(nums);
	    System.out.println(object.length);
		} catch (NoSuchFieldException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

根据需要去选择自己合适的集合进行使用 。
Vactor:初始容量10,加载因子1,扩容机制是原容器的2倍。
ArrayList:初始容量10,加载因子1,扩容机制是原容量的1.5倍。
hashtable:初始容量11,加载因子0.75,扩容机制是原容量的2倍+1。
hashmap:初始容量16,加载因子0.75,扩容机制是原容器的2倍。
Hashset :初始容量16,加载因子0.75,扩容机制是原容器的2倍。

集合总结

一.Collection 单值(对象:自定义对象 封装类 String)

  1. List: 有序可重复集合
  • ArrayList 列表
  • Vector 列表
  • Linkedlist 链表
  • Queue 队列
  1. Set 无序不可重复
  • Treeset 自然排序
  • Hashset hash码排序

二. Map键值对集合,键不可以重复,值可以重复,每一个键对应一个值
Hashmap :键值是null
Hashtable:键值都不可以是null
Treemap:键不能为null,值可以是null

  • 对于可以排序集合tree:
    可以使用comparator比较器来自定义比较规则。
    尤其是treeset要比较的对象需要实现Comparable接口,并重写comparTo方法。
  • properties集合 : 集合中的键值都是String类型的, 该类可以与properties类型的文件采用IO流进行数据交互。 数据的永久保存,持久化。
  • List,Set 集合遍历的方式有基本for循环,foreach循环,iterator迭代器, listiterator,enum(vactor特有的)。
  • Map集合遍历的方式:遍历key,遍历value,使用entry键值对的表示
  • 注意不要在遍历集合的过程中,对集合进行更新操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值