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

List和Set

程序员文章站 2022-05-19 10:12:13
...

1.集合:存储多个引用数据类型的对象的容器,这个容器可以自动扩展。(动态数组,长度可自动扩 增)

2.集合中常用的几个概念
2.1:有序:按添加的顺序来存值。
2.2:可排序:按照一定顺序(数字由小到大,由大到小,字母按字母顺序升序或降序)来存 值。
2.3:唯一性:不可重复。

3.集合家族
List和Set
List和Set
3.1:Collection:无序,可重复(不唯一)的单一对象。
3.1.1:List:存储有序,可重复(不唯一)的单一对象。
2.1.1.1:ArrayList:存储有序,不唯一的单一对象,底层采用Objec数组存值。
2.1.1.2:LinkedList:存储有序,不唯一的单一对象,底层采用双向链表存值。

3.1.2:Set:存储无序,不可重复(唯一)的单一对象。
2.1.2.1:HashSet:存储无序,唯一的单一对象。底层采用HashMap的Key存值。
2.1.2.2:TreeSet:存储无序,可排序的单一对象。底层采用TreeMap的Key存值。

3.2:Map:按Key-Value对方式存值。
3.2.1:HashMap:按Key-Value对方式存值,key无序,唯一的。底层采用数组+链表结构存 值。
3.2.2:TreeMap:按key-Value对方式存值,Key无序,可排序,唯一的。底层采用二叉树 结构存值。

