Java-day11(集合)

集合

1.集合框架

用于存储数量不等的多个对象,还可用于保存具有映射关系的关联数组

  • Java集合可分为CollectionMap两种体系
    Java-day11(集合)_第1张图片

    Collection接口
    Set:元素无序,不可重复的集合----(类似数学中的集合)
    List:元素有序,可重复的集合----("动态"数组)
    Map接口:具有映射关系----(类似数学中的函数)

  • 数组存储对象的缺点:创建后,长度不可变;数组存放的对象的个数不可知

2.Collection接口API

常见的接口API

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;          
import java.util.Iterator;

import org.junit.Test;

public class Test8{
	@Test
	public void testCollection(){
		Collection coll = new ArrayList();   
		//1.size():返回集合中元素的个数
		System.out.println(coll.size());//0
		//2.add(Object obj):向集合中添加一个元素
		coll.add(123);
		coll.add("ABC");
		coll.add(new Object());
		coll.add(true);
		System.out.println(coll.size());//4
		//3.addAll(Collection coll):将形参coll中包含的所有元素添加到当前集合中
		Collection coll1 = Arrays.asList(1,2,3);//添加3个元素到coll1中,coll1长度不可变,且不支持add()、remove()、clear()等方法
		coll.addAll(coll1);
		System.out.println(coll.size());//7
		//查看集合元素
		System.out.println(coll);
		//4.判断集合是否为空
		System.out.println(coll.isEmpty());//false
		//5.clear():清空集合元素
		coll.clear();
		System.out.println(coll.isEmpty());//true
	}

	@Test
	public void testCollection1(){
		Collection coll = new ArrayList();
		coll.add(123);
		coll.add("ABC");
		coll.add(new Object());
		coll.add(true);
		//6.contains(Object obj):判断集合中是否包含指定的obj元素,包含,返回true,不包含,返回false
		//判断的依据:根据元素所在类的equals()方法来判断
		//注意:如果存入集合中的元素是自定义类的对象,要求:自定义类要重写equals()方法
		boolean b1 = coll.contains("ABC");
		System.out.println(b1);//true
		//7.containsAll(Collection coll):判断当前集合中是否包含coll中所有的元素
		Collection coll1 = new ArrayList();
		coll1.add(123);
		coll1.add("ABC");
		boolean b2 = coll.containsAll(coll1);
		System.out.println(b2);//true
		//8.retainAll(Collection coll):求当前集合与coll共有的元素,并返回给当前集合
		coll.retainAll(coll1);
		System.out.println(coll);//[123, ABC]
		//9.remove():删除集合中的obj元素,删除成功,返回true,反之,返回false
		boolean b3 = coll.remove(123);
		System.out.println(b3);
		//10.removeAll(Collection coll):从当前集合中删除包含在coll中的元素
		Collection coll2 = new ArrayList();
		coll2.add("ABC");
		coll2.add("ACE");
		coll.removeAll(coll2);
		System.out.println(coll);//空(上一步后coll只剩ABC元素)

	}
	@Test
	public void testCollection2(){
		Collection coll = new ArrayList();
		coll.add(123);
		coll.add("ABC");
		coll.add(new Object());
		coll.add(true);

		Collection coll1 = new ArrayList();
		coll.add(123);
		coll.add("ABC");
		//11.equals(Collection coll):判断集合中的元素是否完全一样
		//System.out.println(coll.equals(coll1));//false
		//12.hashCode():算出集合哈希值
		//System.out.println(coll.hashCode());
		//13.toArray():将集合转化成数组
		Object[] obj = coll.toArray();
		for(int i = 0;i < obj.length;i++){
			System.out.println(obj[i]);
		}
		//14.iterator():返回一个Iterator接口的实现类,进而实现集合的遍历
		Iterator iterator = coll.iterator();
		System.out.println("开始打印集合元素");
		while(iterator.hasNext()){
			System.out.println(iterator.next());
		}
	}	
}

3.lterator迭代器接口

集合的遍历

方法一:使用lterator迭代器接口实现集合的遍历

正确写法:

public void testCollection2(){
		Collection coll = new ArrayList();   
		coll.add(123);
		coll.add("ABC");
		coll.add(new Object());
		coll.add(true);
Iterator iterator = coll.iterator();
		while(iterator.hasNext()){
			System.out.println(iterator.next());
		}
}

错误写法:

public void testCollection2(){
		Collection coll = new ArrayList();    
		coll.add(123);
		coll.add("ABC");
		coll.add(new Object());
		coll.add(true);
Iterator iterator = coll.iterator();
		while(iterator.Next()= null){
			System.out.println(iterator.next());
		}
		for(Object i:coll){
			System.out.println(i);
		}
}

