欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

第十章:集合

程序员文章站 2022-05-03 08:07:06
...
  • 容器 : 存储对象的方式(数组,集合)

  • 一 数组的特点

  • 1.数组一旦创建成功,长度不可变。

  • 2.声明数组的类型就决定了数组元素的类型

  • 二 数组的弊短

  • 1.长度不可变(不能自动进行扩容)

  • 2.数组的API和属性比较少。没有添加,删除,插入等操作。(缺少元素个数的属性/方法。)

  • 3.数组只能用来存放有序的可重复的数据。对于无序的不可重复的无能为力。

  • 三 Collection

  • List : 有序的且可重复

  • Set : 无序的且不可重复

  • 增强for循环

  • 作用 : 只能用来遍历集合和数组的元素

  • 格式 :

  •   for(元素的类型   临时变量 : 集合、数组的对象){
    
  •   }
    
  • interator() : 调用这个方法会返回一个Iterator接口的实现类的对像

  • Iterator接口 : 遍历集合中的元素

  • Collection :

  •  |---List : 有序的且可重复的
    
  •  |---Set : 无序的且不可重复
    

在当前集合的index位置添加ele元素
void add(int index, Object ele)
在当前集合的index位置插入eles中所有的元素
boolean addAll(int index, Collection eles)
获取当前集合index位置上的元素
Object get(int index)
obj在当前集合的索引 - 从前向后找
int indexOf(Object obj)
obj在当前集合的索引 - 从后向前
int lastIndexOf(Object obj)
将当前集合index位置上的元素删除掉,并返回
Object remove(int index)
将当前集合index位置上的元素改成ele
Object set(int index, Object ele)
截取当前集合fromIndex到toIndex的元素组成新的集合.左闭右开
List subList(int fromIndex, int toIndex)

  • |—List:

  •  |--- ArrayList : 是List的主要实现类 	
    
  •  |--- Vector : 不用了
    
  •  |--- LinkedList : 底层是链表
    
  • [面试题] List的主要实现类有哪些?有什么不同?
    ArrayList : List的主要实现类,底层是数组,线程不安全,查找快,增删慢(数组的特点)。
    Vector : 古老的实现类,底层是数组,线程安全的
    LinkedList : 底层是使用双向链表。增删快,查找慢。

  • [面试题]ArrayList的底层实现原理?
    通过ArrayList空参的构造器创建对象。底层会创建一个长度为10的数组。
    当我们向数组中添加第11个元素时

  • 底层会进行扩容,扩容为原来的1.5倍(创建一个新的数组长度为原来的1.5倍并将原数组中的内容添加到新的数组中)。

  • Collection子接口之Set

  • Set : 无序的不可重复的

  • |----Set :

  •  |---- HashSet: 是Set的主要实现类
    
  •  	|--- LinkedHashSet :继承了HashSet。底层实现原理和HashSet一样。可以安照元素添加的顺序进行遍历。它维护了一张链表该链表记录了元素添加的顺序。
    
  •  |---- TreeSet :
    
  • 无序性:不是指的随机性,通过hashCode方法算出来的值来决定,数据在数组中存放的位置

  • 不可重复:进行euqals方法的比较。如果结果是true则认为两个数据相同,如果是false则认为两个数据不相同

  • [面试题]HashSet的底层实现原理?

  • 当我们向HashSet中添加一个数据时。会先调用该数据的hashCode方法来决定该数据在数组中所存放的位置。

  • 如果该位置上没有其它元素,则将该数据直接存放即可。如果该位置上已经有了其它的元素,调用该元素所在类的equals方法

  • 进行比较。如果返回值是个true则认为两个数据相同则不能存放。如果返回值是个false则以链表的形式将该数据存在该位置上。

  • (jdk1.8)如果数量达到8则将链表换成红黑树。

  • TreeSet

  • 1.底层就是一个红黑树

  • 2.可以对元素进行排序

  • 3.TreeSet中的元素的类型必须保持一致

  • 两种排序方式

  • 一 自然排序

  • 1.自定义类需要实现Comparable接口

  • 2.需要重写compareTo方法

  • 3.安照某个属性进行排序

  • 4.向集合中添加元素

  • 二 定制排序

  • 1.创建一个Compartor实现类的对象,并传入到TreeSet的构造器中

  • 2.重写compare方法

  • 3.安照某个属性进行排序

  • 4.向集合中添加元素

  • 思考:

  •       1.如果即有自然排序又有定制排序那么谁起作用? 定制排序
    
  •        2.自然排序和定制排序哪个更好一些?定制排序更灵活一些
    
  • LinkedHashSet: 继承了HashSet。底层实现原理和HashSet一样。

  •  可以安照元素添加的顺序进行遍历。它维护了一张链表该链表记录了元素添加的顺序。
    
  • 自然排序

  • 1.自定义类需要实现Comparable接口

  • 2.需要重写compareTo方法

  • 3.安照某个属性进行排序

  • 4.向集合中添加元素

 public class SetTest {
	@Test
	public void test4(){
		//向构造器中传入一个Compartor实现类的对象
		TreeSet set = new TreeSet(new Comparator() {
			@Override
			public int compare(Object o1, Object o2) {
				if(o1 instanceof Animal && o2 instanceof Animal){
					Animal a = (Animal) o1;
					Animal a2 = (Animal) o2;
					//排序
					return a.age - a2.age;
				}	
				return 0;
			}
		});
		set.add(new Animal("aaa",18));
		set.add(new Animal("bbb",8));
		set.add(new Animal("fff",38));
		set.add(new Animal("ccc",28));	
		System.out.println(set);
	}
	@Test
	public void test3(){	
		TreeSet set = new TreeSet();
//		set.add(12);
//		set.add(5);
//		set.add(123);
//		set.add(6);
//		set.add(9);		
//		set.add("aaa");
//		set.add("fff");
//		set.add("ddd");
//		set.add("ccc");
		set.add(new Student("aaa",18));
		set.add(new Student("ccc",28));
		set.add(new Student("ddd",28));
		set.add(new Student("fff",28));
		set.add(new Student("kkk",28));
		set.add(new Student("lll",28));
		set.add(new Student("eee",38));	
		System.out.println(set);
	}
	/*
	 * LinkedHashSet: 继承了HashSet。底层实现原理和HashSet一样。
	 * 		可以安照元素添加的顺序进行遍历。它维护了一张链表该链表记录了元素添加的顺序。
	 * 		
	 */
	@Test
	public void test2(){
		Set set = new LinkedHashSet();
		set.add("aaa");
		set.add("bbb");
		set.add("ccc");
		set.add("ddd");
		set.add("aaa");
		System.out.println(set);
	}
	@Test
	public void test(){
		Set set = new HashSet();
		set.add("aaa");
		set.add("bbb");
		set.add("ccc");
		set.add("ddd");
		set.add("aaa");
		set.add(new Person("aaa",18));
		set.add(new Person("aaa",18));
		System.out.println(set);
	}
}
public class Animal {
	String name;
	int age;
	public Animal() {
		super();
	}
	public Animal(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
		return "(" + name + " " + age + ")";
	}
}
public class Person {
	String name;
	int age;
	public Person() {
		super();
	}
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	@Override
	public int hashCode() {
		System.out.println("------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) {
		System.out.println("---------equals----------");
//		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 false;
	}
	@Override
	public String toString() {
		return "(" + name + " " + age + ")";
	}
}
public class Student implements Comparable {
	String name;
	int age;
	public Student() {
		super();
	}
	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
		return "(" + name + " " + age + ")";
	}
	@Override
	public int compareTo(Object o) {		
		if(o instanceof Student){
			Student s = (Student) o;
			//安年纪排序
//			return -(this.age - s.age);
			//安名字排序
//			return this.name.compareTo(s.name);			
			//安年纪排序如果相同安名字排序			
			int a = this.age - s.age;
			//如果年纪相同
			if(a == 0){
				//比较名字
				return this.name.compareTo(s.name);
			}			
			return a;
		}	
		//0代表两个数据是相同的
		return 0;
	}
}

 public class ListTest {
	/*
	 *  void addFirst(Object obj)
		void addLast(Object obj)	
		Object getFirst()
		Object getLast()
		Object removeFirst()
		Object removeLast()
	 */
	@Test
	public void test2(){
		LinkedList list = new LinkedList();
		list.add("aaa");
		list.add("bbb");
		list.add("ccc");
		list.addFirst(111);
		list.addLast(222);
		System.out.println(list);
		System.out.println(list.getFirst());
		System.out.println(list.getLast());
		list.removeFirst();
		list.removeLast();
		System.out.println(list);
	}
	@Test
	public void test(){
		//底层创建一个长度为10的数组
		ArrayList list = new ArrayList();
		list.add("aaa");
		list.add("aaa");
		list.add("aaa");
		list.add("aaa");
		list.add("aaa");
		list.add("aaa");
		list.add("aaa");
		list.add("aaa");
		list.add("aaa");
		list.add("aaa");
		list.add("aaa");
		System.out.println(list);
	}
}

