Java之集合(List和Set)

集合的概念

概念:对象的容器,定义了对多个对象进行操作的常用方法,可实现数组的功能
和数组的区别:

  • 数组的长度固定,集合长度不固定
  • 数组可以存储基本类型和引用类型.集合只能存储引用类型

位置:java.util.*;

  • 集合只能存放对象,比如存一个int型数据i放入集合中,其实它是自动转换成Integer类后存入的,Java中的每一种基本类型都有对应的引用类型(包装类)
  • 集合存放的是多个对象的引用,对象本身还是放在堆内存中
  • 集合可以存放不同类型,不限数量的数据类型
  • 使用foreach循环遍历
for(数据类型 局部变量:集合名){
	//循环内部的局部变量,代表当次循环从集合中取出的对象
}

Collection集合体系

在这里插入图片描述
Collection接口

  • List接口和Set接口的父接口
  • 特点:代表一组任意类型的对象,无序、无下标
  • 方法:
//添加一个对象
boolean add(Object obj)
//将一个集合中的所有对象添加到此集合中
boolean addAll(Collection c)
//清空此集合中的所有对象
void clear()
//检查此集合中是否包含o对象
boolean contains(Object o)
//比较此集合是否与指定对象相等
boolean equals(Object o)
//判断此集合是否为空
boolean isEmpty()
//在此集合中移除o对象
boolean remove(Object o)
//删除所有元素
boolean removeAll(Collection c)
//返回此集合中的元素个数
int size()
//将此集合转换成数组
Object[] toArray()

Collection中的高级功能:

  • boolean addAll(Collection c):添加一个集合中的所有元素
public class CollectionDemo {
	
	public static void main(String[] args) {
		
		Collection<String> c1 = new ArrayList<String>();
		Collection<String> c2 = new ArrayList<String>();
		
		c1.add("abc1");
		c1.add("abc2");
		c1.add("abc3");
		
		c2.add("abc4");
		c2.add("abc5");
		c2.add("abc6");
		
		c1.addAll(c2);
		System.out.println(c1);
	}

}

在这里插入图片描述

  • boolean removeAll(Collection c):问题:是删除一个算删除还是删除所有算删除?
public class CollectionDemo {
	
	public static void main(String[] args) {
		
		Collection<String> c1 = new ArrayList<String>();
		Collection<String> c2 = new ArrayList<String>();
		
		c1.add("abc1");
		c1.add("abc2");
		c1.add("abc3");
		c1.add("abc6");
		
		c2.add("abc1");
		c2.add("abc2");
		c2.add("abc6");
		
		System.out.println("c1c2:"+c1.removeAll(c2));
		System.out.println(c1);
	}

}

删除所有元素,只要集合中有一个元素被包含,将这个元素从c1删除掉,则返回true
在这里插入图片描述

  • boolean containsAll(Collection c):问题:包含一个算包含还是包含所有算包含?
public class CollectionDemo {
	
	public static void main(String[] args) {
		
		Collection<String> c1 = new ArrayList<String>();
		Collection<String> c2 = new ArrayList<String>();
		Collection<String> c3 = new ArrayList<String>();
		
		c1.add("abc1");
		c1.add("abc2");
		c1.add("abc3");
		c1.add("abc6");
		
		c2.add("abc1");
		c2.add("abc2");
		c2.add("abc4");
		
		c3.add("abc1");
		c3.add("abc2");
		c3.add("abc3");
		
		
		System.out.println("c1c2:"+c1.containsAll(c2));
		System.out.println("c1c3:"+c1.containsAll(c3));
		
	}

}

包含所有
在这里插入图片描述

  • public boolean retainAll(Collection c) 取交集,问题:boolean的真实含义是什么?:
public class CollectionDemo {
	
	public static void main(String[] args) {
		
		Collection<String> c1 = new ArrayList<String>();
		Collection<String> c2 = new ArrayList<String>();
		Collection<String> c3 = new ArrayList<String>();
		
		c1.add("abc1");
		c1.add("abc2");
		c1.add("abc3");
		c1.add("abc6");
		
		c2.add("abc1");
		c2.add("abc2");
		c2.add("abc4");
		
		
		System.out.println("c1c2:"+c1.retainAll(c2));
		System.out.println(c1);

	}

}

