集合

集合

  1. 动态的,不需要指定长度。
  2. 集合中只能放 引用/对象 数据类型,若相放基本数据类型 变成包装类。

Collection接口

在这里插入图片描述

	ArrayList<String> list = new ArrayList<>();
// 批量添加
	Collections.addAll(list,"D","c","a","b");
// 利用自然排序
	Collections.sort(list);

// 集合中泛型如果是自定义类型 , 也可以实现定制排序
	Collections.sort(list2, new Comparator<Student2>() {
		@Override
		public int compare(Student2 o1, Student2 o2) {	
			return -(o1.age-o2.age);
		}
	});
	System.out.println(list2);
// 将集合中元素进行 翻转
	Collections.reverse(list2);
//替换集合中的元素, 根据地址进行替换
	Collections.replaceAll(list2, student, new Student2(5));

最大值最小值

// 要求集合中的类实现了  自然排序
// 前提是自定义类实现了Comparable<Studenr2>接口
	Student2 max = Collections.max(list2);
	System.out.println(max);
	Student2 min = Collections.min(list2);
	System.out.println(min);
	
// 定制排序
	Student2 max2 = Collections.max(list2, new Comparator<Student2>() {
			@Override
		public int compare(Student2 o1, Student2 o2) {
			return o1.age-o2.age;
		}
	});
	System.out.println(max2);
	
	Student2 min2 = Collections.min(list2, new Comparator<Student2>() {
		@Override
		public int compare(Student2 o1, Student2 o2) {
			// TODO Auto-generated method stub
			return o1.age-o2.age;
		}
	});
	System.out.println(min2);

List接口:有序且允许重复

ArrayList:线程不安全,效率高
Vector:线程安全,效率低
LinkedList

ArrayList:底层是大小可变的数组,线程不安全

特点:有序且允许重复
场景:适用于频繁操作的场景
初始长度是10,如果有特殊需求,开始就要存储大量数据,则通过构造方法单独设置

优点:遍历速度快,修改速度快
缺点:指定下标插入和删除的时候,可能会移动大量元素,效率较低

遍历

// 1. 产生副本 遍历的是副本
// 2. 遍历副本的时候, 修改的是源集合, 
	for (String string : list) {
		if(string instanceof String){
			list.remove(string);
		}
	}

// 1. 产生副本 遍历的是副本
// 2. 遍历副本的时候, 删除副本的元素, 
// 3. 将副本替换掉原集合
	Iterator<String> it = list.iterator();
	while(it.hasNext()){
		String obj = it.next();
		if(obj instanceof String){
			it.remove();
		}
	}
// 可以有顺序的迭代器
	// 可以有顺序的  迭代器    指针默认在 所有元素的前面
	ListIterator<Integer> listIterator = list.listIterator();
	// 将指针放到  下标为1的元素位置
	ListIterator<Integer> listIterator2 = list.listIterator(1);	
	while(listIterator2.hasPrevious()){
		Integer num = listIterator2.previous();
		if(num==3){
			// 在遍历过程中  添加元素
			listIterator2.add(6);
		}
	}

// 遍历的就是原集合,不是副本
	for (int i = 0; i < list.size(); i++) {
		String str = list.get(i);
		if(str instanceof String){
			list.remove(str);
			// 产生过删除操作的位置,则 i--, 重新检查一遍
			i--;
		}
	}

LinkedList:底层数据结构是双向链表 堆栈结构

特点:有序且允许重复
**优点:插入和删除的时候,效率高**
**缺点:遍历和修改的时候,效率低**
// 创建LinkedList集合对象
	LinkedList<String> list = new LinkedList<>();
	list.add("a");
// 在指定位置插入一个元素。 
	add(int index, E element);
// 添加头和尾的操作
	list.addFirst("z");
	list.addLast("y");
//当队列为空时候,使用add方法会报错,而offer方法会返回false。
	list.offerFirst("z");
	list.offerLast("y");
// 获取头和尾的对象
	String first = list.getFirst();
	String last = list.getLast();
// 获取头和尾的对象
	String peekFirst = list.peekFirst();
	String peekLast = list.peekLast();