public class ListAPI {
	/*
	 * 面试题
	 */
	@Test
	public void test3(){
		List list2 = new ArrayList();
		list2.add(1); //自动装箱
		list2.add("aaa");
		/*
		 * 思考 : 删除的是1这个内容,还是索引值中的元素
		 */
//		list2.remove(1); //1是索引值
		list2.remove(new Integer(1)); //删除的是内容
		list2.rem
		System.out.println(list2);
	}
	@Test
	public void test2(){
		List list2 = new ArrayList();
		list2.add("aaa");
		list2.add("bbb");
		list2.add("ccc");
		list2.add("aaa");
//		Object remove = list2.remove(2);
//		System.out.println(remove);
//		list2.set(0, "AAA");	
		List subList = list2.subList(0, 2);
		System.out.println(subList);	
		System.out.println(list2);
	}
	@Test
	public void test(){	
		List list = new ArrayList();
		list.add(111);
		list.add(222);
		list.add(333);	
//		list.add(0, "aaa");
		List list2 = new ArrayList();
		list2.add("aaa");
		list2.add("bbb");
		list2.add("ccc");
		list2.add("aaa");		
//		list.addAll(0, list2);		
		System.out.println(list.get(0));		
		System.out.println(list);		
		System.out.println("-----------------");		
		System.out.println(list2.indexOf("aaa"));
		System.out.println(list2.lastIndexOf("aaa"));
	}
}