方法二:通过增强for循环实现集合的遍历

public void testCollection2(){
		Collection coll = new ArrayList(); 
		coll.add(123);
		coll.add("ABC");
		coll.add(new Object());
		coll.add(true);

		for(Object i:coll){
			System.out.println(i);
		}
}

通过增强for循环实现数组的遍历

public void tesFor(){
		String[] str = new String[]{"AA","SS","123"};
		for(String s:str){
			System.out.println(s);      
		}
}

4.Collection子接口:Set接口(存储元素无序,不可重复的集合)

  • 添加进Set中的元素所在的类,一定要 重写equals()和hashCode() 方法

  • 无序性:无序性 != 随机性(无序性是指元素在底层存放位置的无序)

  • 不可重复性:当向Set中添加相同的元素的时候,后面的元素不能添加进去

  • 向Set中添加对象时,首先调用对象所在类的hashCode()方法,计算此对象的哈希值,哈希值决定对象存储位置。若对象要存储的位置没对象,就直接存储进去;若对象要存储的位置有对象,再通过equals()比较这两个对象是否相同(相同则后一个对象无法添加进来,反之则都存储)。

注:hashCode()方法与equals()方法需一致

HashSet(主要实现类)

例:

import java.util.HashSet;
import java.util.Set;

import org.junit.Test;

public class Test{
	@Test
	public void testHashSet(){
		Set set = new HashSet();
		set.add(123);
		set.add(456);
		set.add(new String("AA"));   
		set.add("AA");
		set.add(null);
		System.out.println(set.size());
		System.out.println(set);

	}
	
}

LinkedHashSet

使用链表维护了添加进集合的顺序,当我们遍历此集合时,是按照添加的先后顺序进行遍历。

  • LinkedHashSet插入性能低于HashSet,但在迭代访问却有很好的优势
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.Iterator;

import org.junit.Test;

public class Test11{
	@Test
	public void testHashSet(){
		Set set = new LinkedHashSet();
		set.add(123);
		set.add(456);
		set.add(new String("AA"));   
		set.add("AA");
		set.add(null);//LinkedHashSet可以有null
		//遍历集合
		Iterator iterator = set.iterator();
		while(iterator.hasNext()){
			System.out.println(iterator.next());
		}

	}
	
}

TreeSet

  • 向TreeSet中添加的元素必须是同一类

  • 可以按照添加进集合中的元素的指定的顺序遍历。如String,包装类等按照从小到大的顺序遍历

  • 当自定义类没有实现Comparable接口时,当向TreeSet中添加自定义类对象时,会报ClassCastException的异常

  • TreeSet中添加自定义类对象时有两种排序方式:自然排序和定制排序

    自然排序:要求自定义类实现java.lang.Comparable接口并重写其compareTo(Object obj)方法

    • compareTo()与hashCode()方法及equals()方法三者保持一致

    • 在此方法中,指明按照自定义类的哪个属性排序

    • 向TreeSet中添加元素时,首先按照compareTo()进行比较,一但返回0,虽然两个对象的比较的属性值相同,但是程序会认为这两个对象是相同的,进而使后一个对象无法添加进来

    定制排序

    • compare()与hashCode()方法及equals()方法三者保持一致
    • 详细案例见附件

5.Collection子接口:List接口(存储元素有序,可重复的集合)

添加进List中的元素所在的类,一定要 重写equals() 方法

ArrayList(主要的实现类)

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