4.ArrayList:存储有序,可重复的单一对象。底层采用Object数组存值。扩容默认按1.5倍扩容。
优点:遍历集合和修改集合中元素效率高。
缺点:添加和删除指定索引处元素效率低。

  eg:public static void main(String[] args) {
    	//创建集合对象
    	List alist1=new ArrayList();
    	//向集合中添加元素
    	alist1.add(11);
    	alist1.add(33);
    	alist1.add(11);
	
	//遍历集合
	for (int i = 0; i < alist1.size(); i++) {
		System.out.println(alist1.get(i));
	}
	
	System.out.println("---------------------------------");
	//向集合中指定索引处添加元素,索引范围[0,集合名.size()]
	alist1.add(0, 22);
	alist1.add(3,55);
	
	//遍历集合
	for (int i = 0; i < alist1.size(); i++) {
		System.out.println(alist1.get(i));
	}
	
	System.out.println("************************************");
	//删除指定索引处的元素
	alist1.remove(0);
	
	//遍历集合
	for (Object ob : alist1) {
		System.out.println(ob);
	}
	
	System.out.println("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
	//删除集合中的元素对象
	alist1.remove((Object)11);
	
	//遍历集合
	for (Object ob : alist1) {
		System.out.println(ob);
	}
	
	System.out.println("*****************************************");
	//修改集合中指定索引处的元素
	alist1.set(0, 666);
	//遍历集合
	for (Object ob : alist1) {
		System.out.println(ob);
	}
	
	System.out.println("----------------------------------------");
	//清空集合
	alist1.clear();
	//遍历集合
	for (Object ob : alist1) {
		System.out.println(ob);
	}
}

5.LinkedList:存储有序,可重复的单一对象。底层双向链表结构存值。
优点:按照指定索引添加和删除元素效率高。
缺点:遍历元素的效率低,修改元素效率低。

eg:public static void main(String[] args) {
	//创建集合对象
	LinkedList alist1=new LinkedList();
	//向集合中添加元素
	alist1.add(11);
	alist1.add(33);
	alist1.add(11);
	
	//向集合中添加第一个元素
	alist1.addFirst(88);
	//向集合中添加最后一个元素
	alist1.addLast(999);
	
	//遍历集合
	for (int i = 0; i < alist1.size(); i++) {
		System.out.println(alist1.get(i));
	}
	
	System.out.println("---------------------------------");
	//向集合中指定索引处添加元素,索引范围[0,集合名.size()]
	alist1.add(0, 22);
	alist1.add(3,55);
	
	//遍历集合
	for (int i = 0; i < alist1.size(); i++) {
		System.out.println(alist1.get(i));
	}
	
	System.out.println("************************************");
	//删除指定索引处的元素
	alist1.remove(0);
	
	//遍历集合
	for (Object ob : alist1) {
		System.out.println(ob);
	}
	
	System.out.println("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
	//删除集合中的元素对象
	alist1.remove((Object)11);
	
	//遍历集合
	for (Object ob : alist1) {
		System.out.println(ob);
	}
	
	System.out.println("*****************************************");
	//修改集合中指定索引处的元素
	alist1.set(0, 666);
	//遍历集合
	for (Object ob : alist1) {
		System.out.println(ob);
	}
	
	System.out.println("----------------------------------------");
	//清空集合
	alist1.clear();
	//遍历集合
	for (Object ob : alist1) {
		System.out.println(ob);
	}
}

6.Collections:集合的工具类。专门对collection集合下子类作操作。

7.Iterator(跌代器):专门用来遍历数组和集合的工具类。
List和Set
常用方法:
hasNext();如果仍有元素可以迭代,则返回 true。(换句话说,如果 next 返回了元素 而不是抛出异常,则返回 true)。
next();返回迭代的下一个元素。集合中每个元素只能迭代一次。

eg:public static void main(String[] args) {
	//创建一个集合对象
	List numList=new ArrayList();
	//向集合中添加元素
	numList.add(22);
	numList.add(88);
	numList.add(33);
	numList.add(99);
	numList.add(11);
	
	//获得集合的迭代器
	Iterator it1=numList.iterator();
	//先判断迭代器后面有无元素,如果有元素就迭代出来
	while(it1.hasNext()) {
		//获得当前迭代的元素
		Object ob=it1.next();//22
		System.out.println(ob);
	}
}

8.泛型:数据类型参数化。(将数据类型作为参数传递)。
8.1:泛型集合:集合类型<数据类型> 集合名=new 集合类型<【数据类型】>();
集合存值的缺点:什么类型都可以存到同一个集合中,存元素时会默认将元素装箱成 Object类型。取出数据时不方便,不知道这个元素的原来类型。
泛型集合的优点:一个泛型集合中只能存一种数据类型,存值和取值方便;
不用频繁的装箱和拆箱。
8.2:泛型迭代器:Iterator<数据类型> it2=集合名.iterator();
8.2.1:泛型迭代器一般用来遍历泛型集合。

	eg:public static void main(String[] args) {
	//创建一个泛型集合对象
	List<Student> obList=new ArrayList<>();
	//向集合中添加元素
	obList.add(new Student("张三1", 11));
	obList.add(new Student("张三2", 12));
	obList.add(new Student("张三3", 13));
	obList.add(new Student("张三4", 14));

	//获得集合的迭代器对象
	Iterator<Student> it2=obList.iterator();
	//循环先判断迭代器后面是否有元素可迭代,如果有就迭代出来
	while (it2.hasNext()) {
		Student stu=it2.next();
		System.out.println(stu.snmae+","+stu.sage);
	}
  }

8.3:泛型类(扩展):

eg:/**
 * 泛型类
 * @author sx
 * @version 1.0 2019年7月2日
 * @param <T> 泛型的占位符
 */
public class Teacher<T> {
	public String tname;
	public Integer tage;
	public T tt;
}

public static void main(String[] args) {
		Teacher<String> teacher1=new Teacher<>();
		teacher1.tname="孙星";
		teacher1.tage=18;
		teacher1.tt="abdfefef";
		
		Teacher<Integer> teacher2=new Teacher<>();
		teacher2.tname="黄香桔";
		teacher2.tage=18;
		teacher2.tt=11;
	}

8.4:泛型方法(扩展):

eg:/**
 * 泛型方法
 * @param cname
 */
public <T> void show1(T cname) {
	System.out.println("泛型方法的参数为:"+cname);
}
public static void main(String[] args) {
	//创建对象
	Cat c1=new Cat();
	//用对象调用泛型方法
	c1.show1("abcd");
	
	c1.show1(18);
	
	c1.show1('男');
}

9.HashSet:存储无序,唯一的单一对象。底层采用HashMap的Key存值。
唯一性:通过hashCode()和equals()方法来去重。
优点:去除重复元素。
注意:HashSet的泛型类一定要重写hashCode()和equals()方法,才能实现去重。
List和Set

eg:案例一:
	public static void main(String[] args) {
	//创建集合对象
	Set<Integer> hset1=new HashSet();
	//向集合中元素
	hset1.add(77);
	hset1.add(88);
	hset1.add(11);
	hset1.add(99);
	hset1.add(22);
	
	//获得集合的迭代器对象
	Iterator<Integer> it3=hset1.iterator();
	//用迭代器遍历集合
	while (it3.hasNext()) {
		Integer num1=it3.next();
		System.out.println(num1);
	}
	
	System.out.println("---------------------------");
	//删除集合中的元素
	hset1.remove(11);
	
	//遍历集合
	for (Integer num2 : hset1) {
		System.out.println(num2);
	}
	
	System.out.println("*************************");
	//清空集合
	hset1.clear();
	//遍历集合
	for (Integer num2 : hset1) {
		System.out.println(num2);
	}
}

案例二:
	public class Student {
public String sname;
public Integer sage;

public Student() {
	// TODO Auto-generated constructor stub
}

public Student(String snmae, Integer sage) {
	super();
	this.sname = snmae;
	this.sage = sage;
}

@Override
public int hashCode() {
	final int prime = 31;
	int result = 1;
	result = prime * result + ((sage == null) ? 0 : sage.hashCode());
	result = prime * result + ((sname == null) ? 0 : sname.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;
	Student other = (Student) obj;
	if (sage == null) {
		if (other.sage != null)
			return false;
	} else if (!sage.equals(other.sage))
		return false;
	if (sname == null) {
		if (other.sname != null)
			return false;
	} else if (!sname.equals(other.sname))
		return false;
	return true;
	}
}

	public static void main(String[] args) {
	//创建集合对象
	Set<Student> hset1=new HashSet();
	//向集合中元素
	hset1.add(new Student("aa", 18));
	hset1.add(new Student("yy", 28));
	hset1.add(new Student("bb", 58));
	hset1.add(new Student("cc", 38));
	hset1.add(new Student("aa", 18));
	
	//获得集合的迭代器对象
	Iterator<Student> it3=hset1.iterator();
	//用迭代器遍历集合
	while (it3.hasNext()) {
		Student num1=it3.next();
		System.out.println(num1.sname+","+num1.sage);
	}
	
	System.out.println("---------------------------");
	//删除集合中的元素
	hset1.remove(11);
	
	//遍历集合
	for (Student num2 : hset1) {
		System.out.println(num2.sname+","+num2.sage);
	}
	
	System.out.println("*************************");
	//清空集合
	hset1.clear();
	//遍历集合
	for (Student num2 : hset1) {
		System.out.println(num2.sname+","+num2.sage);
	}
}

10.TreeSet:存储无序,可排序,唯一的单一对象。底层采用TreeMap的Key存值。
优点:可排序,去除重复的元素。
可排序性:如果排序器返回小于0数,排在前面,大于0排在后面。
唯一性:排序器返回0,表示元素相同。
注意:TreeSet一定要用排序器,第一种在TreeSet的泛型数据类实现自然排序器接口,重写排 序方法;第二种声明一个自定义排序器类实现自定义排序器接口,重写排序方法,创建自 定义排序器类的对象,将这个对象作为TreeSet集合的构造方法的参数传入。

List和Set

eg:public static void main(String[] args) {
	//创建集合对象
	TreeSet<Integer> tset1=new TreeSet<>();
	//向集合中添加元素
	tset1.add(66);
	tset1.add(88);
	tset1.add(44);
	tset1.add(33);
	tset1.add(99);
	tset1.add(77);
	tset1.add(55);
	tset1.add(66);
	
	//获得集合的迭代器
	Iterator<Integer> it1=tset1.iterator();
	//用迭代器遍历集合
	while (it1.hasNext()) {
		Integer num=it1.next();
		System.out.println(num);
	}
	
	System.out.println("--------------------------------");
	//删除集合中元素
	tset1.remove(66);
	
	//遍历集合
	for (Integer num1 : tset1) {
		System.out.println(num1);
	}
	
	System.out.println("*******************");
	//清空集合
	tset1.clear();
	
	//遍历集合
	for (Integer num1 : tset1) {
		System.out.println(num1);
	}
}

11.排序器
11.1:自然排序器(Comparable):让泛型类实现Comparable接口,重写排序方法compareTo。

eg:/**
 * 学生类,实现自然排序器接口,重写排序方法
 * @author sx
 * @version 1.0 2019年7月3日
 */
public class Student implements Comparable<Student>{
	public String sname;
	public Integer sage;
	
	public Student() {
		// TODO Auto-generated constructor stub
	}
	
	public Student(String sname, Integer sage) {
		super();
		this.sname = sname;
		this.sage = sage;
	}

/**
 * 排序方法,返回负数排在前面,返回正数排在后面,返回0表示是相同元素
 * 排序规则:先按姓名字典顺序升序排序,姓名相同再按年龄从小到大排序
 * @param o
 * @return
 */
@Override
public int compareTo(Student o) {
	if (this.sname.compareTo(o.sname)>0) {
		return 1;
	}else if(this.sname.compareTo(o.sname)<0) {
		return -1;
	}else {//姓名相同
		if (this.sage>o.sage) {
			return 1;
		}else if(this.sage<o.sage) {
			return -1;
		}else {//姓名相同,年龄相同
			return 0;
		}
	}
  }
}

public static void main(String[] args) {
		//创建集合对象
		TreeSet<Student> tset1=new TreeSet<>();
		//向集合中添加元素
		tset1.add(new Student("gg", 15));
		tset1.add(new Student("ee", 19));
		tset1.add(new Student("kk", 25));
		tset1.add(new Student("aa", 35));
		tset1.add(new Student("ff", 45));
		tset1.add(new Student("hh", 17));
		tset1.add(new Student("ee", 18));
		tset1.add(new Student("gg", 15));
		
	//获得集合的迭代器
	Iterator<Student> it1=tset1.iterator();
	//用迭代器遍历集合
	while (it1.hasNext()) {
		Student num=it1.next();
		System.out.println(num.sname+","+num.sage);
	}
	
	System.out.println("--------------------------------");
	//删除集合中元素
	tset1.remove(new Student("jj", 18));
	
	//遍历集合
	for (Student num1 : tset1) {
		System.out.println(num1.sname+","+num1.sage);
	}
	
	System.out.println("*******************");
	//清空集合
	tset1.clear();
	
	//遍历集合
	for (Student num1 : tset1) {
		System.out.println(num1.sname+","+num1.sage);
	}
}

11.2:自定义排序(Comparator):先声明一个排序器类实现自定义排序器接口Comparator,				重写排序规则,再将自定义排序器类的对象传给集合的构造方法作为参数


	eg:/**
 * 自定义排序器类
 * @author sx
 * @version 1.0 2019年7月3日
 */
public class MyComparator implements Comparator<Student>{

	/**
	 * 自定义排序器的排序方法
	 * 排序规则:先按姓名的字典顺序进行降序排序,姓名相同,按年龄从大到小排序
	 * 
	 */
	@Override
	public int compare(Student o1, Student o2) {
		if (o1.sname.compareTo(o2.sname)>0) {
			return -1;
		}else if(o1.sname.compareTo(o2.sname)<0) {
			return 1;
		}else {//姓名相同
			if (o1.sage>o2.sage) {
				return -1;
			}else if (o1.sage<o2.sage) {
				return 1;
			}else {//姓名相同,年龄相同
				return 0;
			}
		}
	}
}

public static void main(String[] args) {
		//创建自定义排序器对象
		MyComparator mc=new MyComparator();
		
	//创建集合对象,将自定义排序器对象作为集合构造方法的参数
	TreeSet<Student> tset1=new TreeSet<>(mc);
	//向集合中添加元素
	tset1.add(new Student("gg", 15));
	tset1.add(new Student("ee", 19));
	tset1.add(new Student("kk", 25));
	tset1.add(new Student("aa", 35));
	tset1.add(new Student("ff", 45));
	tset1.add(new Student("hh", 17));
	tset1.add(new Student("ee", 18));
	tset1.add(new Student("gg", 15));
	
	//获得集合的迭代器
	Iterator<Student> it1=tset1.iterator();
	//用迭代器遍历集合
	while (it1.hasNext()) {
		Student num=it1.next();
		System.out.println(num.sname+","+num.sage);
	}
	
	System.out.println("--------------------------------");
	//删除集合中元素
	tset1.remove(new Student("jj", 18));
	
	//遍历集合
	for (Student num1 : tset1) {
		System.out.println(num1.sname+","+num1.sage);
	}
	
	System.out.println("*******************");
	//清空集合
	tset1.clear();
	
	//遍历集合
	for (Student num1 : tset1) {
		System.out.println(num1.sname+","+num1.sage);
	}
}

11.3:匿名内部类自定义排序器:

eg:public static void main(String[] args) {
		//创建集合对象,将匿名自定义排序器内部类的对象作为集合构造方法的参数
	
	TreeSet<Student> tset1=new TreeSet<>(new Comparator<Student>() {

		/**
		 * 自定义排序器的排序方法
		 * 排序规则:先按姓名的字典顺序进行降序排序,姓名相同,按年龄从大到小排序
		 * 
		 */
		@Override
		public int compare(Student o1, Student o2) {
			if (o1.sname.compareTo(o2.sname)>0) {
				return -1;
			}else if(o1.sname.compareTo(o2.sname)<0) {
				return 1;
			}else {//姓名相同
				if (o1.sage>o2.sage) {
					return -1;
				}else if (o1.sage<o2.sage) {
					return 1;
				}else {//姓名相同,年龄相同
					return 0;
				}
			}
		}
	});
	//向集合中添加元素
	tset1.add(new Student("gg", 15));
	tset1.add(new Student("ee", 19));
	tset1.add(new Student("kk", 25));
	tset1.add(new Student("aa", 35));
	tset1.add(new Student("ff", 45));
	tset1.add(new Student("hh", 17));
	tset1.add(new Student("ee", 18));
	tset1.add(new Student("gg", 15));
	
	//获得集合的迭代器
	Iterator<Student> it1=tset1.iterator();
	//用迭代器遍历集合
	while (it1.hasNext()) {
		Student num=it1.next();
		System.out.println(num.sname+","+num.sage);
	}
	
	System.out.println("--------------------------------");
	//删除集合中元素
	tset1.remove(new Student("jj", 18));
	
	//遍历集合
	for (Student num1 : tset1) {
		System.out.println(num1.sname+","+num1.sage);
	}
	
	System.out.println("*******************");
	//清空集合
	tset1.clear();
	
	//遍历集合
	for (Student num1 : tset1) {
		System.out.println(num1.sname+","+num1.sage);
	}
}

12.匿名内部类(扩展):在一个类里面声明的类,这个类没有类名。
实现:用父接口或父抽象类作为数据类型,后面跟一双大括号,大括号中实现父接口或父抽象 类中方法。
适用场景:一个类一生只有一个对象,这个对象一生只用一次,就可以用匿名内部类。

eg:public static void main(String[] args) {
	//大括号就是匿名内部类,用父接口或父抽象类作为数据类型,创建这个类的对象
	AddInterface ai= new AddInterface() {

		@Override
		public void add(Integer num1, Integer num2) {
			int result=num1+num2;
			System.out.println("两数之和为:"+result);
			
		}

	};
	
	//用对象调用方法
	ai.add(1, 2);
}