JAVA高级特性-List Set Map

JAVA高级特性-集合框架

为何需要用到集合框架?

在我们已需要存储的数据的个数时,往往可以采用数组存储或者自定义链表等数据结构存储数据。但是如果数据的长度是未知的,则无法满足我们的需求。
因此需要使用到JAVA中的集合框架存储相关数据。

集合框架之间的关系

请添加图片描述
在集合框架中比较常用的一般是ArrayList、LinkedList、HashSet、HashMap
接下来谈谈它们在使用时的一些注意事项-个人观点

List

List接口存储一组 不唯一,有序(插入顺序) 的对象,其2个实现类为ArrayList,LinkedList。前者的底层结构为数组,后者为链表。
前者增删慢,查询遍历快,后者相反。

关于LIst集合常用的几种遍历方法

public class Demo_01 {

	public static void main(String[] args) {
		List<String> list=new ArrayList<String>();
		list.add("1");
		list.add("2");
		list.add("3");
		System.out.println("*****遍历方法一****");
		for(int i=0;i<list.size();i++) {//普通for循环 利用get方法
			System.out.println(list.get(i));
		}
		System.out.println("****遍历方法二*****");
		for(String str:list) {//增强型for循环
			System.out.println(str);
		}
		System.out.println("*****遍历方法三******");
		Iterator it=list.iterator();
		while(it.hasNext()) {//迭代器遍历
			String s=(String)it.next();
			System.out.println(s);
		}
	}
}

List重写了toString方法 ?

	public static void main(String[] args) {
		List<Integer> list=new ArrayList<Integer>();
		list.add(1);
		list.add(3);
		System.out.println("****基本数据类型****");
		System.out.println(list);
		List<Student> stu=new ArrayList<Student>();
		Student stu_1=new Student(12,"da");
		Student stu_2=new Student(12,"da");
		stu.add(stu_1);
		stu.add(stu_2);
		System.out.println("***引用数据类型*****");
		System.out.println(stu);
	}
 结果:
 ****基本数据类型****
[1, 3, 1]
***引用数据类型*****
[day_29.work.Student@7de26db8, day_29.work.Student@1175e2db]

很多人以为List重写了toSring方法 ,其实通过结果可知,并不是这样子。因为包装类Integer(或基本数据类型)重写了toString方法,才可以输出其值,而不是哈希地址等。

Set接口

List集合存储的一般是可重复的元素,如果需要存储不重复的元素,则我们需要用到其他集合,例如Set。
Set接口存储一组唯一,无序的对象。

关于Set集合常用的两种遍历方法

public static void main(String[] args) {
		Set<Integer> set=new HashSet<Integer>();
		set.add(1);
		set.add(2);
		set.add(4);
		set.add(2);//添加相同的元素
		System.out.println(set);//输出其值,Integer类型里重写了toString
		System.out.println("*******遍历方法一****");
		for(Integer in:set) {//增强型for
			System.out.println(in);
		}
		System.out.println("******遍历方法二*******");
		Iterator it=set.iterator();//迭代器
		while(it.hasNext()) {
			System.out.println(it.next());
		}
	}
结果:
[1, 2, 4]
*******遍历方法一****
1
2
4
******遍历方法二*******
1
2
4

通过代码可发现,后续添加的相同元素,set结合只会保留前一个值,如果set中的类型为自定义数据类型,结果又是如何呢?

public static void main(String[] args) {
		//自定义了一个Student类
		Set<Student> set=new HashSet<Student>();
		Student stu=new Student(1,"a");
		Student stu2=new Student(4,"a");
		Student stu3=new Student(1,"a");
		Student stu4=new Student(5,"b");
		
		set.add(stu);
		set.add(stu2);
		set.add(stu3);//添加相同的对象值(地址不一样)
		set.add(stu4);
		System.out.println(set);//Studetn未重写toString方法 ,则输出其地址字段(哈希)
		System.out.println("*******遍历方法一****");
		for(Student st:set) {//增强型for
			System.out.println(st.getNum()+" "+st.getName());
		}
		System.out.println("******遍历方法二*******");
		Iterator it=set.iterator();
		while(it.hasNext()) {
			Student su=(Student)it.next();
			System.out.println(su.getNum()+" "+su.getName());
		}
	}
结果:
[day_29.work.Student@5e265ba4, day_29.work.Student@156643d4, day_29.work.Student@cac736f, day_29.work.Student@379619aa]
*******遍历方法一****
1 a
5 b
4 a
1 a
******遍历方法二*******
1 a
5 b
4 a
1 a