public class Test10{
	@Test
	//List常用的方法:增(add(Object obj)),删(remove(int index))改(set(int index,Object obj))查(get(int index))插(add(int index,Object obj))长度(size())
	//List相对于Collection的新增方法
	public void test1(){
		List list = new ArrayList();
		list.add(123);
		list.add(456);
		list.add(789);
		list.add(new String("ACA"));
		list.add(new String("ACE"));            
		System.out.println(list);//[123, 456, 789, ACA, ACE] 
		
		//1.void add(int index,Object obj):在指定的索引位置添加元素
		list.add(0,"SSS");
		System.out.println(list);//[SSS, 123, 456, 789, ACA, ACE] 
		//2.Object get(int index):获取指定位置的元素
		Object obj = list.get(3);
		System.out.println(obj);//789
		//3.boolean addAll(int index,Collection coll):判断向该集合中的指定位置加入集合coll;成功true,失败false;
		List list1 = new ArrayList();
		list1.add(1263);
		list1.add(4566);
		boolean b1 = list.addAll(1,list1);
		System.out.println(b1);//true 
		System.out.println(list);//[SSS, 1263, 4566, 123, 456, 789, ACA, ACE] 
		//4.Object remove(int index):删除指定索引位置的元素
		list.remove(0);
		System.out.println(list);//[1263, 4566, 123, 456, 789, ACA, ACE] 
		//5.Object set(int index,Object obj):设置指定索引位置的元素为obj
		list.set(0, 2222);
		System.out.println(list);//[2222, 4566, 123, 456, 789, ACA, ACE] 
		//6.int indexOf(Object obj):返回第一次出现的指定元素obj在集合中的索引位置,没有返回 -1
		int index = list.indexOf("ACE");
		System.out.println(index);//6 
		//7.int indexOf(Object obj, intstartIndex):返回最后一次出现的指定元素obj在集合中的索引位置,没有返回 -1
		System.out.println(list.lastIndexOf(123));//2 
		list.add(123);
		System.out.println(list.lastIndexOf(123));//7 
		//8.List subList(int fromIdex,int toIndex):返回从fromIdex索引到 toIndex索引位置的集合元素{索引值不能为负,范围左闭右开(fromIdex,toIndex]}
		List a1 = list.subList(2 ,8);
		System.out.println(a1);//[123, 456, 789, ACA, ACE, 123] 
	}
}

LinkedList(对于频繁的插入,删除操作,则建议使用)

Vector(古老的实现类,线程安全,效率低于ArrayList)

练习
Java-day11(集合)_第2张图片
参考答案:略

6.Map接口(存储“键-值”对的数据)

  • 用于保存具有映射关系的数据:Key-Value
  • Map中的key和value都可以是任何引用类型的数据
  • Map中的key用Set来存放,不允许重复(value(用Collection存放)可以重复),所有的Entry(Key-Value对)是用Set存放,不可重复。同一个Map对象所对应的类,须重写hashCode()和equals()方法
  • 常用String类作为Map的"键"
  • Key和Value之间存在单向一对一的关系,即通过指定的key都能找到唯一,确定的value

Java-day11(集合)_第3张图片
虚线实现,实线继承

HashMap(主要实现类)

向HashMap中添加元素时,会调用Key所在类的equals()方法,判断两个Key是否相同,若相同,新老交替(老的Entry被新的Entry覆盖)

Map的主要方法
public class TestMap{
@Test
	public void test1(){
		Map map = new HashMap();          
		
		//1.Object put(Object key,Object value):向Map中添加元素(即Entry:一对完整的键-值对)
		map.put("AA", 223);
		map.put("BB", 223);
		map.put("AA", 227);
		map.put(123, "cc");
		map.put(null, null);
		map.put(new Customer("OO", 33), 99);
		map.put(new Customer("OO", 33), 99);
		
		//2. int size():返回集合长度
		System.out.println(map.size());//5(Key不可重复)
		System.out.println(map);//{AA=227, BB=223, null=null, Customer [name= OO, id=33]=99, 123=cc}
		
		//3.Object remove(Object key):按照指定的Key,删除对应的Entry
		map.remove(123);
		System.out.println(map);//{AA=227, BB=223, null=null, Customer [name= OO, id=33]=99}
		
		//4.void putAll(Map t):将新的Map(t)添加进本map
		Map map1 = new HashMap();
		map1.put(111, 223);
		map1.put(222, 223);
		map.putAll(map1);
		System.out.println(map);//{AA=227, BB=223, null=null, Customer [name= OO, id=33]=99, 222=223, 111=223}
		
		//5.clear():清空
		System.out.println(map1);//{222=223, 111=223}
		map1.clear();
		System.out.println(map1);//{}

		//6.Object get(Object key):获取指定Key的Value值,若无此Key,就返回null
		System.out.println(map.get(999));//null

		//7.boolean containsKey(Object key):
		boolean b1 = map.containsKey("AA");
		System.out.println(b1);//ture

		//8.boolean containsValue((Object Value):判断此集合中是否有值为Value的Entry,有返回ture,没有返回false;
		boolean b2 = map.containsValue(227);//此时map中有一个值为227的Entry
		System.out.println(b2);//ture
		map.remove("AA", 227);
		boolean b3 = map.containsValue(227);//此时map中没有值为227的Entry
		System.out.println(b3);//false

		//9.boolean isEmpty():判断集合是否为空
		boolean b4 = map.isEmpty();
		System.out.println(b4);//false

		//10.boolean equals(Object obj):判断此集合是否完全等于集合obj(即判断本集合是否与obj集合是否一样)
		map1.put("aa", 234);
		map1.put("AA", 234);
		boolean b5 = map.equals(map1);
		System.out.println(b4);//false
	}
}
Map的遍历
public class TestMap{
@Test
	public void test2(){
		Map map = new HashMap();       
		map.put("AA", 223);
		map.put("BB", 223);
		map.put(123, "cc");
		map.put(null, null);
		map.put(new Customer("OO", 33), 99);

		//1.Set KeySet():遍历Key集
		Set set = map.keySet();
		for(Object obj : set){
			System.out.println(obj);
		}
		//AA BB null Customer [name= OO, id=33] 123

		//2.Collection values():遍历Value集
		Collection coll = map.values();
		Iterator i = coll.iterator();
		while(i.hasNext()){
			System.out.println(i.next());
		}
		//223 223 null 99 cc

		//3.Set entrySet():遍历Key-Value集
		Set entry = map.entrySet();
		for(Object obj : entry){
			//直接打印
			System.out.println(obj);
			//转变类型通过get方法遍历
			Map.Entry entrily = (Map.Entry)obj;
			System.out.println(entrily.getKey() + "=====>" + entrily.getValue());

		}
		//AA=223 BB=223 null=null Customer [name= OO, id=33]=99 123=cc

		//4.通过遍历Key集进而遍历Value集
		Set set1 = map.keySet();
		for(Object obj : set1){
			System.out.println(obj + "=====" + map.get(obj));
		}
		//AA=====223 BB=====223 null=====null Customer [name= OO, id=33]=====99 123=====cc
	}
}