public class IteratorTest {
	@Test
	public void error(){
	
	}
	int sum = 0;
	int[] numbers = null;
	public void addObject(int obj){	
		numbers = new int[10];	
		numbers[sum++] = obj;
	}
	/*
	 * 常见错误 
	 */
	@Test
	public void test2(){
		Collection c = new ArrayList();
		c.add(123);
		c.add("aaa");
		c.add(222);
		c.add(333);
		/*
		Iterator iterator = c.iterator();
		while(iterator.next() != null){
			System.out.println(iterator.next());
		}
		*/
		/*
		 * c.iterator() : 因为每次都会创建一个新的对象。所以不行
		while(c.iterator().hasNext()){
			System.out.println(c.iterator().next());
		}
		*/
	}
	@Test
	public void test(){
		Collection c = new ArrayList();
		c.add(123);
		c.add("aaa");
		c.add(222);
		c.add(333);		
		//返回一个Iterator接口实现类的对象
		Iterator iterator = c.iterator();		
		//next() :  作用 : 1.指针下移  2.返回指针指向的元素
//		Object obj = iterator.next();
//		System.out.println(obj);	
//		System.out.println(iterator.next());
//		System.out.println(iterator.next());
//		System.out.println(iterator.next());	
//		for(int i = 0;i < 4; i++){
//			System.out.println(iterator.next());
//		}	
		//hasNext() : 如果还有下一个元素则返回true
		while(iterator.hasNext()){
			System.out.println(iterator.next());
		}
	}
}

public class ForEachTest {
/*
 * 演示(理解)
 */
@Test
public void test3(){
	String[] names = {"gg","jj","dd","mm"};	
	/*
	for (int i = 0; i < names.length; i++) {
		 System.out.println(names[i]);
		 //给数组的元素赋值
		 names[i] = "aa";
	}
	for (String string : names) {
		System.out.println(string);
	}
	*/	
	/*
	 * 下面的例子可以理解成下面的形式
	 * String name = names[i];
	 * name = "aa";
	 */
	for (String name : names) {
		System.out.println(name);
		//没有改变数组中的元素,因为改变的是临时变量的值
		name = "aa";
	}
	for (String string : names) {
		System.out.println(string);
	}
}
/*
 * 遍历数组的元素
 */
@Test
public void test2(){
	String[] names = {"aa","bb","cc","dd"};
	for(String name : names){
		System.out.println(name);
	}
}
/*
 * 遍历集合中的元素
 */
@Test
public void test(){
	Collection c = new ArrayList();
	c.add(123);
	c.add("aaa");
	c.add(222);
	c.add(333);
	for(Object obj : c){
		System.out.println(obj);
	}
}
}

