2021/6/3 JAVA集合框架Collection,set,map

1 篇文章 0 订阅
1 篇文章 0 订阅

集合框架

Collection体系

特点:代表任意一组的对象,无序,无下标,不能重复
在这里插入图片描述

Collection示例一

 * Collection接口的使用(一)
 * 1.添加元素
 * 2.删除元素
 * 3.遍历元素
 * 4.判断
 */
public class Demo1{
    pubic static void main(String[] args){
        //创建集合
        Collection collection=new ArrayList();        
//      * 1.添加元素
        Collection.add("苹果");
        Collection.add("西瓜");
        Collection.add("榴莲");
        System.out.println("元素个数:"+collection.size());
        System.out.println(collection);
//      * 2.删除元素
        collection.remove("榴莲");
        System.out.println("删除之后:"+collection.size());
//      * 3.遍历元素
        //3.1 使用增强for 
        for(Object object : collection){
            System.out.println(object);
        }
        //3.2 使用迭代器(迭代器专门用来遍历集合的一种方式)
        //hasnext();判断是否有下一个元素
        //next();获取下一个元素
        //remove();删除当前元素
        Iterator iterator=collection.Itertor();
        while(iterator.hasnext()){
            String object=(String)iterator.next();
            System.out.println(s);
            //删除操作
            //collection.remove(s);引发错误:并发修改异常
            //iterator.remove();应使用迭代器的方法
//      * 4.判断
        System.out.println(collection.contains("西瓜"));//true
        System.out.println(collection.isEmpty());//false
        }
    }
}

Collection示例二:

 * Collection接口的使用(二)
 * 1.添加元素
 * 2.删除元素
 * 3.遍历元素
 * 4.判断
 */
public class Demo2 {
	public static void main(String[] args) {
		Collection collection=new ArrayList();
		Student s1=new Student("张三",18);
		Student s2=new Student("李四", 20);
		Student s3=new Student("王五", 19);
		//1.添加数据
		collection.add(s1);
		collection.add(s2);
		collection.add(s3);
		//collection.add(s3);可重复添加相同对象
		System.out.println("元素个数:"+collection.size());
		System.out.println(collection.toString());
		//2.删除数据
		collection.remove(s1);
		System.out.println("删除之后:"+collection.size());
		//3.遍历数据
		//3.1 增强for
		for(Object object:collection) {
			Student student=(Student) object;
			System.out.println(student.toString());
		}
		//3.2迭代器
		//迭代过程中不能使用collection的删除方法
		Iterator iterator=collection.iterator();
		while (iterator.hasNext()) {
			Student student=(Student) iterator.next();
			System.out.println(student.toString());
		}
		//4.判断和上一块代码类似。
	}
}

list集合

特点:有序,有下标,可重复

List示例一

 * List子接口的使用(一)
 * 特点:1.有序有下标 2.可以重复
 * 
 * 1.添加元素
 * 2.删除元素
 * 3.遍历元素
 * 4.判断
 * 5.获取位置
 */
public class Demo3 {
	public static void main(String[] args) {
		List list=new ArrayList<>();
		//1.添加元素
		list.add("tang");
		list.add("he");
		list.add(0,"yu");//插入操作
		System.out.println("元素个数:"+list.size());
		System.out.println(list.toString());
		//2.删除元素
		list.remove(0);
		//list.remove("yu");结果同上
		System.out.println("删除之后:"+list.size());
		System.out.println(list.toString());
		//3.遍历元素
		//3.1 使用for遍历
		for(int i=0;i<list.size();++i) {
			System.out.println(list.get(i));
		}
		//3.2 使用增强for
		for(Object object:list) {
			System.out.println(object);
		}
		//3.3 使用迭代器
		Iterator iterator=list.iterator();
		while (iterator.hasNext()) {
			System.out.println(iterator.next());
		}
		//3.4使用列表迭代器,listIterator可以双向遍历,添加、删除及修改元素。
		ListIterator listIterator=list.listIterator();
		//从前往后
		while (listIterator.hasNext()) {
			System.out.println(listIterator.next());		
		}
		//从后往前(此时“遍历指针”已经指向末尾)
		while(listIterator.hasPrevious()) {
			System.out.println(listIterator.previous());
		}
		//4.判断
		System.out.println(list.isEmpty());
		System.out.println(list.contains("tang"));
		//5.获取位置
		System.out.println(list.indexOf("tang"));
	}
}