LinkedHashMap

使用链表维护添加进Map中的顺序,遍历时,按照添加的顺序遍历

public class TestMap{
@Test
	public void test3(){
		Map map = new LinkedHashMap();
		map.put("AA", 223);
		map.put("BB", 223);
		map.put(123, "cc");
		map.put(null, null);           
		map.put(new Customer("OO", 33), 99);

		Set entry = map.entrySet();
		for(Object obj : entry){
			System.out.println(obj);
		}
	}
}

TreeMap

  • 按照添加进Map中的元素的Key的指定属性进行排序,要求:key必须是同一类的对象

  • 针对Key有自然排序与定制排序

  • 自然排序(需重写compareTo方法)
    例:

 public class Customer implements Comparable{               
	private Integer id;
	private String name;

	public Integer getId(){
		return id;
	} 
	public void setId(Integer id){
		this.id = id;
	}
	public void setName(String name){
		this.name = name;
	}
	public String getName(){
		return name;
	}
	public Customer(String name,Integer id){
		super();
		this.name = name;
		this.id = id;
	}
	public Customer(){
		super();
	}
	@Override
	public String toString(){
		return "Customer [name= " + name + ", id=" + id + "]";
	}
	@Override
	public int hashCode(){
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		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;
		Customer other = (Customer)obj;
		if(id == null){
			if(other.id != null)
				return false;
		}else if(!id.equals(other.id))
			return false;
		if(name == null){
			if(other.name != null)
				return false;
		}else if(!name.equals(other.name))
			return false;
		return true;
	}
	@Override
	public int compareTo(Object o){//先按ID,后按名字排序
		if(o instanceof Customer){
			Customer c = (Customer)o;
			int i = this.id.compareTo(c.id);
			if(i == 0){
				return this.name.compareTo(c.name);
			}else{
				return i;
			}
		}
		return 0;
	}
}
javapublic void test1(){
	@Test
	public void test4(){
		Map map = new TreeMap();
		map.put(new Customer("AA", 33), 99);
		map.put(new Customer("BB", 39), 95);
		map.put(new Customer("OO", 133), 69);

		Set entry = map.entrySet();
		for(Object obj : entry){            
			System.out.println(obj);
		}
	}
}
  • 定制排序
    例:
public void test2(){
	@Test
	public void test5(){
		Comparator com = new Comparator(){
			public int compare(Object o1,Object o2){               
				if(o1 instanceof Customer && o2 instanceof Customer){
					Customer c1 = (Customer)o1;
					Customer c2 = (Customer)o2;
					int i = c1.getId().compareTo(c2.getId());
					if(i == 0){
						return c1.getName().compareTo(c2.getName());
					}
					return i;

				}
				return 0;
			}
		};
		TreeMap map = new TreeMap(com);
		map.put(new Customer("BB", 1001), 89);
		map.put(new Customer("CB", 1001), 89);
		map.put(new Customer("BB", 1011), 89);
		map.put(new Customer("BB", 10101), 89);

		Set entry = map.entrySet();
		for(Object obj : entry){
			System.out.println(obj);
		}
	}
}

