2021-05-27_JAVA_集合

JAVA进阶

学习12.0

集合

概述

集合-容器
此时的存储主要是内存层面的存储

数组:

初始化后:长度不可变;元素类型确定;数组数据可重复;获取元素个数不变;方法有限;

Collection接口

单列集合
如果是自定义数据,需重写equals()方法

List:equals()
Set:(HashSet,LikedHashSet):equals(),hashCode();
(TreeSet):Comparable:CompareTo(Object obj);
Comparator:Compare(Object o1,Object o2);

接口中方法的使用(14种:5+9,如下)

Collection c1=new ArrayList();
Collection c2=new ArrayList();

1 c1.add();
2 c1.size();
3 c1.adAll(c2); c2添加到c1中
4 c1.isEmpty();
5 c1.clear(); 清空

		Collection c1=new ArrayList();
		c1.add(123);
		c1.add("abc");
		c1.add(false);
		c1.add(new Person("lili",18));
		
		// 1 contains() 判断当前集合是否包含obj
		boolean contains=c1.contains(123);
		System.out.println(contains);
		System.out.println(c1.contains(new String("lili")));
		
		boolean contains1=c1.contains(new Person("lili",18));
		System.out.println(contains1);//false  //自定义类一般要重写equals()
		System.out.println(c1);
		
		// 2 containsAll()
		Collection c2=new ArrayList();
		c2.add(123);
		c2.add("abc");
		c2.add(false);
		c2.add(new Person("lili",18));
		System.out.println(c1.containsAll(c2));
		System.out.println("-------------------------");
		
		// 3 remove(Object obj)从当前集合中移除obj
		c1.remove(123);
		System.out.println(c1);
		
		// 4 removeAll(Collection c) 差集: 移除集合c(一样的)
		Collection c3=Arrays.asList(123,"abc",4567);
		c1.removeAll(c3);
		System.out.println(c1);
		
		// 5 retainAll(Collection c)  交集:保留一样的,删除不一样的
		c2.retainAll(c3);
		System.out.println(c2);
		
		// 6 equals(Obeject obj)  完全相同且顺序一样才为真
		System.out.println(c1.equals(c3));
		
		// 7 hashCode() 返回当前对象的哈希值
		System.out.println(c1.hashCode());
		
		// 8  集合--->数组:toArray()
		Object[] arr=c1.toArray();
		for(int i=0;i<arr.length;i++)
		{
			System.out.println(arr[i]);
		}
		
		// 8.1   数组--->集合 : asList()
		List<String> list= Arrays.asList(new String[]{"aa","ss","dd","ff"});
		System.out.println(list);
		
		List l1=Arrays.asList(new int[] {123,456});
		System.out.println(l1.size());//1
		
		List l2=Arrays.asList(new Integer[] {123,456});
		System.out.println(l2.size());//2
		
		List l3=Arrays.asList(123,45);
		System.out.println(l3.size());//2
		
		// 9 iterator() 迭代器, 返回Iterator接口的实例,用于遍历集合元素,放在IteratorTest.java中测试  
		Iterator iterator=c1.iterator();
		//方式三:推荐 
		while(iterator.hasNext())  //hasNext 判断是否还有下一个元素
		{
			System.out.println(iterator.next());  //next指针下移
		}
		//  Iterator中的remove:在遍历的时候删除
		Iterator iterator=c1.iterator();
		System.out.println(c1);
		while(iterator1.hasNext())
		{
			Object obj=iterator1.next();
			if("abc".equals(obj))
			{
				iterator1.remove();
			}
		}
		while(iterator1.hasNext())
		{
			System.out.println(iterator1.next());
		}

使用foreach循环,遍历集合,数组

		//for(集合元素的类型  局部变量:集合对象)
		//内部还是迭代器
		for(Object obj:c4)
		{
			System.out.println(obj);
		}

练习

		String[] arr1=new String[] {"aa","ss","dd"};
//		//方式一:普通for循环,原数组变了
//		for(int i=0;i<arr1.length;i++)
//		{
//			arr1[i]="lkjhg";
//		}
		//方式一:增强for循环  ,原数组不变
		for(String s:arr1)
		{
			s="lkjhg";
		}

List

存有序的,可重复的,“动态”数组

ArrayList,LinkedList,Vector三者异同?

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

List接口常用方法

