黑马程序员——Java基础——集合(一)

------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------


一、集合

为了方便多个对象的操作,我们需要把多个对象存储到一个容器中,数组除了存储基本数据类型也可以存储对象,但数组的长度是固定的,所以抽取了一个长度可变,只能存储对象且不同类型对象的容器,就是集合。对于集合容器,有很多种。因为每一个容器的自身特点不同,其实原理在于每个容器的内部数据结构不同。集合容器在不断向上抽取过程中就出现了集合体系,Collection就是集合体系的根接口,集合框架的构成及分类:


Collection接口中定义了集合框架的共性功能。

1.添加

boolean add(Object obj);

boolean addAll(Collection coll);

2.删除

boolean remove(Object obj);

boolean removeAll(Collection coll);

boolean isEmpty();判断集合中是否有元素

3.判断

boolean contains(Object obj);

boolean containsAll(Collection coll);

boolean isEmpty();判断集合中是否有元素。

4.获取

int size();

Iterator iterator();

取出元素的方式:迭代器,该对象必须依赖于具体容器,因为每一个容器的数据结构都不同,所以该迭代器对象是在容器中进行内部实现的,也就是iterator方法在每个容器中的实现方式是不同的。使用时只要通过容器获取到该实现的迭代器的对象即可,也就是iterator方法。

JDK1.5提供了高级for循环获取集合元素,但是不能对集合进行操作。

Iterator接口就是对所有的Collection容器进行元素取出的公共接口。

5.获取交集

boolean retainAll(Collection coll);取交集

6.集合变数组

Object toArray();

因为Collection是抽取出来的一个接口,所以想要使用共性方法必须建立子类对象。

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

public class CollectionDemo {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		//创建集合
		Collection col = new ArrayList();
		//添加元素
		col.add("java01");
		col.add("java02");
		col.add("java03");
		col.add("java04");
		
		//用迭代器获取集合中的元素
		Iterator it = col.iterator();
		while(it.hasNext())
		{
			System.out.println(it.next());
		}
		
		System.out.println("---------------");
		
		//删除元素
		col.remove("java02");
		
		//使用高级for循环获取集合中的元素
		for(Object obj : col)
		{
			System.out.println(obj);
		}
		//获取集合中的元素个数
		System.out.println("集合中的元素个数:"+col.size());
		
		//判断集合中是否包含指定元素
		System.out.println("集合中有没有java02的元素:"+col.contains("java02"));
		
		
	}

}

Collection
    |--List:存取的元素有序(存入和取出的顺序一致),元素都有索引(角标),允许重复元素
    |--Set:元素不能重复,无序

二、List

List是Collection接口的子接口,所以除了Collection接口的共性方法,还有自己的特有方法。因为有索引所以特有方法可以操作角标。

List:
  |--Vector:底层是数组数据结构,是同步的。增删,查询都很慢。
  |--ArrayList:底层是数组数据结构,是不同步的,替代了Vector。替代了Vector,查询的速度快。
  |--LinkedList:底层是链表数据结构,是不同步的。增删元素的速度很快。


List集合的特有方法:

1.添加

void add(index,element);在指定的索引位插入元素。

void addAll(index,collection);在指定的索引位插入一个集合的所有元素

2.删除

Object remove(index);删除指定索引位的元素,返回被删的元素。

3.修改

Object set(index,element);对指定索引位进行元素的修改。

4.获取:

Object get(index);通过索引获取指定元素。

int indexOf(object);获取指定元素第一次出现的索引位,如果该元素不存在返回-1;所以,通过-1,可以判断一个元素是否存在

int lastIndexOf(object);反向索引指定元素的位置。

List subList(from,to);获取子列表。

5.获取所有元素

ListIterator listIterator();List集合特有的迭代器,ListIterator是Iterator的子接口。 

在迭代时,不可以通过集合对象的方法操作集合中的元素。因为会发生ConcurrentModificationException异常。所以在迭代器时,只能用迭代器的方法操作元素。可是Iterator方法是有限的,只能对元素进行判断,取出,删除的操作。如果想要其他的操作,如添加、修改等,就需要使用其子接口ListIterrator。该接口只能通过List集合的ListIterator方法获取。

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

public class ListDemo {

	public static void main(String[] args) {
		
		//创建List集合对象
		List lists = new ArrayList();
		
		//添加元素
		lists.add("java01");
		lists.add("java02");
		lists.add("java03");
		lists.add("java04");
		
		//使用迭代器子接口ListIterator获取集合元素
		ListIterator it = lists.listIterator();
		
		while(it.hasNext())
		{
			System.out.println(it.next());
		}
		
		System.out.println("--------------");
		
		//在指定索引添加元素
		lists.add(2, "java05");
		//删除指定索引的元素并获取
		System.out.println("删除元素:"+lists.remove(3));
		//修改指定索引的元素
		System.out.println("修改元素:"+lists.set(0, "java000"));
		//获取指定索引的元素
		System.out.println("java04所在的索引是:"+lists.indexOf("java04"));
		//通过索引获取集合元素
		for(int x = 0 ; x < lists.size() ; x++)
		{
			System.out.println(lists.get(x));
		}
		
		//获取子列表
		
		System.out.println("子列表:"+lists.subList(0, 2));
		
	}

}