Hashtable(子类:Properties)

  • 线程安全

  • 不允许使用null作为Key和Value

  • 不保证其中Key-Value对的顺序

  • 判断两个Key相同,两个value相同的标准与hashMap(通过hashCode()方法及equals()方法)一致

  • Properties常用来处理属性文件,键值都为String类型

例:

public void test2(){
	@Test
	public void test6() throws FileNotFoundException,IOException{           
		Properties pros = new Properties();
		/*手动创建jdbc.sql文件
		 * user=root
		 * password=123ch
		 */
		//读取文件jdbc.sql
		pros.load(new FileInputStream(new File("jdbc.sql")));
		String user = pros.getProperty("user");
		System.out.println(user);//root
		String password = pros.getProperty("password");
		System.out.println(user);//123ch
	}
}

7.Collections工具类

  • 用于操作Collection及Map的工具类
 import java.util.ArrayList;
import java.util.Collection;       
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.junit.Test;

public class Test18{
	@Test
	//排序操作:均为static方法
	public void test1(){
		List list = new ArrayList();
		list.add(123);
		list.add(345);
		list.add(567);
		list.add(789);
		list.add(999);
		System.out.println(list);//[123, 345, 567, 789, 999]     
		
		//1.reverse(List):反转List中元素的顺序
		Collections.reverse(list);
		System.out.println(list);//[999, 789, 567, 345, 123]

		//2.shuffle(List):对List集合元素进行随机排序
		Collections.shuffle(list);
		System.out.println(list);//[567, 789, 345, 123, 999]

		//3.sort(List)根据元素的自然顺序对指定List集合元素按升序排序
		Collections.sort(list);
		System.out.println(list);//[123, 345, 567, 789, 999]

		//4.sort(List,Comparator)根据指定的Comparator产生的顺序对List集合元素进行排序(可略过)
		ArrayList<Customer> list1= new ArrayList<>();
        list1.add(new Customer("rank",20));
        list1.add(new Customer("Jack",16));
        list1.add(new Customer("Tom",18));
		 Collections.sort(list1, new Comparator<Customer>() {
            @Override
            public int compare(Customer o1, Customer o2) {
                return o1.getId()-o2.getId();   //根据id进行升序排序
            }
        });
        System.out.println(list1);
		//5.将指定List集合的i处元素和j处元素进行交换
		Collections.swap(list, 0, 3);
		System.out.println(list);//[789, 345, 567, 123, 999]

	}
	@Test
	//查找,替换操作
	public void test2(){
		List list = new ArrayList();
		list.add(123);
		list.add(345);
		list.add(567);
		list.add(789);
		list.add(999);
		list.add(789);
		System.out.println(list);//[123, 345, 567, 789, 999]

		//1.Object max(Collecton):根据元素的自然顺序,返回集合中的最大元素
		System.out.println(Collections.max(list));//999

		//2.Object min(Collecton):根据元素的自然顺序,返回集合中最小元素
		System.out.println(Collections.min(list));//123

		//3.int min(Collecton,Object):返回指定集合中指定元素的出现次数
		int i = Collections.frequency(list, 789);
		System.out.println(i);//2

		//4.void copy(List desc,List src):将src中的元素复制到desc中(注:需要desc元素长度大于等于src元素长度,并且复制的元素会覆盖desc元素的src元素相应长度的位置,desc元素长度不变)
		List list1 = new ArrayList();
		list1.add("AAA");
		list1.add("BBB");
		Collections.copy(list, list1);
		System.out.println(list);//[AAA, BBB, 567, 789, 999, 789]

		//5.boolean replaceAll(List list,Object oldValue,Object newValue):使新值替换List中对应的旧值
		boolean b1 = Collections.replaceAll(list, 999, 111);
		System.out.println(b1);//true
		System.out.println(list);//[AAA, BBB, 567, 789, 111, 789]

		//同步控制
		//将指定集合包装线程同步的集合,进而解决多线程并发访问集合时的线程安全问题
		List list3 = Collections.synchronizedList(list);
		System.out.println(list3);
	}	
}

练习
Java-day11(集合)_第4张图片
参考答案:略

感谢大家的支持,关注,评论,点赞!
参考资料:
尚硅谷宋红康20天搞定Java基础中部

你可能感兴趣的:(Java,java,python,开发语言)