public class CollectionTest {
/*
 * API第四波
 */
@Test
public void test4(){
	Collection c = new ArrayList();
	c.add(111);
	c.add(222);
	c.add("aaa");
	c.add("bbb");	
	Collection c2 = new ArrayList();
	c2.add(111);
	c2.add(222);
	c2.add("ccc");	
	/*
	 * retainAll(Collection coll)只保留当前集合和coll中交集(相同的元素)的元素。
	 */
	//c.retainAll(c2);		
	//System.out.println(c);	
	Collection c3 = new ArrayList();
	c3.add("aaa");
	c3.add("ddd");
	c3.add("ccc");		
	//将一个集合转化成一个数组
	Object[] array = c3.toArray();
	System.out.println(array[0]);
	System.out.println(array[1]);
	System.out.println(array[2]);		
}
/*
 * API第三波
 */
@Test
public void test3(){
	Collection c = new ArrayList();
	c.add(111);
	c.add(222);
	c.add("aaa");
	c.add("bbb");	
	//remove(Object obj)从当前集合中删除obj这个元素。删除失败返回false
	//c.remove(111);
	Collection c2 = new ArrayList();
	c2.add(111);
	c2.add(222);
	c2.add("ccc");
	//removeAll(Collection coll) 将当前集合和coll集合中交集(相同的元素)的元素从当前集合中删除掉。
	c.removeAll(c2);
	System.out.println(c);
}
/*
 * API第二波
 * 
 * 注意 : 凡是向Collection中添加的自定义类的对象,自定义类的对象都需要重写equals方法
 */
@Test
public void test2(){
	Collection c = new ArrayList();
	c.add(111);
	c.add(222);
	c.add("aaa");
	c.add("bbb");
	//c.add(new Person("abc",19));
	//contains(Object obj) : 当前集合是否包含obj这个元素
	boolean contains = c.contains("aaa");
	System.out.println(contains);
	/*
	 * 如果集合中的元素是自定义类的对象。那么查找对象的时候比较的是地址值。
	 * 如何比较属性呢?
	 * 重写equals()
	 */
	System.out.println(c.contains(new Person("abc",19)));
	System.out.println("--------------------------------------------");
	Collection c2 = new ArrayList();
	c2.add(111);
	c2.add(222);
	//containsAll(Collection coll) : 当前集合是否包含coll集合中所有的元素
	boolean containsAll = c.containsAll(c2);
	System.out.println(containsAll);
	System.out.println("--------------------------------");
	Collection c3 = new ArrayList();
	c3.add(111);
	c3.add(222);
	c3.add(222);	
	//equals(Object obj) 比较两个集合中的元素是否相等。(类型,个数,内容)
	System.out.println(c2.equals(c3));	
	System.out.println("-----------------------------");
	System.out.println(c3.hashCode());
	System.out.println(c2.hashCode());	
}
/*
 * API第一波
 */
@Test
public void test(){		
	//多态 : 接口和类之间的多态性,接口的类型 = 接口的实现类的对象,接口可以看成父类,接口的实现类可以看成子类
	Collection c = new ArrayList();		
	//add(Object obj) : 向集合中添加一个元素
	c.add(123); //自动装箱
	c.add("aaaa");
	c.add("aaaa");
	c.add(new Person("范冰冰",18));	//重写了Person类的toString方法,输出内容,如果没有重写Person类的toString则输出地址值	
	Collection c2 = new ArrayList();
	c2.add(111);
	c2.add(222);		
	//addAll(Collection coll) : 将coll集合中的每一个元素分别添加到当前的集合中
	c.addAll(c2);		
	//isEmpty() : 如果该集合没有元素则返回true
	System.out.println(c.isEmpty());
	System.out.println("--------clear后---------------");
	//clear() : 移除集合中的所有的元素
	c.clear();	
	System.out.println(c.isEmpty());
	System.out.println(c);
	//size()集合中元素的个数
	System.out.println(c.size());
}	
}
package com.atguigu.java;
public class Person {
String name;
int age;
public Person() {
	super();
}
public Person(String name, int age) {
	super();
	this.name = name;
	this.age = age;
}
@Override
public boolean equals(Object obj) {
//		System.out.println("-----equals-------------");
	if(this == obj){
		return true;
	}
	if(obj instanceof Person){
		Person p = (Person) obj;
		return p.name.equals(this.name) && p.age == this.age;
	}
	return false;
}
@Override
public String toString() {	
	return "(" + name + " " + age + ")";
}
}

相关标签: 集合