list示例二

/**
 * List子接口的使用(二)
 * 1.添加元素
 * 2.删除元素
 * 3.遍历元素
 * 4.判断
 * 5.获取位置
 */
public class Demo4 {
	public static void main(String[] args) {
		List list=new ArrayList();
		//1.添加数字数据(自动装箱)
		list.add(20);
		list.add(30);
		list.add(40);
		list.add(50);
		System.out.println("元素个数:"+list.size());
		System.out.println(list.toString());
		//2.删除元素
		list.remove(0);
		//list.remove(20);很明显数组越界错误,改成如下
		//list.remove(Object(20));
		//list.remove(new Integer(20));
		System.out.println("元素个数:"+list.size());
		System.out.println(list.toString());
		//3-5不再演示,与之前类似
		//6.补充方法subList,返回子集合,含头不含尾,1包含3不包含
		List list2=list.subList(1, 3);
		System.out.println(list2.toString());	
	}
}

**

List实现类

**
ArrayList【重点】
数组结构实现,查询块、增删慢;
JDK1.2版本,运行效率快、线程不安全。

ArrayList示例一
/**

* ArrayList的使用
 * 存储结构:数组;
 * 特点:查找遍历速度快,增删慢。
 * 1.添加元素
 * 2.删除元素
 * 3.遍历元素
 * 4.判断
 * 5.查找
 */
public class Demo5 {
	public static void main(String[] args) {
		ArrayList arrayList=new ArrayList<>();
		//1.添加元素
		Student s1=new Student("唐", 21);
		Student s2=new Student("何", 22);
		Student s3=new Student("余", 21);
		arrayList.add(s1);
		arrayList.add(s2);
		arrayList.add(s3);
		System.out.println("元素个数:"+arrayList.size());
		System.out.println(arrayList.toString());
		//2.删除元素
		arrayList.remove(s1);
		//arrayList.remove(new Student("唐", 21));
		//注:这样可以删除吗(不可以)?显然这是两个不同的对象。
		//假如两个对象属性相同便认为其是同一对象,那么如何修改代码?
		//3.遍历元素
		//3.1使用迭代器
		Iterator iterator=arrayList.iterator();
		while(iterator.hasNext()) {
			System.out.println(iterator.next());
		}
		//3.2使用列表迭代器
		ListIterator listIterator=arrayList.listIterator();
		//从前往后遍历
		while(listIterator.hasNext()) {
			System.out.println(listIterator.next());
		}
		//从后往前遍历
		while(listIterator.hasPrevious()) {
			System.out.println(listIterator.previous());
		}
		//4.判断
		System.out.println(arrayList.isEmpty());
		//System.out.println(arrayList.contains(new Student("何", 22)));
		//注:与上文相同的问题。
		//5.查找
		System.out.println(arrayList.indexOf(s1));
	}
}

注:Object里的equals(this==obj)用地址和当前对象比较,如果想实现代码中的问题,可以在学生类中重写equals方法:

@Override
public boolean equals(Object obj) {
	//1.是否为同一对象
	if (this==obj) {
		return true;
	}
	//2.判断是否为空
	if (obj==null) {
		return false;
	}
	//3.判断是否是Student类型
	if (obj instanceof Student) {
		Student student=(Student) obj;
		//4.比较属性
		if(this.name.equals(student.getName())&&this.age==student.age) {
			return true;
		}
	}
	//不满足,返回false
	return false;
}

ArrayList源码分析:

默认容量:DEFAUT_CAPCITY=10。
ArrayList存储结构:数组,增删慢,查找和遍历速度快。
tatic final int DEFAULT_CAPACITY 是10,是默认容量。但是如果没向集合中添加任何元素是,当前ArrayList容量为0,添加一个元素后,容量为10。
可以指定初始容量,在构造ArrayList时指定。
ArrayList 每次扩容会扩容为原来的1.5倍。
Object[] elementData 是存放元素的数组。
int size 是实际元素个数。

Vector:

特点:

数组元素实现,查询快,增删慢。
JDK1.0版本,运行效率慢, 线程安全。

LinkedList使用:

创建链表集合:
LinkedList li = new LinkedList<>();

链表结构实现(双向链表),增删快,查询慢。

/**
 * LinkedList的用法
 * 存储结构:双向链表
 * 1.添加元素
 * 2.删除元素
 * 3.遍历
 * 4.判断
 */
public class Demo2 {
	public static void main(String[] args) {
		LinkedList linkedList=new LinkedList<>();
		Student s1=new Student("唐", 21);
		Student s2=new Student("何", 22);
		Student s3=new Student("余", 21);
		//1.添加元素
		linkedList.add(s1);
		linkedList.add(s2);
		linkedList.add(s3);
		linkedList.add(s3);
		System.out.println("元素个数:"+linkedList.size());
		System.out.println(linkedList.toString());
		//2.删除元素
		/*
		 * linkedList.remove(new Student("唐", 21));
		 * System.out.println(linkedList.toString());
		 */
		//3.遍历
		//3.1 使用for
		for(int i=0;i<linkedList.size();++i) {
			System.out.println(linkedList.get(i));
		}
		//3.2 使用增强for
		for(Object object:linkedList) {
			Student student=(Student) object;
			System.out.println(student.toString());
		}
		//3.3 使用迭代器
		Iterator iterator =linkedList.iterator();
		while (iterator.hasNext()) {
			Student student = (Student) iterator.next();
			System.out.println(student.toString());
		}
		//3.4 使用列表迭代器(略)
		//4. 判断
		System.out.println(linkedList.contains(s1));
		System.out.println(linkedList.isEmpty());
		System.out.println(linkedList.indexOf(s3));
	}
}

ArrayList 与LinkedList的区别:
在这里插入图片描述

泛型集合

概念
参数化类型、类型安全的集合,强制集合元素的类型必须一致
特点
编译时即可检查,而非运行时抛出异常
访问时,不必类型转换(拆箱)
不同泛型之间应用不能相互赋值,泛型不存在多态

Set接口

特点:无序,无下标,不可重复
方法:全部继承Collection中的方法

HashSet方法:

/**
 * HashSet集合的使用
 * 存储结构:哈希表(数组+链表+红黑树)
 * 1.添加元素
 * 2.删除元素
 * 3.遍历
 * 4.判断
*/
public class Demo3 {
	public static void main(String[] args) {
		HashSet<Person> hashSet=new HashSet<>();
		Person p1=new Person("tang",21);
		Person p2=new Person("he", 22);
		Person p3=new Person("yu", 21);
		//1.添加元素
		hashSet.add(p1);
		hashSet.add(p2);
		hashSet.add(p3);
        //重复,添加失败
        hashSet.add(p3);
        //直接new一个相同属性的对象,依然会被添加,不难理解。
        //假如相同属性便认为是同一个对象,怎么修改?
        hashSet.add(new Person("yu", 21));
		System.out.println(hashSet.toString());
		//2.删除元素
		hashSet.remove(p2);
		//3.遍历
		//3.1 增强for
		for (Person person : hashSet) {
			System.out.println(person);
		}
		//3.2 迭代器
		Iterator<Person> iterator=hashSet.iterator();
		while (iterator.hasNext()) {
			System.out.println(iterator.next());		
		}
		//4.判断
		System.out.println(hashSet.isEmpty());
        //直接new一个相同属性的对象结果输出是false,不难理解。
        //注:假如相同属性便认为是同一个对象,该怎么做?
		System.out.println(hashSet.contains(new Person("tang", 21)));
	}
}