// 获取集合开头和结尾的元素,并且在集合中移除
	String pollFirst = list.pollFirst();
	String pollLast = list.pollLast();
// 弹栈  删除第一个元素
	String pop = list.pop();
	System.out.println(pop);
	System.out.println(list);
// 压栈  在第一个元素前添加
	list.push("z");
	System.out.println(list);
// 删除指定元素
	list.remove("a");
// 删除头部元素
	list.removeFirst();
// 删除尾部元素
	list.removeLast();

list集合遍历

	for (String string : list) {
		System.out.println(string);
	}
	
	for (int i = 0; i < list.size(); i++) {
		System.out.println(list.get(i));
	}
	
	Iterator<String> iterator = list.iterator();
	while(iterator.hasNext()){
		iterator.next();
	}

LinkedList与ArrayList区别

ArrayList和LinkedList都实现了List接口,他们有以下的不同点:

	.LinkedList比ArrayList更占内存,因为LinkedList为每一个节点存储了两个引用,一个指向前一个元素,一个指向下一个元素
	.相对于ArrayList,LinkedList的插入,添加,删除操作速度更快,因为当元素被添加到集合任意位置的时候,不需要像数组那样重新计算大小或者是更新索引
练习:要求向集合中添加10个不重复的10~20之间的随机数
	LinkedList<Integer> list = new LinkedList<>();
		for (int i = 0; i < 10; i++) {
			int num = (int)(Math.random()*(20-10+1)+10);
			if(!list.contains(num)){
				list.add(num);
			}else{
				i--;
			}
		}
		System.out.println(list);

Vector:线程同步,底层是数组

Vector 由于使用了 synchronized 方法(线程安全),通常性能上较 ArrayList 差

Set接口:无序且不允许重复

初始容量是16
加载因子:扩容:16*0.75 = 12 16+12 = 28;
当链表长度达到8个的时候,改成红黑树,当删除到六个的时候就改成链表在这里插入图片描述

HashSet

添加元素时,执行的流程:
当调用add方法的时候,add方法内部会自动的调用hashcode计算哈希吗,得到哈希吗之后,会通过哈希表进行比较查看是否有重复元素, 如果没有重复元素,则可以直接添加到集合, 如果有重复元素 则调用equals进行比较. equals方法结果如果为false,则添加到集合, 如果equals的结果为true则不添加

HashCode:获取哈希码
	public static void add(Student stu){
		// 1. 先调用对象的hashcode方法的到一个哈希值
		int hashCode = stu.hashCode();
		//2. 去哈希表中查找遍历, 是否有相同的哈希值
		// 3. 如果没有相同的哈希值, 则直接存入集合
		
	}
	public static void add2(Student stu){
		// 1. 先调用对象的hashcode方法的到一个哈希值
		int hashCode = stu.hashCode();
		//2. 去哈希表中查找遍历, 是否有相同的哈希值
		//3. 找到相同的了哈希值,但是哈希值相同不一定是相同的对象
		// age height;   6   9 
		//				 9   6
		//4. 则调用equals方法 进行 判断 每个属性是否相同,
		//5. 如果各个属性都相同, 就是相同对象,则不添加
		//    如果属性不同,则认为是不同的对象, 就添加
		// equals
	}
// 集合的嵌套
	HashSet<ArrayList<String>> set2 = new HashSet<>();

特殊情况:内容不同 哈希码相同,也要进行存储,利用equals进行对比

Treeset

TreeSet 可以排序的, 泛型是自定义类的话 必须实现排序接口
Comparable 自然排序

HashSet与TreeSet区别

HashSet是由一个hash表来实现的,因此,它的元素是无序的
TreeSet是由一个树形的结构来实现的,它里面的元素是有序的

自然排序

  1. 在泛型中的自定义类中实现Comparable<自定义类名>
  2. 重写compareTo方法
  3. 创建TreeSet集合,向集合中添加元素