通过结果我们惊奇的发现,set中居然出现了相同的元素,则岂不是与set的唯一性冲突?其实这与set的底层数据结构有关系(哈希表),我们先保留这个问题。

Map

Map集合与Set集合类似,是一个唯一,无序的集合;只是多了一种映射关系。

关于Map集合常用的几种遍历方法

public static void main(String[] args) {
		Map<String,Integer> map=new HashMap<String,Integer>();
		map.put("a", 1);
		map.put("b", 2);
		map.put("c", 3);
		map.put("a", 4);//添加相同映射关系
		map.put("d", 3);
		System.out.println("******遍历方法一******");
		Iterator<String> it=map.keySet().iterator();//迭代器
		while(it.hasNext()) {
			String s=it.next();
			Integer in=(Integer)map.get(s);
			System.out.println(s+" "+in);
		}
		System.out.println("******遍历方法二******");
		for(Map.Entry<String, Integer> maps:map.entrySet()) {//推荐使用
			System.out.println(maps.getKey()+" "+maps.getValue());
		}
		System.out.println("****以自定义数据类型作为键****");
		Map<Student,String> maps=new HashMap<Student,String>();
		Student su=new Student(1,"小吴");
		Student stu=new Student(2,"小米");
		Student st=new Student(1,"小吴");
		maps.put(su,"1");
		maps.put(stu, "2");
		maps.put(st, "1");
		for(Map.Entry< Student,String> ma:maps.entrySet()) {
			Student sus=ma.getKey();
			System.out.println(sus.getNum()+" "+sus.getName()+"maps值:"+ma.getValue());
		}
		
	}
结果:
******遍历方法一******
a 4
b 2
c 3
d 3
******遍历方法二******
a 4
b 2
c 3
d 3
****以自定义数据类型作为键****
1 小吴maps值:1
1 小吴maps值:1
2 小米maps值:2

通过上述代码可发现,当map添加的数据类型为JAVA中定义好的类型时,如果有重复值,后续添加的相同元素会覆盖前面的元素,从而保证其key的唯一性。但是如果我们定义的数据类型为自定义数据类型,则会发现key的值是重复了的,与唯一性冲突。这其实也与Map的底层数据结构有关(哈希表)。

哈希表

哈希表底层使用的也是数组机制,数组中也存放对象,而这些对象往数组中存放时的位置比较特殊,当需要把这些对象给数组中存放时,那么会根据这些对象的特有数据结合相应的算法,计算出这个对象在数组中的位置,然后把这个对象存放在数组中。而这样的数组就称为哈希数组,即就是哈希表。

当向哈希表中存放元素时,需要根据元素的特有数据结合相应的算法,这个算法其实就是Object类中的hashCode方法。由于任何对象都是Object类的子类,所以任何对象有拥有这个方法。即就是在给哈希表中存放对象时,会调用对象的hashCode方法,算出对象在表中的存放位置,这里需要注意,如果两个对象hashCode方法算出结果一样,这样现象称为哈希冲突,如果2个hashcode的值不一样,就不会再调用对象的equals()方法,而是直接把元素添加到集合中。,否则会调用对象的equals方法,比较这两个对象是不是同一个对象,如果equals方法返回的是true,那么就不会把第二个对象存放在哈希表中,如果返回的是false,就会把这个值存放在哈希表中。

总结:如果我使用的数据类型不是java中自带的数据类型(jdk内部已写好),就必须重写equals方法或hashcode方法,保证其set和map集合的唯一性。

Set集合其实就是Map集合套个壳-之前遗留的问题

//jdk源码
  public HashSet() {
        map = new HashMap<>();
    }

由此可知,Set集合的唯一性与Map集合唯一性的实现原理是一样的。

Map集合如何实现一对多的关系?

众所周知,map集合的唯一性使它可以一对一,多对一;那能不能一对多呢?答案当然是可以的。
我们可以借助Set或者List集合,将该集合与某一个key建立映射关系,即可实现。

public static void main(String[] args) {
		
		Map<String,List<Integer>> map=new HashMap<String,List<Integer>>();
		List<Integer> list=new ArrayList<Integer>();
		list.add(1);
		list.add(2);
		list.add(3);
		list.add(4);
		map.put("a", list);
		
		for(Map.Entry<String, List<Integer>> maps:map.entrySet()) {
			List<Integer> li=maps.getValue();
			System.out.println("键:"+maps.getKey());
			System.out.println("   值:");
			for(Integer in:li) {
				System.out.println("\t"+in);
			}
		}
		
		
	}
结果:
键:a
   值:
	1
	2
	3
	4

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值