常用 的:

增:add
删:remove
改:set
查:get
插;add
长度:size
遍历:Iterator迭代器;增强for循环;普通for循环;

例:

// 1 void add(int index,Object ele);在index位置插入ele
		list.add(2, 000);
		System.out.println(list);
		// 2 boolean addAll()
		List list1=Arrays.asList(1,2,3);
		list.addAll(list1);
		System.out.println(list);
		// 3 Object get(int index); 按照索引获取
		System.out.println(list.get(1));
		// 4 int indexOf(Object obj);返回obj在集合中首次出现的位置,如果不存在返回-1
		System.out.println(list.indexOf(456));
		// 5 int lastIndexOf(Object obj);返回obj在集合中最后一次出现的位置
		System.out.println(list.lastIndexOf(789));
		// 6 Object remove(int index);移除指定位置的元素,并返回此元素
		Object obj=list.remove(2);  //删的是位置2的
		// list.remove(new Integer(2);   //删的是数据2
		System.out.println(obj);
		System.out.println(list);
		// 7 Object set(int index,Object ele); 设置指定位置元素为ele
		list.set(0, "aaa");
		System.out.println(list);
		// 8 List subList(int fromindex,int toindex);返回[fromindex,toindex),左闭右开
		List list2=list.subList(2,4);
		System.out.println(list2);
		// 9 遍历
		//方式一:迭代器
		Iterator iterator=list.iterator();
		while(iterator.hasNext())  //hasNext 判断是否还有下一个元素
		{
			System.out.println(iterator.next());  //next指针下移
		}
		//方式二:增强for循环
		for(Object obj1:list)
		{
			System.out.println(obj1);
		}
		//方式三:普通for循环
		for(int i=0;i<list.size();i++)
		{
			System.out.println(list.get(i));
		}
ArrayList

源码分析:jdk7

造对象时创建数组
若数组容量不够,默认情况下扩为原来的1.5倍
建议开发中使用带参的构造器 ArrayList list=new ArrayList(int capacity);

源码分析:jdk8中的变化

第一次调用add时才创建数组(节省内存)

LinkedList

源码分析

底层用链表存储
LinkedList l=new LinkedList(); 内部声明了Node类型的first和last属性,默认值为null
l.add(123); 将123封装到Node中,创建了Node对象
其中,Node定义了 next,prev ; 体现了双向链表

Vector

源码分析:

通过Vector()创造构造器时,都创建了长度为10的数组
扩容时都扩大2倍

Set

存无序的(不是随机的):不可重复的,
Set接口没有定义新的方法

HashSet,LinkedHashSet,TreeSet ?

HashSet:作为Set接口的主要实现类;线程不安全;可以存null值
------LinkedHashSet:是HashSet的子类;遍历其内部数据时,可以按照添加的顺序遍历;效率更高
TreeSet:可以按照添加的对象指定属性进行排序

添加元素的过程:以HashSet为例:
在这里插入图片描述

哈希值不一样时,元素肯定不一样;
哈希值一样,equal不一样时,元素不一样;

为什么写hashCode()方法,有31这个数字?

选择尽量大的系数,减少冲突;

要求:

像Set添加时一定要重写hashCode()和 equals();且尽可能保持一致性
一般直接生成;

HashSet

无序性(不是随机的):存的数据并不是按照数组索引的顺序添加,和哈希值有关
不可重复性:保证添加的元素按照equals()判断时,不能返回true,即相同的元素只能添加一个;

底层原理和HashMap一样

LinkedHashSet

在添加数据的同时,每个数据还维护了两个引用,记录此 数据的前一个数据和后一个数据

TreeSet

添加的数据要求是相同类的对象;
按照从小到大排

两种排序方式:

自然排序:比较两个对象是否相同的标准:compareTo()返回0
定制排序:比较两个对象是否相同的标准:compareTo()返回0

Map接口

双列集合,用来存储一对(key,value)的数据,可以多对一;

实现类:HashMap,LinkedHashMap,TreeMap,Hashtable ?

HashMap:作为map的主要实现类;线程不安全,效率高;存储null的key和value;
------LinkedHashMap:hashMap的子类;保证遍历时可以按照添加的顺序遍历(底层加了指针);效率更高
TreeMap:保证按照太黏的key-value对进行排序;底层使用红黑树;
Hashtable:作为古老实现类;线程安全,效率低;不能存储null的key和value;
------Properties:Hashtable的子类;常用来处理配置文件。key,value都是String 类型