定制排序

  1. 编写自定义类
  2. 单独定义比较器类,实现Comparator<自定义类>
  3. 重写compare方法
  4. 创建TreeSet集合,new TreeSet<>(new 比较器对象)
  5. 向集合中添加元素
    定制排序比自然排序耦合性低
    定制排序优先级高
    如果集合中添加的是自定义类型, 则必须实现排序方式中的一种,否则会报ClassCastException
	public class StudentComparator implements Comparator<Student>{
    // compare 和Comparato方法一样
    @Override
    public int compare(Student o1, Student o2) {
        // o1--->this
        // o2--> o用
        // 年龄降序排序
        if(o1.age>o2.age){
            return -1;
        }else if(o1.age<o2.age){
            return 1;
        }
        return 0;
    }

定制排序的 匿名内部类写法

	TreeMap<Person, Integer> map2 = new TreeMap<>(new Comparator<Person>() {
// 排序也只能针对 键起作用, 不能针对值起作用
    	@Override
         public int compare(Person o1, Person o2) {
         	return o1.age -o2.age;
         }
    });

HashSet与HashMap的关系

HashSet中会有一个HashMap的属性,每当创建一个HashSet,就会自动创建一个HashMap
添加数据的时候,是向HashMap的键中添加一个数据

Map接口

在这里插入图片描述

key 不可重复
value 可以重复,若重复 被新的覆盖

HashMap

用哈希表存放,使用频率最高

	HashMap<String, Integer> map  = new HashMap<>();
// 添加元素
	map.put("a", 1);
// 如果键有相同,键只能存储一份, 但是新的值覆盖旧的值
	map.put("a", 5);
// 判断是否包含指定的键
	boolean b = map.containsKey("a");
// 判断是否包含指定的值
	boolean b2 = map.containsValue(13);
// 判断是否为空(集合中没有元素)  没有元素 结果为true, 有元素结果为false
	boolean empty = map.isEmpty();
// 根据键 得到值
	Integer value = map.get("a");

// 如果自定义类放在键的上 是 不允许重复的, 如果自定义类在键的位置上, 则可以通过重写hashcode和equals实现,内容相同只存一个键
	HashMap<Student, Integer> map2 = new HashMap<>();
// 如果自定义类放在值的上 是 不允许重复的. 自定义类放在值的位置上, 即使重写了hashcode和equals没用
	HashMap<Integer, Student> map3 = new HashMap<>();

Map集合遍历

不能通过 增强for循环 直接遍历集合
Set<Map.Entry<K,V>> entrySet()
Set keySet()
Collection values()
通过一些方式进行转换, 转换成 set,Collection这种集合进行遍历
1. 将集合中所有的键全部拿到

	Set<String> keys = map.keySet();
        //  a  b   c
        for (String key : keys) {
            // key =  a   b    c
            Integer value2 = map.get(key);
            System.out.println(key+"="+value2);
        }

2. Collection<V> values() 只能拿到所有的值 不能遍历key
只能通过键找值,不能通过值找键

	Collection<Integer> values = map.values();
        for (Integer integer : values) {
            System.out.println(integer);
        }

3. Set<Map.Entry<K,V>> entrySet()

	Set<Entry<String,Integer>> set = map.entrySet();
        for (Entry<String, Integer> entry : set) {
            String key = entry.getKey();
            Integer value2 = entry.getValue();
            System.out.println(key+"="+value2);
        }

4.通过迭代器的方式

在这里插入图片描述

	Iterator<Entry<String, Object>> it = map.entrySet().iterator();
           while(it.hasNext()){
                Entry<String, Object> entry = it.next();
            	System.out.println("key:"+entry.getKey()+
            	"  key:"+entry.getValue());
          }

TreeMap:

排序也只能针对 键起作用, 不能针对值起作用

	TreeMap<Person,Integer> map = new TreeMap<>(new PersonComparator());
	map.put(new Person("zhangsan", 16), 1);

// 定制排序  匿名内部类的写法
	TreeMap<Person, Integer> map2 = new TreeMap<>(new Comparator<Person>() {
		@Override
		public int compare(Person o1, Person o2) {
			// TODO Auto-generated method stub
			return o1.age -o2.age;
		}
	});

定制排序

	public class PersonComparator implements Comparator<Person>{
		@Override
		public int compare(Person o1, Person o2) {
			return -(o1.age-o2.age);
		}
	}

迭代器

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值