取c1和c2的交集,并赋给c1,若c1改变则为true,否则为false
在这里插入图片描述

迭代器Iterator

  • Iterator iterator():Collection集合的专有遍历方式

  • iterator()的返回值是接口:需要返回的是该接口的子实现类对象!

  • boolean hasNext():判断当前迭代器中是否有下一个可以遍历元素,如果存在,则返回true;

  • Iterator:存在一个方法,Object next():获取下一个元素

  • 使用迭代器遍历集合

public class Demo1 {
	public static void main(String[] args) {
		
		List<Student> list = new ArrayList<Student>();
		list.add(new Student("奥利给",18));
		list.add(new Student("giao",19));
		list.add(new Student("画画的贝贝",28));
		list.add(new Student("你说嘿我说嘿嘿",21));

		Iterator<Student> it = list.iterator();
		//判断是否存在下一个元素
		while(it.hasNext()) {
			//it.next,获取下一个元素
			//注意,next方法不能使用多次,使用一次即可,
			//能使用for循环,不推荐(因为以后集合中元素可能不知道个数,使用while循环)
			System.out.println(it.next());
		}

List集合

特点:有序、有下标、元素可以重复
方法

  • 除了上面Collection的方法外,还有一些
//在index位置插入对象o
void add(int index,Object o)
//将一个集合中的元素添加到此集合中的index韦志中
boolean addAll(int index,Collection c)
//返回集合中指定位置的元素
Object get(int index)
//返回fromIndex和toIndex之间的集合元素(范围是[fromIndex,toIndex-1)
List subList(int fromIndex,int toIndex)

ListIterator:列表迭代器

  • ListIterator listIterator()这个方法底层实现:是通过ArrayList里面的成员内部类
  • 正向遍历
    boolean hasNext():判断是否有下一个元素
    Object next() :获取下一个元素
  • 逆向遍历
    boolean hasPrevious():判断是否有上一个元素
    Object previous():获取前一个元素
//示例
ListIterator<String> lit = list.listIterator() ;
	
		while(lit.hasNext()) {
			String s = lit.next() ;
			System.out.println(s+"---"+s.length());
		}

List集合的遍历方式

  • Collection集合的方法 Object[] toArray
  • Collection集合的迭代器Iterator iterator()
  • size()+Object get(int index):普通for循环
  • 列表迭代器:ListIteraotr listiterator()

List接口的三个经典实现

  • 1.ArrayList
  • 底层数据结构是数组,查询快,增删慢,线程不安全,效率高,JDK1.2版本
  • ArrayList里面可以存放null值,元素可以重复(可以有多个null值),可以存储重复元素,存储和取出一致(有序的)!
  • ArrayList:单线程程序中考虑执行效率,优先采用!
  • 其父类叫做AbstractList
  • 应用场景:网络聊天室 查看在线好友列表
List list1 = new ArrayList();
  • 2.Vector
  • 数组结构实现,查询快,增删慢,运行效率慢,线程安全,JDK1.0版本(这个集合几乎已经淘汰)
  • 线程安全的---->同步的---->执行效率低!
  • 特有功能:
    public void add(int index, E element):插入元素
    public Enumeration elements() — 相当于:Iterator iterator()
    该接口有两个方法
    boolean hasMoreElements():判断是否有下一个元素-----> 相当于:boolean hasNext()
    Object nextElement():获取一个元素 -----> 相当于:next()
    public Object elementAt(int index):通过角标获取指定的元素---->相当于:Object get(int index)
    elementAt()+size() :vector的普通for遍历方式
  • 场景:IO流:合并流 SequenceInputStream 可以将多个文件内容读出来复制到指定文件中!
List list2 = new Vector();
  • 3.LinkedList
  • 链表结构实现,增删快,查询慢,线程不安全,效率高
  • 线程不安全的—不同的---->执行效率高!
  • 应用场景:网站中 记录用户浏览过商品足迹 (Web技术:Cookie/Session)
  • 特有功能
    添加
    public void addFirst(Object e):将该元素添加到列表的开头!
    public void addLast(Object e):将该元素添加到列表的末尾!
    删除
    public Object removeFirst():删除列表第一个
    public Object removeLast():删除列表最后一个
    获取
    public Object getFirst():获取第一个
    public Object getLast() :获取最后一个
List list3 = new LinkedList();

方法

//	LinkedList的getFirst()方法是从Deque双向链表中实现的方法
//List对象中并不包含该方法,所以单纯的List对象不能调用getFirst()方法
public E getFirst() 
//与此类似的
public E getLast() 
//peek()"偷瞄"了一下第一个元素,只是看了一下,不对其进行操作
public E peek()
//pop()"偷瞄"之后还带走了第一个元素
public E pop() 

在集合中插入元素

对ArrayList而言(数组结构)
在这里插入图片描述
对于LinkedList而言(链表结构)

在这里插入图片描述

  • 根据上面两图,可以得出,如果数据较多且需要频繁的在集合中间插入元素,优先选择LinkedList
  • 如果只是在集合的尾部做元素的追加,优先选择ArrayList
  • 必须连续开辟空间,查询快,增删慢
  • 无需连续开辟空间,查询慢,增删快

Set集合

特点:无序,无下标,元素不可重复(存储和取出不一致,取决于底层HashMap实例)
方法:全部继承自Collection中的方法
Set的实现类

  • 1.HashSet
  • 底层hash表结构 来保证元素的唯一性!
  • 基于HashCode实现元素不重复
  • 存储自定义对象,必须重写hashcode()和equals()
  • 当存入元素的哈希码相同时,会调用==或equals进行确认,结果为true,拒绝后者存入
Set set1 = new HashSet();
  • 2.LinkedHashSet
  • 链表实现的HashSet,按照链表进行存储,即可保留元素的插入顺序
Set set2 = new LinkedHashSet();
  • 3.TreeSet
  • 本质基于TreeMap的底层实现(红黑树结构---->自平衡"的二叉树结构")
  • 基于排序顺序实现元素不重复
  • 实现了SortedSet接口,对集合元素自动排序
  • 元素对象的类型必须实现Comparable接口,指定排序规则
  • 通过CompareTo方法确定是否为重复元素
  • 有两种排序方式:取决于创建当前Set集合对象的时候的构造方法
    public TreeSet():默认的自然顺序排序(无参构造方法:自然排序)
    public TreeSet(Comparator<? super E> comparator)TreeSet集合有参构造方法(比较器排序)
Set set3 = new TreeSet();

比较器排序

  • 方式1:直接给了创建了接口子实现类MyComparator
    TreeSet ts = new TreeSet(new MyComparator())
  • 方式2:形参参数如果接口:传入接口的匿名内部类(本质:接口的子实现类)
    匿名内部类(推荐的方式)
    示例
TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {

			@Override
			public int compare(Student s1, Student s2) {
				//主要条件: 学生年龄的从大到小排序
				//s1---->this
				//s2---->s
				int num = s2.getAge() - s1.getAge() ;
				
				//学生年龄相同,比较姓名是否一样
				int num2 = (num==0) ? (s1.getName().compareTo(s2.getName())):  num ;
				return num2; 
			}
			
		}) ;

附加题

利用集合List和Set来实现对0-9十个数字的随机排序

public class Random {
	public static void main(String[] args) {
		//创建list集合
		List<Integer> list = new ArrayList<Integer>();
		//创建set集合
		Set<Integer> set = new HashSet<Integer>();
		//当set集合中的元素个数小于10的时候,执行此循环
		while(set.size()<10) {
			//使用Math的random方法创建随机数
			//随机数的范围为0-9
			int num = (int)(Math.random()*10);
			//如果set集合追加成功(追加的元素不重复)
			if(set.add(num)) {
				//把该元素追加给list集合
				list.add(num);
			}
		}
		//打印list集合,这样就实现了随机排序
		System.out.println(list);
	}
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值