Map中的key:无序的,不可重复的;使用set存储
Map中的value:无序的,可重复的;使用collection存储
一个键值对:key-value构成了一个Entry对象

map常用方法

添加:put
删除:remove
修改:put
查询:get
长度:size
遍历:
如下

		Map map=new HashMap();
		// 1 添加 put
		map.put("aa", 123);
		map.put("bb", 123);
		map.put("cc", 789);
		map.put("dd", 123);
		map.put(111, 321);
		System.out.println(map);
		
		// 2 修改 
		map.put("aa", 456);
		
		// 3 移除 remove(key)
		Object value=map.remove("dd");
		System.out.println(value);
		System.out.println(map);
		
		// 4 查     get,containsKey,containsValue
		System.out.println(map.get("aa"));
		
		boolean isExist=map.containsKey("bb");
		System.out.println(isExist);
		
		boolean isExist1=map.containsValue(123);
		System.out.println(isExist1);
		
		// 5    清空
//		map.clear();  // 不等于 map=null
//		System.out.println(map.size());  
		
		// 6  是否为空
		System.out.println(map.isEmpty()); 
		
		// 7 遍历
		//遍历所有的key集:keySet()
		Set set=map.keySet();
		Iterator iterator=set.iterator();
		while(iterator.hasNext())
		{
			System.out.println(iterator.next());
		}
		System.out.println();
		//遍历所有的value:
		Collection valus=map.values();
		for(Object obj:valus)
		{
			System.out.println(obj);
		}
		
		//遍历所有的key-value
		//方式一:entrySet()
		Set entryset=map.entrySet();
		Iterator iterator1=entryset.iterator();
		while(iterator1.hasNext())
		{
			Object obj=iterator1.next();
			Map.Entry entry=(Map.Entry) obj;
			System.out.println(entry.getKey()+"--->"+entry.getValue());
		}
		//方式二:
		Set set1=map.keySet();
		Iterator iterator2=set.iterator();
		while(iterator2.hasNext())
		{
			Object key=iterator2.next();
			Object keyvalue=map.get(key);
			System.out.println(key+"------"+keyvalue);
		}
HashMap

底层:

数组+链表(jdk7之前)
数组+链表+红黑树(jdk8)

底层实现原理(jdk7)
在这里插入图片描述
底层实现原理(jdk8)
在这里插入图片描述
在这里插入图片描述
加载因子决定数据密度;

LinkedHashMap
TreeMap
Hashtable
Properties
//处理配置文件
		Properties pros =new Properties();
		FileInputStream fis=new FileInputStream("jdbc.properties");
		pros.load(fis);
		
		String name=pros.getProperty("name");
		String password=pros.getProperty("password");
		
		System.out.println("name="+name+",password="+password);

Collections工具类

操作Collection,map的工具类

Collection 和Collections 的区别?

Collection:实现List和Set的接口
Collections:操作map和list的工具类

		List list =new ArrayList();
		list.add(123);
		list.add(98);
		list.add(0);
		list.add(-55);
		list.add(98);
		
		//reverse(list);  反转
		//shuffle(list);  随机排序
		//sort(list);   自然排序,升序
		//swap(list,int i,int j);list的i和j交换

		Collections.reverse(list);
		Collections.shuffle(list);
		Collections.sort(list);
		Collections.swap(list, 1, 3);
		System.out.println(list);
		
	    //int frequency(Collection,Object);返回指定元素的出现次数;
		int fre=Collections.frequency(list, 98);
		System.out.println(fre);
		
		//void copy(List dest,List src);将src复制到dest中
		List dest =Arrays.asList(new Object[list.size()]);
		Collections.copy(dest, list);
		
		System.out.println(dest);
		System.out.println(list);
		
		/*
		 * Collections 类提供了多个synchronizedXxx()方法
		 * 该方法可将指定集合包装成线程同步的集合,从而可以解决
		 * 多线程并发访问集合时的线程安全问题
		 * 
		 * 返回的list1线程安全
		 */
		List list1=Collections.synchronizedList(list);
		

ArrayList和HashMap都是线程不安全的,但是可以转成线程安全的,举例如上

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值