其中,LinkedList作为List的子类,也有其自身的特有方法

1.添加元素

void addFirst(element);将指定元素插入此列表的开头。

void addLast(element);将指定元素添加到此列表的结尾。

2.获取元素,但不删除元素。如果集合中没有元素,会出现NoSuchElementException

getFirst();返回此列表的第一个元素。

getLast();返回此列表的最后一个元素。

3.删除元素,同时获取元素。如果集合中没有元素,会出现NoSuchElementException

removeFirst();移除并返回此列表的第一个元素。

removeLast();移除并返回此列表的最后一个元素。

在JDK1.6出现了替代方法。

1.插入元素

boolean offerFirst();在此列表的开头插入指定的元素。

boolean offerLast(); 在此列表末尾插入指定的元素。

2.获取元素

peekFirst(); 获取但不移除此列表的第一个元素;如果此列表为空,则返回 null。

peekLast();获取但不移除此列表的最后一个元素;如果此列表为空,则返回 null。

3.删除元素

pollFirst();获取并移除此列表的第一个元素;如果此列表为空,则返回 null。

pollLast();获取并移除此列表的最后一个元素;如果此列表为空,则返回 null。

import java.util.LinkedList;

public class LinkedListDemo {

	public static void main(String[] args) {
		//创建LinkedList集合对象
		LinkedList list1 = new LinkedList();
		
		//将指定元素插入开头
		list1.addFirst("java01");
		list1.addFirst("java02");
		//将指定元素插入结尾
		list1.addLast("java03");
		list1.addLast("java04");
		//获取列表第一个元素
		System.out.println("列表第一个元素:"+list1.getFirst());
		//获取列表最后一个元素
		System.out.println("列表最后一个元素:"+list1.getLast());
		System.out.println(list1);
		
		//获取并删除列表第一个元素
		System.out.println("要删除的第一个元素:"+list1.removeFirst());
		//获取列表最后一个元素
		System.out.println("要删除的最后一个元素:"+list1.removeLast());
		System.out.println(list1);
		
		System.out.println("---------------");
		
		//JDK1.6替代方法
		//创建LinkedList集合对象
		LinkedList list2 = new LinkedList();
		
		//将指定元素插入开头
		list2.offerFirst("java01");
		list2.offerFirst("java02");
		//将指定元素插入结尾
		list2.offerLast("java03");
		list2.offerLast("java04");
		//获取列表第一个元素
		System.out.println("列表第一个元素:"+list2.peekFirst());
		//获取列表最后一个元素
		System.out.println("列表最后一个元素:"+list2.peekLast());
		System.out.println(list2);
		
		//获取并删除列表第一个元素
		System.out.println("要删除的第一个元素:"+list2.pollFirst());
		//获取列表最后一个元素
		System.out.println("要删除的最后一个元素:"+list2.pollLast());
		System.out.println(list2);
	}

}



三、Set

Set:无序,不可以重复元素。Set接口中的方法和Collection一致。

1.HashSet:底层数据结构是哈希表,线程不同步。

保证元素唯一性的原理:判断元素的hashCode值是否相同。如果相同,还会继续判断元素的equals方法,是否为true。如果为true,那么视为相同元素,不存。如果为false,那么存储。如果元素的hashCode值不同,不会调用equals。

哈希表的原理:

对对象元素中的关键字(对象中的特有数据),进行哈希算法的运算,并得出一个具体的算法值,这个值称为哈希值,哈希值就是这个元素的位置。如果哈希值出现冲突,再次判断这个关键字对应的对象是否相同。如果对象相同,就不存储,因为元素重复。如果对象不同,就存储,在原来对象的哈希值基础+1顺延。存储哈希值的结构,我们称为哈希表。既然哈希表是根据哈希值存储的,为了提高效率,最好保证对象的关键字是唯一的。这样可以尽量少的判断关键字对应的对象是否相同,提高了哈希表的操作效率。

//创建Person类,定义name和age属性,创建set、get方法,复写toString方法方便打印
//姓名和年龄相同视为相同元素,复写hashCode和equals方法
class Person
{
	private String name ; 
	private int age;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
	@Override
	public int hashCode() {

		return name.hashCode()+age*27;
	}
	@Override
	public boolean equals(Object obj) {
		//同一个对象存两次,直接返回true
		if (this == obj)
			return true;
		//对象为空返回false
		if (obj == null)
			return false;
		//存储的对象不是所需类的抛出ClassCastException
		if (!(obj instanceof Person))
			throw new ClassCastException("类型错误");
		Person p = (Person) obj;
		
		return this.name.equals(p.name)&&this.age == p.age;
		
	}
	
}
//往HashSet集合中存储Person对象。如果姓名和年龄相同,视为同一个人,视为相同元素。
public class HashSetDemo {

