【java学习】集合

解决什么类型的数据用什么结构存储

一、Java集合框架概述

  • 一方面,面向对象语言对事物的体现都是以对象的形式,为了方便对多个对象的操作,就要对对象进行存储
  • 另一方面,使用Array存储对象方面具有一些弊端,而Java集合就像一个容器,可以动态地把多个对象的引用放入容器中。

数组在内存存储方面的特点:
1.数组初始化后,长度确定了;
2. 数组声明的类型,就决定了进行元素初始化的类型。
数组在存储数据方面的弊端:
1.数组初始化后,长度不可变,不便于扩展;
2.数组中提供的属性和方法少,不便于进行增删改的操作,且效率不高,同时无法直接获取存储元素的个数;
3.数组存储的数据是有序的、可重复的,存储数据的特点单一。对于无序、不可重复的需求不能满足;
4.获取数组中实际元素的个数的需求,数组没有现成的属性或方法可用。

  • Java集合类可以用于存储数量不等的多个对象,还可以保存具有映射关系的关联数组。

二、集合框架

在这里插入图片描述
在这里插入图片描述
Collection接口:单列集合,用来存储一个一个对象

  • list接口:存储有序的、可重复的数据,“动态”数组(不用考虑最大长度超不超的问题,代替数组)
    (ArrayList、Linkedlist、Vector)
  • set接口:存储无序的、不可重复的数据,类似数学中的“集合”
    (HashSet、LinkedHashSet、TreeSet)

Map接口:双列集合,用来存储一对(key-value)数据
(HashMap、LinkedHashMap、TreeMap、Hashtable、Properties)

三、Collection接口

1.Collection中常用方法示例:

public class CollectionTest{
@Test
public void test1(){
	Collection coll=new ArrayList();
	//1.add(Object e)将元素e添加到集合coll中
	coll.add('AA');
	coll.add('BB');
	coll.add(123);//自动装箱
	coll.add(new Date());
	
	//2.size()获取添加的元素的个数
	System.out.println(colll.size());//4

	//3.addAll(Collection coll1)将coll1集合中的元素添加到当前集合中
	Collection coll1=new ArrayList();
	coll1.add(456);
	coll1.add("CC");
	coll.addAll(coll1);
	System.out.println(coll1)//4.clear()清空集合中的元素
	coll.clear();
	
	//5.isEmpty()判断当前集合是否为空
	System.out.println(coll.isEmpty())//true
	
	//6.cotains(Object obj)判断当前集合中是否包含该obj
	coll1.add(123);
	coll1.add(456);
	coll1.add(new String("Tom"));
	coll1.add(false);
	coll1.add(new Person("Jerry"),20);//添加自定义类
	System.out.println(coll.contains(123))//true
	System.out.println(coll.contains(new String("Tom")))//true,判断的内容是否相等,实际上调用的equals方法(String包装类重写过该方法)
	System.out.println(coll.contains(new Person("Jerry"),20))//false,自定Person类未重写equals方法

** 结论:向Collection接口的实现类的对象中添加数据obj时,要求obj所在类重写equals()方法 **

	7.//containsAll(Collection coll)判断形参coll中的所有元素是否都存在于当前集合中
	Collection coll1=Arrays.asList(123,456);//返回的List类型是Collection的子接口
	System.out.println(coll.containsAll(coll1))//true
	}	
}
@test
public void test2(){
	Collection coll=new ArrayList();
	coll.add(123);
	coll.add(456);
	coll.add(new String("Tom"));
	coll.add(new Person("Jerry"),20);
	coll.add(false);
	//8.remove(Object obj)移除集合中的元素(先判断其中有没有该元素)
	coll.remove(new Person{name='Jerry',age=20});
	System.out.println(coll);//[123,456,Tom,false]
	
	//9.removeAll(Collection coll1)从当前集合中移除coll1中所有元素(类似做差集)
	Collection coll=Arrays.asList(123,456);
	coll.removeAll(coll1);
	System.out.println(coll);//[Tom,false]

@test
public void test3(){
	Collection coll=new ArrayList();
	coll.add(123);
	coll.add(456);
	coll.add(new String("Tom"));
	coll.add(new Person("Jerry"),20);
	coll.add(false);
	//10.retainAll(Collection coll1);获取当前集合和coll1
	集合的交集,并返回给当前集合(类似交集)
	Collection coll1=Arrays.asList(123,456,789);
	coll.retainAll(coll1);
	System.out.println(coll);//[123,456]
	
	//11.equals(Object obj)比较当前集合和形参是否相等
	Collection coll1=new ArrayList();
	coll1.add(456);
	coll1.add(123);
	coll1.add(new String("Tom"));
	coll1.add(new Person("Jerry"),20);
	coll1.add(false);
	System.out.println(coll.equals(coll1));//false(ArrayList实现List接口,存储需要有序)
	
	//12.hashCode()返回当前对象的哈希值
	System.out.println(coll.hashCode());

	//13.toArray()集合——>数组
	Object[] arr=coll.toArray();
	for(int i=0;i<arr.length;i++){
		System.out.println(arr[i]);
	}

	//拓展:asList()数组——>集合 调用Arrays的静态方法
	List<String> list1=Arrays.asList(new String[]{"AA","BB","CC"});
	System.out.println(List1);
	List list2=Arrays.asList(new int[]{123,456});
	System.out.println(list2.size());//1(会当做一个元素)
	List list3=Arrays.asList(new Interger[]{123,456});
	System.out.println(list3.size());//2(得用包装类)

2.使用Iterator接口遍历集合元素

  • GOF给迭代器模式的定义为:提供一种方法访问一个容器(container)对象中各个元素,而又不需要暴露该对象的内部细节。迭代器模式,就是为容器而生,类似于“公交车上的售票员”、“火车上的乘务员”。
  • Collection接口继承了java.lang.Iterable接口,该接口有一个iterator()方法,那么所有实现了Collection接口的集合类都有一个ierator()方法,用以返回一个实现了Iterator接口的对象。
  • Iterator仅用于遍历集合,Iterator本身并不提供继承对象的能力。如果需要创建Iterator对象,则必须有一个被迭代的集合。
  • 集合对象每次调用iterator()方法都得到一个全新的迭代器对象,默认游标都在集合的第一个元素之前。
    在这里插入图片描述

Iterator接口的方法:

//14.iterator()返回Iterator接口的实例,用于遍历集合元素。
@test
public void test4(){
		Collection coll=new ArrayList();
		coll.add(123);
		coll.add(456);
		coll.add(new String("Tom"));
		coll.add(new Person("Jerry"),20);
		coll.add(false);
		Iterator iterator=coll.iterator();
	//方式一:
		System.out.println(iterator.next());//123
		System.out.println(iterator.next());//456
		System.out.println(iterator.next());//Tom
		System.out.println(iterator.next());//Person{name='Jerry',age=20}	
		System.out.println(iterator.next());//false
		System.out.println(iterator.next());//报异常:NosuchElemenException(没有第六个元素)
	//方式二:
		for(int i=0;i<coll.size();i++){
			System.out.println(iterator.next())
	}
	//方式三:(推荐)hasNext()与next()一起使用
		while(iterator.hasNext()){
			System.out.println(iterator.next())
	}

	//错误写法:每次调用iterator()都会返回一个迭代器对象
		while(coll.iterator().hasNext()){
			System.out.println(coll.iterator().next())//输出一直是第一个元素

	//Iterator中remove()方法
	//删除集合中的"Tom"元素
		Iterator iterator=coll.iterator();
		while(iterator.hasNext()){
		Object obj=iterator.next();
		if("Tom".equals(obj)){
		iterator.remove();	
	}
}
	//遍历该集合看还有没有"Tom"
		Iterator iterator=coll.iterator();
		while(iterator.hasNext()){
			System.out.println(iterator.next())
	}

foreach循环遍历集合或数组

//遍历集合
@Test
public void test4(){
		Collection coll=new ArrayList();
		coll.add(123);
		coll.add(456);
		coll.add(new String("Tom"));
		coll.add(new Person("Jerry"),20);
		coll.add(false);
	//for(集合元素的类型 局部变量:集合对象)
	//内部仍然调用了迭代器
		for(Object obj:coll){
			System.out.println(obj);
	}
}
//遍历数组
@Test
	public void test5(){
		int[] arr=new int[]{1,2,3,4,5,6};
		for(int i:arr){
			System.out.println(i);
	}
}

3.List接口

ArrayList/LinkedList/Vetor的比较

三个类都实现了List接口,存储数据的特点相同:存储有序、可重复的数据
ArrayList:作为List接口的主要实现类。线程不安全,但效率高;底层用Object[] elementData存储
LinkedList:对于频繁的插入、删除操作,使用此类效率比ArrayList高;底层使用双向链表存储
Vetor:作为List接口的古老实现类。线程安全,效率低;底层用Object[] elementData存储

1.ArrayList源码分析:
(1)jdk7情况下:

ArrayList list =new ArrayList();//底层创建了长度为10的Object[]数组elementData
list.add(123);//相当于elementData[0]=new Interger(123);
....
list.add(11);//如果此次的添加导致底层elementData数组容量不够,则扩容,默认情况下,扩容为原来容量的1.5倍,同时将原有数组中的数据复制到新的数组中。故线程不安全

结论:为了避免扩容,建议开发中使用带参的构造器:
ArrayList list=new ArrayList(int capacity);

(2)jdk8情况下:

ArrayList list =new ArrayList();//底层Object[] elementData初始化为{},并没有长度为10的数组
list.add(123);//第一次调用add()时,底层才创建了长度为10的数组,并将数据123添加到elementData[0]
...
后续的添加与扩容操作与jdk7一致

小结:jdk7中的ArrayList对象的创建类似于单例的饿汉式,而jdk8中ArrayList对象的创建类似于单例的饿汉式,延迟了数组的创建,节省内存。

2.LinkedList源码分析:

ArrayList list =new ArrayList();//内部声明了Node类型的firt和last属性,默认值为null
list.add(123);//第一次调用add()时,将123封装到Node中,创建了Node对象(双向链表结点)

List除了从Collection集合继承的方法外,List集合里添加了一些根据索引来操作集合元素的方法。(由于Collection接口中包含Set接口,是无序的,所以索引的操作单独在List接口中添加)

3.List接口常用方法:

public class ListTest{
	@Test
	public void test1{
		ArrayList list=new ArrayList;
		list.add(123);
		list.add(456);
		list.add("AA");
		list.add(new Person("Tom","12"));
		list.add(456);

	//1.add(int index,Object ele)在index位置插入ele元素
		list.add(1,"BB");
		System.out.println(list);
		//"BB"被插入到123和456之间
		
	//2.addAll(int index,Collection ele)从index位置开始将ele中所有元素添加到原集合
		List list1=Arrays.asList(1,2,3);
		list.addAll(list1);//如果用add()则会把list1当一个元素加入原集合,用size()则会输出7
		System.out.println(list.size());//9
		
	//3.Object get(int index)获取指定index位置的元素
		System.out.println(list.get(0));//123

	//4.int indexOf(Object obj)返回obj在当前集合中首次出现的位置,没有返回-1;
		System.out.println(list.indexOf(456));

	//5.int lastIndexOf(Object obj)返回obj在当前集合中末次出现的位置
	
	//6.Object remove(int index)移除指定index位置的元素,并返回此元素(与Collection中的方法重载,可以按照对象删也可以按照索引删)
		Object obj =list.remove(0);
		System.out.println(obj);//返回删除位置的元素123

	//7.Object set(int index,Object ele)设置指定index位置的元素为ele
		list.set(1,"CC")
		System.out.println(list);//将索引为1的元素改成CC

	//8.List subList(int fromIndex,int toIndex)返回从fromIndex到toIndex位置的左闭右开子集合
		System.out.println(list.sublist(2,4));
	}
}

常用方法总结:
增:add(Object obj)
删::emove(int index)/remove(Object obj)
改:set(int index,Object ele)
查:get(int index)
插:add(int index,Object ele)
长度:size()
遍历:1.Iterator迭代器方式2.增强for循环3.普通循环

4.Set接口(开发中用的少)

HashSet/LinkedHashSet/TreeSet比较

三个类都实现了Set接口,存储数据的特点相同:存储无序、不可重复的数据(类似集合)
HashSet:作为Set接口的主要实现类;线程不安全;可以存储null值
LinkedHashSet:作为HashSet的子类;遍历其内部数据时,可以按照添加的顺序遍历(并非有序)
TreeSet:可以按照添加对象的指定属性进行排序(用到Comparator和Comparable接口)

1.HashSet/LinkedHashSet详解

  • Set接口中没有额外定义新的方法,使用的都是Collection中声明过的方法。
  • 向Set中添加的数据,其所在的类一定要重写hashCode()和equals()方法,重写的方法尽可能保持一致性:即相等的对象必须具有相等的散列码。
  • 无序性:不等同于随机性。以HashSet为例,存储的数据在底层并非按照数组索引的顺序添加,而是根据数据的哈希值决定。
  • 不可重复性:保证添加的元素按照equals()判断时,不能返回true,即相同的元素只能添加一个。

添加元素的过程:(HashSet为例)
我们向HashSet中添加元素a,首先调用元素a所在类的hashCode()方法,计算元素a的哈希值,再通过某种算法计算出在HashSet数组中的存放位置(索引位置),判断数组此位置上是否已经有元素:
若没其他元素,则元素a添加成功
若有其他元素,则比较两者的hash值,若不同则添加成功;若相同则进而调用元素a所在类的equals()方法,一样则添加失败,否则成功。

public class SetTest{
	@Test
	public void test1{
		Set set=new HashSet();//若用LinkedHashSet(),则输出顺序与添加顺序一致,但并非有序
		Set.add(123);
		Set.add(123);//重复数据在输出中不显示
		Set.add(456);
		Set.add("AA");
		Set.add("CC");
		Set.add(new Person("Tom","12"));
		Set.add(129);
		Iterator iterator=set.iterator();
		while(iterator.hasNext()){
			System.out.println(iterator.next());
			//输出与输入顺序不一致,存储无序的
		}
	}
	@Test
	public void test2{
		Set set=new LinkedHashSet();
		Set.add(123);
		Set.add(456);
		Set.add("AA");
		Set.add("CC");
		Set.add(new Person("Tom","12"));
		Set.add(129);
		Iterator iterator=set.iterator();
		while(iterator.hasNext()){
			System.out.println(iterator.next());
			//输出与输入顺序一致,存储仍是无序的,
			//但是在添加数据的同时,还为每个数据添加了两个地址,
			//记录前后两个数据,所以可以保持输出顺序一致。
			//对于频繁的遍历操作,其效率高于HashSet
		}
	}
}

2.TreeSet详解

  • 向TreeSet中添加的数据,要求是相同类的对象。
  • 两种排序方式:自然排序和定制排序
  • 自然排序中,比较两个对象是否相同的标准为:compareTo()返回0,不再是equals()方法
  • 定制排序中,比较两个对象是否相同的标准为:compare()返回0,不再是equals()
@Test
	public void test2{
		TreeSet set=new TreeSet();
		//失败,不能添加不同类的对象
		//Set.add(123);
		//Set.add(456);
		//Set.add("AA");
		//Set.add("CC");
		//Set.add(new Person("Tom","12"));
		
		//举例一:
		TreeSet set=new TreeSet();
		set.add(34);
		set.add(-34);
		set.add(43);
		set.add(11);
		set.add(8);
		Iterator iterator=set.iterator();
		while(iterator.hasNext()){
			System.out.println(iterator.next());
			//输出为从小到大顺序
		}
		
		//举例二:
		TreeSet set=new TreeSet();
		set.add(new User("Tom","12"));
		set.add(new User("Jerry","32"));
		set.add(new User("Mike","2"));
		set.add(new User("Jack","33"));
		//User类需要实现comparable接口,重写compareTo()方法
		Iterator iterator=set.iterator();
		while(iterator.hasNext()){
			System.out.println(iterator.next());
			//输出按照重写的compareTo()方法进行排序
		}
		
		//举例三:
		TreeSet set=new TreeSet(new Comparator(){
		//按照年龄从小到大排序
		@Overrride
		public int compare(Object o1,Object o1){
			if(o1 instanceof User&&o2 instanceof User){
				User u1=(User)o1;
				User u2=(User)o2;
				return Integer.compare(u1.getAge(),u2.getAge())
			}else{
				throw new RuntimeEception("输入的数据类型不匹配");
			}
		}
	});
		set.add(new User("Tom","12"));
		set.add(new User("Jerry","32"));
		set.add(new User("Mike","2"));
		set.add(new User("Jack","33"));
		Iterator iterator=set.iterator();
		while(iterator.hasNext()){
			System.out.println(iterator.next());
			//输出按照重写的compareTo()方法进行排序
		}

	}

四、Map接口

1.Map主要实现类

Map:双列数据,存储kay-value对的数据。类似于函数
|----|----HashMap:作为Map的主要实现类;线程不安全的,效率高;可以存储null的key和value。
|----|----|----LinkedHashMap:保证在遍历map元素时,可以按照添加的顺序实现遍历(在原有HashMap底层结构基础上,添加了一对指针,指向前后元素)对于频繁的遍历操作,此类执行效率高于HashMap。
|----|----TreeMap:保证按照添加的key-value对进行排序,实现排序遍历。此时考虑key的自然排序和定制排序。(底层使用红黑树) |----|----Hashtable:作为古老的实现类;线程安全的,效率低;不能存储null的key和value。
|----|----|----Properites:常用来处理配置文件;key和value都是String类型

HashMap的底层:数组+链表(jdk7之前)
数组+链表+红黑树(jdk8)

2.Map结构的理解

  • Map中的key:无序的、不可重复的,使用Set存储所以的key([以hashMap为例]则key所在的自定义类要重写equals()和hashCode()方法)
  • Map中的value:无序的、可重复的,使用Collection存储所有value(则value所在的自定义类要重写equals())
  • 一个键值对:key-value构成了一个Entry对象
  • Map中的entry:无序的、不可重复的,使用Set存储所有的entry

3.底层实现原理

(1)HashMap的底层实现原理

(面试高频)

jdk7中
HashMap map=new HashMap()
//在实例化以后,底层创建了长度为16的一维数组Entry[]
table …(已经执行了多次put)…
map.put(key1,value1)
//首先,调用key1所在类的hashCode()计算key1哈希值,此哈希值经过某种算法计算以后,得到在Entry数组中的存放位置。
如果此位置上的数据为空,此时的key1-value1添加成功----情况1
如果此位置上的数据不为空(意味着此位置上存在一个或多个数据,以链表形式),则要比较key1和已经存在的一个或多个数据的哈希值
|----如果key1的哈希值与已经存在的数据(key2-value2)的哈希值都不同,此时key1-value1添加成功----情况2
|----如果key1的哈希值和已经存在的某一个数据的哈希值相同,则继续比较:调用key1所在类的equal()方法:
|---- |---- 如果equal()返回false:此时key1-value1添加成功----情况3
|---- |---- 如果equal()返回ture:使用value1替换value2(添加了修改原本value)
补充:关于情况2和情况3:此时key1-value1和原来的数据以链表的方式存储
在不断的添加过程中,会涉及到扩容问题,当超出临界值时(且要存放的位置非空时),默认的扩容方式:扩容为原来容量的2倍,并将原有的数据复制过来。


jdk8相较于jdk7在底层实现方面的不同:
1.new HashMap():底层没有创建一个长度为16的数组
2.jdk8底层的数组是:Node[],而非Entry[]
3.首次调用put()方法时,底层创建长度为16的数组
4.jdk8中底层结构:数组+链表+红黑树,七上八下
当数组的某一个索引位置上的元素以链表形式存在的数据个数>8且当前数组的长度>64时,此时此索引位置上的所有数据改为用红黑树存储

(2)LinkedHashMap0底层实现原理(了解)

LinkedHashMap是HashMap的子类,之所以输出顺序与输入顺序一致是因为将父类中的内部类Node改成了Entry并且在中间添加了before,after属性,可以标明前后元素。

public class SetTest{
	@Test
	public void test1{
			Map map=new HashMap();
			map.put(null,null);
		//可以存储null值
		
			Map map=new LinkedHashMap();
			map.put(123,"aa");
			map.put(345,"bb");
			map.put(12,"cc");
			System.out.print(map);
		//LinkedHashMap输出的序列为输入的序列
	}
}

4.Map接口中的常用方法

(以HashMap为例)

public class MapTest{
	@Test
	public void test1(){
		//1.Object put()添加
			Map map=new HashMap();
			map.put("AA",123);
			map.put(45,123);
			map.put("BB",56);
		//将AA==123,修改成AA==87
			map.put("AA",87);
			System.out.println(map);
		//输出{AA=87,BB=56,45=123}
		
		//2.void putAll(Map m)将m中所有的key-value对存放到当前map中
			Map map1=new HashMap();
			map1.put("CC",123);
			map1.put("DD",123);
			map.putAll(map1);
			System.out.println(map);

		//3.Object remove(Object key)
			Object value=map.remove("CC");
			System.out.println(value);//123
			System.out.println(map);//输出{AA=87,BB=56,DD=123,45=123}

		//4.void clear()
			map.clear();//将map中的元素清除,map对象还在
			System.out.println(map);//{/}
			System.out.println(map.size());//0
	}
		@Test
		public void test2(){
			Map map=new HashMap();
			map.put("AA",123);
			map.put(45,123);
			map.put("BB",56);
		//5.Object get(Object key)获取指定key对应的value
			System.out.println(map.get(45));//123
		
		//6.boolean containsKey(Object key)/containsValue(Object value)
			boolean isExist=map.containsKey("BB");
			System.out.println(isExist);//true
		
			boolean isExist=map.containsValue(123);
			System.out.println(isExist);//ture,只要找到一个就不会继续找了

		//7.boolean isEmpty()
			map.clear();
			System.out.println(map.isEmpty());//ture

		//8.boolean equals(Object obj)判断当前map和参数对象obj是否相等
					
		}
}

由于Map没有iterator方法,但是Set以及Collection有,在第二节Map的结构中可知,Map中的key用Set存储,而value用Collection存储,键值对构成的Entry对象用Set存储,故要想遍历Map中的元素可以获取其Set或Collection集合,再调用iterator方法。

		@Test
		public void test2(){
			Map map=new HashMap();
			map.put("AA",123);
			map.put(45,123);
			map.put("BB",56);
		//9.Set keySet()遍历所有key集
			Set set=map.keySet()
			Iterator iterator=set.iterator();
			while(iterator.hasNext()){
			System.out.println(iterator.next());
			//AA BB 45
			}
		
		//10.Collection values()遍历所有的value集
			Collection values=map.values();
			for(Object obj:values){
				System.out.println(obj);
				//123 56 123
				//与keySet顺序一致

		//11.Set entrySet()遍历所有的key-value
			//方式一:
			Set entrySet=map.entrySet();
			Iterator iterator1=entrySet.iterator();
			while(iterator1.hasNext()){
				Object obj=iterator1.next();
			//entrySet集合中的元素都是entry
				Map.Entry entry=(Map.Entry) obj;
			//调用entry的getKey()和getValue()方法
				System.out.println(entry.getKey()+"---->"+entry.getValue());
			//AA---->123 BB---->56 45---->123

			//方式二:keySet()+value()拼接出
			Set keySet=map.keySet();
			Iterator iterator2=keySet.iterator();
			while(iterator2.hasNext()){
				Object key=iterator2.next();
				Object value=map.get(key);
				System.out.println(key+"---->"+value);
			}
		}

常用方法总结:
增:put(Object key,Object value)
删::remove(Object key)
改:set(Object key,Object ele)
查:get(Object key)
插:无序所有没有插入操作
长度:size()
遍历:keySet()/values()/entrySet/keySet+values拼接

5.Map其他实现类

1.TreeMap介绍

向TreeMap中添加key-value,要求key必须是由同一个类创建的对象,因为要按照key进行排序:自然排序、定制排序
(不能按照value值排序)

public class TreeMapTest{
	@Test
	public void test1(){
	//自然排序
			TreeMap map=new TreeMap();
		//自定义User类,User已经继承Comparable接口,重写compareTo()方法
			User u1=new User("Tom",23);
			User u2=new User("Jerry",32);
			User u3=new User("Jack",20);
			User u4=new User("Rose",18);
			map.put(u1,98);
			map.put(u2,89);
			map.put(u3,76);
			map.put(u4,100);
			Set entrySet=map.entrySet();
			Iterator iterator=entrySet.iterator();
			while(iterator.hasNext()){
				Object obj=iterator.next();
				Map.Entry entry=(Map.Entry) obj;
				System.out.println(entry.getKey()+"---->"+entry.getValue());
			//按照名字从小到大顺序输出
	}
	@Test
	public void test1(){
	//定制排序
			TreeMap map=new TreeMap(new Compartor(){
			@Override
			public int compare(Object o1,Object o2){
				if(o1 instanceof User&&o2 instanceof User){
					User u1=(User)o1;
					User u2=(User)o2;
					return Integer.compare(u1.getAge(),u2.gerAge());
				}	
				throw new RuntimeException("输入的类型不匹配");
			}
	});
			User u1=new User("Tom",23);
			User u2=new User("Jerry",32);
			User u3=new User("Jack",20);
			User u4=new User("Rose",18);
			map.put(u1,98);
			map.put(u2,89);
			map.put(u3,76);
			map.put(u4,100);
			Set entrySet=map.entrySet();
			Iterator iterator=entrySet.iterator();
			while(iterator.hasNext()){
				Object obj=iterator.next();
				Map.Entry entry=(Map.Entry) obj;
				System.out.println(entry.getKey()+"---->"+entry.getValue());
			//按照年龄大小从小到大输出
	}
}

2.Properties介绍

  • Properties类是Hashtable的子类,用于处理属性文件
  • 由于属性文件里的key、value都是字符串类型,所以Properties里的key和value都是字符串类型
public class PropertiesTest{
	public static void main(String[] args){
	//在程序中读取配置文件的内容
		Properties pros=new Properties();
		FileInputStream fis=new FileInputStream("jdbc.properties");//自己创建的jdbc.properties配置文件,内容:name=Tom password=abc123
		pros.load(fis);//加载流对应的文件
		String name=pros。getProperty("name");
		String passward=pros.getProperty("passward");
		System.out.println("name="+name+"passward="+passward);
		fis.close;
	}
}

五、Collections工具类

Collection是一个操作Set、List和Map等集合的工具类

public class CollectionTest{
	@Test
	public void test1(){
			List list =new ArrayList();
			list.add(123);
			list.add(43);
			list.add(765);
			list.add(-97);
			list.add(0);
			System.out.println(list);//[123,43,765,-97,0]
	
		//1.reverse(List)反转集合顺序
			Collections.reverse();
			System.out.println(list);//[0,-97,765,43,123]

		//2.shuffle(List)随机化排序
			System.out.println(list);//[43,765,-97,123,0]
			//每次随机不一样
		
		//3.sort(List)根据元素的自然排序对指定List集合元素按升序排序
		//sort(List,comparator)根据指定的Comparator(定制排序)对List集合元素排序
			Collections.sort(list);
			System.out.println(list);//[-97,0,43,123,765]
		
		//4.swap(List,int i,int j)将指定list集合中的i处的元素和j进行交换
		
		//5.Object max/min(Collection)根据元素的自然排序,返回给定集合最大/小元素
		//Object max/min(Collection,Comparator)根据Comparator(定制排序),返回集合中最大/小元素

		//6.int frequency(Collection,Object)返回指定集合中指定元素的出现次数
		
		//7.void copy(List dest,List src)将src中的内容复制到dest中
			List list =new ArrayList();
			list.add(123);
			list.add(43);
			list.add(765);
			list.add(-97);
			list.add(0);
			//错误写法
			List dest=new ArrayList();
			Collections.copy(dest,list);
			System.out.println(dest);//报错:Source does not fit in dest
			//正确写法
			List dest=Arrays.asList(new Object[list.size()]);
			//得先造一个和list长度一样的集合dest
			System.out.println(dest.size());//和list.size()长度一致
			Collections.copy(dest,list);
			System.out.println(dest);

		//8.boolean replaceAll(List list,Object,Object newVal)使用新值替换List中的旧值
	}
}

在开发中,如果需要线程安全,我们一般也不会使用Vetor和Hashtable,而是将ArrayList和HashMap改成线程安全的。
Collections类中提供了多个synchronizedXXX()方法,该方法可使将指定集合包装成线程同步的集合,从而可以解决多线程并发访问集合时的线程安全问题

public class CollectionTest{
	@Test
	public void test2(){
			List list =new ArrayList();
			list.add(123);
			list.add(43);
			list.add(765);
			list.add(-97);
			list.add(0);
			List list=Collections.synchronizedList(list);
			//该list即为线程安全的
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值