List和Set
1.集合:存储多个引用数据类型的对象的容器,这个容器可以自动扩展。(动态数组,长度可自动扩 增)
2.集合中常用的几个概念
2.1:有序:按添加的顺序来存值。
2.2:可排序:按照一定顺序(数字由小到大,由大到小,字母按字母顺序升序或降序)来存 值。
2.3:唯一性:不可重复。
3.集合家族
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(跌代器):专门用来遍历数组和集合的工具类。
常用方法:
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()方法,才能实现去重。
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集合的构造方法的参数传入。
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);
}
上一篇: Elasticsearch环境搭建
下一篇: 为什么JavaScript是弱类型语言