	public static void main(String[] args) {
		//添加不同的的对象进行验证
		HashSet hs = new HashSet();
		hs.add(new Person("zhangsan01",10));
		hs.add(new Person("zhangsan02",10));
		hs.add(new Person("zhangsan03",10));
		hs.add(new Person("zhangsan01",13));
		hs.add(new Person("zhangsan01",10));
		
		for(Iterator it = hs.iterator();it.hasNext();)
		{
			System.out.println(it.next());
		}
	}

}

2.TreeSet:可以对Set集合中的元素进行排序,底层数据结构是二叉树。

保证元素唯一性的依据:就是根据比较方法的返回结果是否是0,是0,就是相同元素,不存。在判断时,需要分主要条件和次要条件,当主要条件相同时,再判断次要条件,按照次要条件排序。

TreeSet对元素进行排序的方式一:让元素自身具备比较功能,元素就需要实现Comparable接口,覆盖compareTo方法。这种方式也被称为元素的自然顺序,或者叫做默认顺序。

//实现Comparable接口,复写compareTo方法,让Person元素自带比较性
class Person implements Comparable{
	private String name;
	private int age;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}

	//复写hashCode和equals方法方便其他调用
	public int hashCode() {

		return name.hashCode() + age * 27;
	}
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (!(obj instanceof Person))
			throw new ClassCastException("类型错误");
		Person p = (Person) obj;

		return this.name.equals(p.name) && this.age == p.age;

	}
	
	//复写compareTo方法,先按照姓名排序,姓名相同按年龄排
	@Override
	public int compareTo(Object o) {
		
		if (!(o instanceof Person))
			throw new ClassCastException("类型错误");
		Person p = (Person) o;
		int num = this.getName().compareTo(p.getName());
		return num == 0 ? this.getAge() - p.getAge(): num ;
		
	}

}

//往TreeSet集合中存储Person对象,验证排序
public class TreeSetDemo {

	public static void main(String[] args) {
		
		TreeSet ts = new TreeSet();
		ts.add(new Person("zhangsan01",10));
		ts.add(new Person("zhangsan03",10));
		ts.add(new Person("zhangsan02",10));
		ts.add(new Person("zhangsan01",13));
		ts.add(new Person("zhangsan02",10));
		
		for(Object obj : ts)
		{
			Person p = (Person) obj ;
			System.out.println(p);
		}

	}

}


如果不要按照对象中具备的自然顺序进行排序,就使用TreeSet集合第二种排序方式:让集合自身具备比较功能,定义一个类实现Comparator接口,复写compare方法。将该类对象作为参数传递给TreeSet集合的构造函数。

当两种排序都存在时,以比较器为主。

import java.util.Comparator;
import java.util.TreeSet;

class Person {
	private String name;
	private int age;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}

	//复写hashCode和equals方法方便其他调用
	public int hashCode() {

		return name.hashCode() + age * 27;
	}
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (!(obj instanceof Person))
			throw new ClassCastException("类型错误");
		Person p = (Person) obj;

		return this.name.equals(p.name) && this.age == p.age;
		
	}	
}
//自定义一个比较器,复写compare方法,先按年龄排序,后按姓名排序
class PersonComparator implements Comparator
{
	@Override
	public int compare(Object o1, Object o2) {
		
		if (!(o1 instanceof Person))
			throw new ClassCastException("类型错误");
		if (!(o2 instanceof Person))
			throw new ClassCastException("类型错误");
		Person p1 = (Person) o1;
		Person p2 = (Person) o2;
		int num = p1.getAge()-p2.getAge();
		return num == 0 ? p1.getName().compareTo(p2.getName()) : num ;
		
	}
	
}

//定义TreeSet集合,传入自定义的比较器对象,验证排序
public class TreeSetDemo {

	public static void main(String[] args) {
		
		TreeSet ts = new TreeSet(new PersonComparator());
		ts.add(new Person("zhangsan01",10));
		ts.add(new Person("zhangsan03",10));
		ts.add(new Person("zhangsan02",10));
		ts.add(new Person("zhangsan01",13));
		ts.add(new Person("zhangsan02",10));
		
		for(Object obj : ts)
		{
			Person p = (Person) obj ;
			System.out.println(p);
		}

	}

}







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
黑马程序员的tb_brand是指在JavaWeb基础教程中创建的一个表。这个表是用来存储品牌信息的,具体的表结构和数据类型需要和JavaBean类中的成员变量保持一致。\[1\]在这个教程中,使用了Maven来构建项目,并且使用了MyBatis作为持久层框架,通过配置pom.xml文件来引入相关依赖。\[2\] Maven是一个用于管理和构建Java项目的工具,它提供了一套标准化的项目结构、构建流程和依赖管理机制。\[3\] #### 引用[.reference_title] - *1* [【JAVAWEB开发】黑马程序员java web案例资料(含Element的删除与修改)](https://blog.csdn.net/aasd23/article/details/126940147)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [黑马程序员-MyBatis 框架-最全入门笔记、阿伟看了都得说真大、真细、真全!!!](https://blog.csdn.net/qq_57383364/article/details/128103058)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [JavaWeb——黑马程序员课程笔记](https://blog.csdn.net/King_ZACC/article/details/128573804)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值