hashSet存储过程:

根据hashCode计算保存的位置,如果位置为空,则直接保存,否则执行第二步。
执行equals方法,如果方法返回true,则认为是重复,拒绝存储,否则形成链表。
存储过程实际上就是重复依据,要实现“注”里的问题,可以重写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;
    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;
}

TreeSet方法

基于排序顺序实现不重复。
实现了SortedSet接口,对集合元素自动排序。
元素对象的类型必须实现Comparable接口,指定排序规则。
通过CompareTo方法确定是否为重复元素。

TreeSet基本操作1:

/**
 * 使用TreeSet保存数据
 * 存储结构:红黑树
 * 要求:元素类必须实现Comparable接口,compareTo方法返回0,认为是重复元素 
 */
public class Demo4 {
	public static void main(String[] args) {
		TreeSet<Person> persons=new TreeSet<Person>();
		Person p1=new Person("tang",21);
		Person p2=new Person("he", 22);
		Person p3=new Person("yu", 21);
		//1.添加元素
		persons.add(p1);
		persons.add(p2);
		persons.add(p3);
		//注:直接添加会报类型转换错误,需要实现Comparable接口
		System.out.println(persons.toString());
		//2.删除元素
		persons.remove(p1);
		persons.remove(new Person("he", 22));
		System.out.println(persons.toString());
		//3.遍历(略)
		//4.判断
		System.out.println(persons.contains(new Person("yu", 21)));
	}
}

补充:TreeSet集合的使用

Comparator 实现定制比较(比较器)

Comparable 可比较的

// 重写compare

@override
public int compare(Person o1, Person o2){
  int n1 = o1.getAge()-o2.getAge();
  int n2 = o1.getName().comareTo(o2.getName());
  return n1 == 0 ? n2 : n1;
  }

在创建集合的时候就制定好Comparator比较规则

/**
 * TreeSet的使用
 * Comparator:实现定制比较(比较器)
 */
public class Demo5 {
	public static void main(String[] args) {
		TreeSet<Person> persons=new TreeSet<Person>(new Comparator<Person>() {
			@Override
			public int compare(Person o1, Person o2) {
				// 先按年龄比较
				// 再按姓名比较
				int n1=o1.getAge()-o2.getAge();
				int n2=o1.getName().compareTo(o2.getName());
				return n1==0?n2:n1;
			}			
		});
		Person p1=new Person("tang",21);
		Person p2=new Person("he", 22);
		Person p3=new Person("yu", 21);
		persons.add(p1);
		persons.add(p2);
		persons.add(p3);
		System.out.println(persons.toString());
	}
}

Map集合

Map接口的特点:

用于存储任意键值对(Key-Value)。
键:无序、无下标、不允许重复(唯一)。
值:无序、无下标、允许重复。

在这里插入图片描述

方法:

V put(K key,V value)//将对象存入到集合中,关联键值。key重复则覆盖原值。
Object get(Object key)//根据键获取相应的值。
Set//返回所有的key
Collection values()//返回包含所有值的Collection集合。
Set<Map.Entry<K,V>>//键值匹配的set集合

Map接口的使用


```javascript

```javascript

```java
//创建Map集合
Map<String, String> map = new HashMap<>();
// 1. 添加元素
map.put("cn", "中国");
map.put("uk", "英国");
map.put("cn", "zhongguo"); // 会替换第一个 
// 2. 删除
map.remove("uk");
// 3. 遍历
// 3.1 使用KeySet()
//Set<String> keyset = map.keySet(); // 所有Key的set集合
for(String key : map.keyset){
  sout(key + "---" + map.get(key));
}
// 3.2 使用entrySet()
//Set<Map.Entry<String, String>> entries = map.entrySet();
for(Map.Entry<String, String> entry : map.entries){
  sout(entry.getKey() + "---" + entry.getValue();
}

HashMap的使用(重点)

JDK1.2版本,线程不安全,运行效率快;允许用null作为key或是value。

/**
   * HashMap的使用
   * 存储结构:哈希表(数组+链表+红黑树)
   */
  public class Demo2 {
  	public static void main(String[] args) {
  		HashMap<Student, String> hashMap=new HashMap<Student, String>();
  		Student s1=new Student("tang", 36);
  		Student s2=new Student("yu", 101);
  		Student s3=new Student("he", 10);
  		//1.添加元素
  		hashMap.put(s1, "成都");
  		hashMap.put(s2, "杭州");
  		hashMap.put(s3, "郑州");
  		//添加失败,但会更新值
  		hashMap.put(s3,"上海");
  		//添加成功,不过两个属性一模一样;
  		//注:假如相同属性便认为是同一个对象,怎么修改?
  		hashMap.put(new Student("he", 10),"上海");
  		System.out.println(hashMap.toString());
  		//2.删除元素
  		hashMap.remove(s3);
  		System.out.println(hashMap.toString());
  		//3.遍历
  		//3.1 使用keySet()遍历
  		for (Student key : hashMap.keySet()) {
  			System.out.println(key+" "+hashMap.get(key));
  		}
  		//3.2 使用entrySet()遍历
  		for (Entry<Student, String> entry : hashMap.entrySet()) {
  			System.out.println(entry.getKey()+" "+entry.getValue());
  		}
  		//4.判断
  		//注:同上
  		System.out.println(hashMap.containsKey(new Student("he", 10)));
  		System.out.println(hashMap.containsValue("成都"));
  	}
  }

源码分析总结:

1.HashMap刚创建时,table是null,节省空间,当添加第一个元素时,table容量调整为16
2.当元素个数大于阈值(16*0.75 = 12)时,会进行扩容,扩容后的大小为原来的两倍,目的是减少调整元素的个数
3.jdk1.8 当每个链表长度 >8 ,并且数组元素个数 ≥64时,会调整成红黑树,目的是提高效率
4.jdk1.8 当链表长度 <6 时 调整成链表
5.jdk1.8 以前,链表时头插入,之后为尾插入

Collections工具类

方法
public static void reverse(List<?> list)//反转集合中元素的顺序
public static void shuffle(List<?> list)//随机重置集合元素的顺序
public static void sort(List list)//升序排序(元素类型必须实现Comparable接口)

/**
 * 演示Collections工具类的使用
 *
 */
public class Demo4 {
	public static void main(String[] args) {
		List<Integer> list=new ArrayList<Integer>();
		list.add(20);
		list.add(10);
		list.add(30);
		list.add(90);
		list.add(70);
		
		//sort排序
		System.out.println(list.toString());
		Collections.sort(list);
		System.out.println(list.toString());
		System.out.println("---------");
		
		//binarySearch二分查找
		int i=Collections.binarySearch(list, 10);
		System.out.println(i);
		
		//copy复制
		List<Integer> list2=new ArrayList<Integer>();
		for(int i1=0;i1<5;++i1) {
			list2.add(0);
		}
		//该方法要求目标元素容量大于等于源目标
		Collections.copy(list2, list);
		System.out.println(list2.toString());
		
		//reserve反转
		Collections.reverse(list2);
		System.out.println(list2.toString());
		
		//shuffle 打乱
		Collections.shuffle(list2);
		System.out.println(list2.toString());
		
		//补充:list转成数组
		Integer[] arr=list.toArray(new Integer[0]);
		System.out.println(arr.length);
		//补充:数组转成集合 
		String[] nameStrings= {"tang","he","yu"};
		//受限集合,不能添加和删除
		List<String> list3=Arrays.asList(nameStrings);
		System.out.println(list3);
		
		//注:基本类型转成集合时需要修改为包装类
	}
}

完结撒花

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值