while(lit.hasNext()) {
String s = (String)(lit.next()) ;
System.out.println(s);
}
System.out.println(“--------------------”);
//逆向遍历
while(lit.hasPrevious()) {
String s = (String)(lit.previous()) ;
System.out.println(s);
}
}
4.3.1 使用迭代器遍历的问题
如果使用迭代器遍历元素,就不能使用集合添加元素;
java.util.ConcurrentModificationException:并发修改异常 ;
4.3.1.1 使用迭代器遍历,迭代器添加元素
public static void main(String[] args) {
//创建一个List集合对象
List list = new ArrayList();
//集合存储三个元素
list.add(“hello”) ;
list.add(“world”) ;
list.add(“java”) ;
//由于Collection的Iterator迭代器没有添加功能的,所以列表迭代器
ListIterator lit = list.listIterator() ;
while(lit.hasNext()) {
String s = (String)(lit.next()) ;
//判断
if(“world”.equals(s)) {
//迭代器添加元素
lit.add(“javaee”);
}
}
System.out.println(“list:”+list);
4.3.1.2 使用集合遍历,集合添加元素
public static void main(String[] args) {
//创建一个List集合对象
List list = new ArrayList();
//集合存储三个元素
list.add(“hello”) ;
list.add(“world”) ;
list.add(“java”) ;
//普通for循环:get(int index) 和 size()方法先结合
for(int i = 0 ;i < list.size() ; i ++) {
//获取元素
String s = (String)(list.get(i)) ;
//判断
if(“world”.equals(s)) {
//使用集合添加
list.add(“javaee”) ;
}
}
System.out.println(“list:”+list);
}
public static void main(String[] args) {
//创建ArrayList集合对象
ArrayList array = new ArrayList() ;
//给集合中添加元素
array.add(“kaka”) ;
array.add(“hello”) ;
array.add(“world”) ;
array.add(“world”) ;
array.add(“java”) ;
array.add(“java”) ;
//1:Object[] toArray遍历
Object[] objs = array.toArray() ;
for(int x = 0 ; x < objs.length ; x ++) {
String s = (String)(objs[x]) ;
System.out.println(s+“—”+s.length());
}
System.out.println(“-----------------------”);
//2:Collection的迭代器
Iterator it = array.iterator() ;
while(it.hasNext()) {
String s = (String)(it.next()) ;
System.out.println(s+“—”+s.length());
}
System.out.println(“-----------------------”);
//3:使用List集合的列表迭代器
ListIterator lit = array.listIterator() ;
while(lit.hasNext()) {
String s = (String)(lit.next()) ;
System.out.println(s+“—”+s.length());
}
System.out.println(“-----------------------”);
//4:Object get(int index) 和int size()方法相集合
for (int i = 0; i < array.size(); i++) {
String s = (String)(array.get(i)) ;
System.out.println(s+“—”+s.length());
}
}
- ArrayList:
底层数据结构:数组----->查询快,增删慢
从线程角度考虑:此实现不是同步的---->线程不安全---->执行效率高!
- LinkedList:
底层数据结构:链接列表(链表)---->查询慢,增删快
从线程角度考虑:此实现不是同步的----->线程不安全---->执行效率高!
- Vector:
底层数据库结构:可增长的数组实现---->查询快.增删慢
线程方面: 线程安全—>同步----->执行效率低!
除多线程环境外,在需求中没有指定具体的集合---->都使用ArrayList ()
见4.4,4.5;
4.6.1 存储自定义对象并遍历
需求:有5个学生,都有姓名和年龄,现需要将5个学生存储到集合中,并遍历5个学生信息
1)定义一个学生类
2)创建集合对象 ArrayList
3)创建5个学生
5)将5个学生添加到集合中
6)创建迭代器
7)利用迭代器遍历集合
//学生类
public class Student {
private String name;
private int age;
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String name, int age) {
super();
this.name = name;
this.age = 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;
}
@Override
public String toString() {
return “Student [name=” + name + “, age=” + age + “]”;
}
}
public static void main(String[] args) {
//创建ArrayList集合对象
ArrayList array = new ArrayList();
//创建5个学生对象
Student s1 = new Student(“卡卡”,23);
Student s2 = new Student(“张三”,23);
Student s3 = new Student(“李四”,23);
Student s4 = new Student(“王五”,23);
Student s5 = new Student(“赵六”,23);
//集合中添加元素
array.add(s1);
array.add(s2);
array.add(s3);
array.add(s4);
array.add(s5);
//迭代器
Iterator it = array.iterator();
//遍历
while(it.hasNext()){
Student s = (Student)(it.next());
System.out.println(s.getName() + “—” + s.getAge());
}
}
4.6.2 案例:获取10个1-20之间的随机数,要求不能重复,使用ArrayList集合
public static void main(String[] args) {
ArrayLists();
}
private static void ArrayLists() {
ArrayList arr = new ArrayList<>();
Random r = new Random();
while(arr.size() != 10){
int number = r.nextInt(20)+1 ;
if(!arr.contains(number)){
arr.add(number) ;
}
}
System.out.println(“ArrayList版本:”);
//遍历
Iterator it = arr.iterator();
while(it.hasNext()){
Integer i = (Integer)(it.next());
System.out.print(i + “\t”);
}
}
见4.5
通过整数索引访问组件;
线程安全的类:StringBuffer 和 Vector
Vector类特有功能:
- public void addElement(Object obj):给Vector集合中添加元素 ------->类似于add(Object obj)
- public Object elementAt(int index):通过整数索引值获取指定元素内容---->类似于Object get(int index)
- public Enumeration elements() :就是Vector集合的专有遍历方式:返回Enumeration接口(枚举元素)----->类似于:Iterator iterator()
Enumeration接口:
* boolean hasMoreElements():判断枚举中是否存在元素
* Object nextElement():获取下一个枚举元素
public static void main(String[] args) {
//创建Vector集合对象
Vector v = new Vector();
//给Vector集合中添加元素
v.add(“kaka”);
v.add(“hello”);
v.add(“world”);
v.add(“java”);
//通过整数索引值获取指定元素内容 + size()遍历Vector集合
for(int i = 0; i < v.size(); i++){
String s = (String)(v.elementAt(i));
System.out.println(s + “—” + s.length());
}
System.out.println(“------------”);
//特有遍历
Enumeration em = v.elements();
while(em.hasMoreElements()){
String s = (String)(em.nextElement());
System.out.println(s + “—” + s.length());
}
}
见4.5
ListedList集合特有功能:
- 添加
public void addFirst(Object e):将指定元素始终在链表开头添加
public void addLast(Object e):将指定的元素在链表的末尾添加
- 获取
public Object getFirst() :获取链表的第一个元素
public Object getLast() :获取链表的最后一个元素
- 删除
public Object removeFirst():删除链表第一个元素
public Object removeLast() :删除链表最后一个元素
public static void main(String[] args) {
//创建一个LinkeList集合对象
LinkedList link = new LinkedList() ;
link.add(“hello”) ;
link.add(“world”) ;
link.add(“java”) ;
//将指定元素始终在链表开头添加
link.addFirst(“javaee”);
link.addFirst(“android”);
//将指定的元素在链表的末尾添加
link.addLast(“go”);
link.addLast(“R”);
//获取链表的第一个元素,返回被获取的元素
System.out.println(“getFirst():”+link.getFirst());//android
//获取链表的最后一个元素
System.out.println(“getLast():”+link.getLast());//R
//删除链表第一个元素
System.out.println(“removeFirst():”+link.removeFirst());//android
//删除链表最后一个元素
System.out.println(“removeLast():”+link.removeLast());//R
System.out.println(“link:”+link);//[javaee, hello, world, java, go]
}
4.8.1 利用ListedList 集合模拟栈结构特点_01
栈的特点:先进后出;
利用ListedList 中的 public void addFirst(Object e)方法,将指定元素始终在链表开头添加,实现模拟栈的结构特点;
public static void main(String[] args) {
//创建一个LinkedList集合
LinkedList link = new LinkedList() ;
//addFirst()添加
link.addFirst(“kaka”);
link.addFirst(“hello”);
link.addFirst(“java”);
//遍历
//使用迭代器
Iterator it = link.iterator();
while(it.hasNext()) {
String s = (String)(it.next()) ;
System.out.println(s);
}
}
4.8.2 利用ListedList 集合模拟栈结构特点_02
利用ListedList 中的 public void addFirst(Object e)方法,将指定元素始终在链表开头添加,在利用public Object removeFirst()方法,删除链表第一个元素;一加一删来实现模拟栈结构特点;
import java.util.LinkedList;
/**
-
自定义的栈集合类
-
@author 卡卡
*/
public class MyStack {
private LinkedList link;
//定义无参构造
public MyStack(){
link = new LinkedList();
}
/**
- 添加
*/
public void add(Object obj){
link.addFirst(obj);
}
/**
- 获取
*/
public Object get(){
return link.removeFirst();
}
/**
- 判断
*/
public boolean isEmpy(){
return link.isEmpty();
}
}
/*
- 测试类
*/
public class MyStackTest {
public static void main(String[] args) {
//创建MyStack对象
MyStack my = new MyStack();
//添加元素
my.add(“kaka”);
my.add(“hello”);
my.add(“world”);
while(!my.isEmpy()){
//获取元素
System.out.println(my.get());
}
}
}
需求:在ArrayList存储了一些重复元素,去重ArrayList重复的元素!(字符串元素)
创建一个新集合的思想
- 创建一个ArrayList集合对象 array
- 给集合中添加很多重复元素
- 创建一个新的集合newArray
- 遍历以前的集合
- 判断新集合如果不包含这个元素,就将这个元素添加到新集合中
- 遍历新集合
public static void main(String[] args) {
//创建一个ArrayList集合
ArrayList arr = new ArrayList<>();
//给集合中添加重复元素
arr.add(“kaka”);
arr.add(“hello”);
arr.add(“world”);
arr.add(“java”);
arr.add(“kaka”);
arr.add(“hello”);
arr.add(“kaka”);
arr.add(“java”);
//创建一个新集合
ArrayList newArr = new ArrayList<>();
//遍历以前的元素
Iterator it = arr.iterator();
while(it.hasNext()){
//获取元素
String s = (String)(it.next());
//判断新集合如果不包含这个元素,添加到新集合中;
if(! newArr.contains(s)){
newArr.add(s);
}
}
//遍历新集合
Iterator itN = newArr.iterator();
while(itN.hasNext()){
String s = (String)(itN.next());
System.out.println(s);
}
}
需求:在ArrayList存储了一些重复元素,去重ArrayList重复的元素!(字符串元素)
不创建新集合,利用选择排序的思想
- 使用0索引对应的元素和后面索引的元素进行比较,如果后面的元素和前面元素一致,就将后面重复元素从集合删除掉----->remove(int index)
- 创建ArrayList集合对象
- 添加重复元素
- 利用选择排序的思想,删除重复的元素
- 遍历集合
public static void main(String[] args) {
//创建一个ArrayList集合
ArrayList arr = new ArrayList<>();
//给集合中添加重复元素
arr.add(“kaka”);
arr.add(“hello”);
arr.add(“world”);
arr.add(“java”);
arr.add(“kaka”);
arr.add(“hello”);
arr.add(“kaka”);
arr.add(“java”);
//利用选择排序的思想,将后面重复元素从集合删除掉
for(int i = 0 ;i < arr.size()-1 ;i ++) {
for(int j = i+1 ; j < arr.size(); j++) {
//如果后面元素和前面的元素重复了,删除后面元素,里面索引–
//通过角标获取集合元素内容get(int index)
if(arr.get(i).equals(arr.get(j))) {
//删除
arr.remove(j) ;
j – ;
}
}
}
//遍历集合
Iterator it = arr.iterator() ;
while(it.hasNext()) {
String s = (String)(it.next()) ;
System.out.println(s);
}
}
需求:使用ArrayList集合存储自定义对象Student并去重
1)定义一个学生类
2)创建集合对象 ArrayList
3)创建5个学生
5)将5个学生添加到集合中
6)创建迭代器
7)利用迭代器遍历集合
重点:重写equals方法
//学生类
public class Student {
private String name ;
private int age ;
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String name, int age) {
super();
this.name = name;
this.age = 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;
}
@Override
public String toString() {
return “Student [name=” + name + “, age=” + age + “]”;
}
@Override
public boolean equals(Object obj) { //Student s ;
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())//获取字节码文件对象: this.getClass
return false;
Student other = (Student) obj;
if (age != other.age) //比较当前学生类中成员信息
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name)) //String name
return false;
return true;
}
}
public static void main(String[] args) {
//创建ArrayList集合对象
ArrayList arr = new ArrayList<>();
//创建学生对象
//创建对象
Student s1 = new Student(“卡卡”,23);
Student s2 = new Student(“张三”,23);
Student s3 = new Student(“李四”,23);
Student s4 = new Student(“卡卡”,23);
Student s5 = new Student(“王五”,23);
Student s6 = new Student(“赵六”,23);
//添加到集合中
arr.add(s1);
arr.add(s2);
arr.add(s3);
arr.add(s4);
arr.add(s5);
arr.add(s6);
//创建一个新集合
ArrayList newArr = new ArrayList<>();
//遍历以前的集合
Iterator it = arr.iterator();
while(it.hasNext()){
Student s = (Student)(it.next());
if(!newArr.contains(s)){
newArr.add(s);
}
}
//遍历新的集合
Iterator it2 = newArr.iterator();
for(int i = 0; i < newArr.size();i++){
Student s = (Student)(newArr.get(i));
System.out.println(s.getName() + “—” +s.getAge());
}
}
================================================================================
Set接口就是一个不包含重复元素的collection;全部继承自Collection中的方法;
特点:
无序、无下标、元素不可以重复
Set集合和List集合的区别:
- List集合:有序的集合,存储和取出是一致的,它允许元素重复
- Set集合:无序的集合,存储和取出不一致(不能保证该顺序恒久不变),它元素唯一的
public static void main(String[] args) {
//创建一个Set集合对象
Set set = new HashSet();
//添加元素
set.add(“hello”);
set.add(“hello”);
set.add(“java”);
set.add(“java”);
set.add(“world”);
set.add(“world”);
//增强for遍历
for(String s :set){
System.out.println(s);//java world hello
}
}
- 元素不能重复
Set中的子实类包括HashSet、LinkedHashSet、TreeSet
5.2.1 HashSet类概述
HashSet集合的add方法跟HashMap集合的put有关系,将所有需要存入HashSet的值,直接保存在HashMap中,底层依赖于hashCode()、equals()方法。需要在自定义的类中重写hashCode()和equals方法();
需求:使用HashSet集合存储自定义对象Student,保证元素唯一
//学生类
public class Student {
private String name;
private int age;
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String name, int age) {
super();
this.name = name;
this.age = 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;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
//result = 31 * 29 + name的哈希值
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 (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public String toString() {
return “Student [name=” + name + “, age=” + age + “]”;
}
}
public static void main(String[] args) {
//创建一个HashSet集合对象
Set set = new HashSet();
//创建学生对象
Student s1 = new Student(“卡卡”,23);
Student s2 = new Student(“张三”,26);
Student s3 = new Student(“卡卡”,24);
Student s4 = new Student(“张三”,26);
Student s5 = new Student(“卡卡”,34);
//添加集合中
set.add(s1);
set.add(s2);
set.add(s3);
set.add(s4);
set.add(s5);
//增强for遍历
for(Student s : set){
System.out.println(s.getName()+“—”+s.getAge());
}
}
以上代码输出:
卡卡—23
卡卡—24
卡卡—34
张三—26
5.2.2 LinkedHashSet类概述
元素有序唯一,底层数据结构是链接列表和哈希表
-
链接列表: 来保证元素有序(存储和取出一致的)
-
哈希表: 来保证元素唯一性
节点形式单独存储数据,并可以指向下一个节点,通过顺序访问节点,可保留元素插入顺序;
public static void main(String[] args) {
//创建LinkedHashSet集合对象
LinkedHashSet link = new LinkedHashSet();
//添加元素
link.add(“hello”);
link.add(“hello”);
link.add(“kaka”);
link.add(“kaka”);
link.add(“javaEE”);
link.add(“javaEE”);
link.add(“android”);
//遍历
for(String s : link){
System.out.println(s);
}
}
以上代码输出:
hello
kaka
javaEE
android
===================================================================================
底层数据结构是红黑树一种自平衡的二叉树;
1). 实现了SortedSet接口,要求必须可以对元素排序,使用元素的自然顺序对元素进行排序。
2). 所有插入元素,必须实现Comparable接口,覆盖compareTo方法。
3). 根据compareTo方法返回0作为去重的依据
6.1 Red - Black - Tree 红黑树结构简述
红黑树一种自平衡的二叉查找树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。
public static void main(String[] args) {
//创建TreeSet集合对象
TreeSet ts = new TreeSet();
//add()添加
ts.add(20) ;
ts.add(18) ;
ts.add(23) ;
ts.add(22) ;
ts.add(17) ;
ts.add(24) ;
ts.add(19) ;
ts.add(18) ;
ts.add(24) ;
//遍历集合
for(Integer i : ts) {
System.out.print(i+" ");//17 18 19 20 22 23 24
}
}
遍历原理:拿上面的数字20,18,23,22,17,24,19,18,24来说:
存储元素:
-
添加元素时,第一个元素20作为根节点---->root
-
后面添加的元素都需要和根节点进行比较
-
如果比根节点小,作为根节点的左孩子(根节点左边的子节点)
-
如果比根节点打,作为根节点的右孩子(根节点右边的子节点)
-
如果元素相等,不会进入到红黑树的结构中
遍历元素:
使用中序遍历(左根右)
-
首先访问根节点的左孩子,如果这个左孩子仍然有左孩子继续访问,一直到没有左孩子的节点,输出该节点17;
-
依据中序遍历次序,输出17的父节点18,;
-
在输出18的右孩子19;
-
以节点18为大的左孩子输出完毕,在输出整个二叉树的根节点20;
-
依据中序遍历次序左根右,找到根节点20的右孩子23,因为23有左孩子所以输出23的左孩子22;
-
输出22的根节点23;
-
在输出23的右孩子24;
-
最终得到序列17,18,19,20,22,23,24
6.2 TreeSet 集合案例_按照学生的年龄从小到大排序
TreeSet集合存储自定义对象,并且主要条件按照学生年龄的长度(从小到大比较)
- 主要条件:年龄从小到大排序
- 次要条件:
长度如果一样,还需要比较姓名的内容
需要比较人的年龄是否一样
/*
-
如果要使用自然排序,针对自定义,该自定义类必须实现Comparable接口
-
重写 compareTo(T s)方法对元素进行比较
*/
public class Student implements Comparable{
private String name;
private int age;
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String name, int age) {
super();
this.name = name;
this.age = 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;
}
@Override
public String toString() {
return “Student [name=” + name + “, age=” + age + “]”;
}
@Override
public int compareTo(Student s) {
// TODO Auto-generated method stub
int num = this.age - s.age;
int num2 = (num == 0?(this.name.compareTo(s.name)):num);
return num2;
}
}
public static void main(String[] args) {
TreeSet ts = new TreeSet();
Student s1 = new Student(“kaka”,23);
Student s2 = new Student(“kaka”,21);
Student s3 = new Student(“kaaka”,28);
Student s4 = new Student(“kkkkaka”,26);
Student s5 = new Student(“ka11ka”,24);
Student s6 = new Student(“kakaaa”,23);
Student s7 = new Student(“kaka”,23);
//添加元素
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
ts.add(s5);
ts.add(s6);
ts.add(s7);
//遍历
for(Student s : ts){
System.out.println(s.getName()+“—”+s.getAge());
}
}
以上代码输出:
kaka—21
kaka—23
kakaaa—23
ka11ka—24
kkkkaka—26
kaaka—28
/*
- 学生类
*/
public class Student implements Comparable {
private String name ;
private int age ;
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String name, int age) {
super();
this.name = name;
this.age = 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;
}
@Override
public String toString() {
return “Student [name=” + name + “, age=” + age + “]”;
}
//重写Comparable接口的方法
@Override
public int compareTo(Student s) {
//主要条件按照学生姓名的长度(从小到大)
int num = this.name.length() - s.name.length() ;
//1)次要条件:姓名的长度一样,姓名的内容不一定一样
int num2 = num == 0 ? (this.name.compareTo(s.name)) : num;
//2)次要条件:姓名的长度一样,内容一样,年龄不一定一样
int num3 = num2 == 0 ? (this.age-s.age) : num2 ;
return num3 ;
}
}
public static void main(String[] args) {
//创建一个TreeSet集合 对象
TreeSet ts = new TreeSet() ; //实现自然排序
//创建学生对象
Student s1 = new Student(“kaka”,23);
Student s2 = new Student(“kaka”,21);
Student s3 = new Student(“kaaka”,28);
Student s4 = new Student(“kkkkaka”,26);
Student s5 = new Student(“ka11ka”,24);
Student s6 = new Student(“kakaaa”,23);
Student s7 = new Student(“kaka”,23);
ts.add(s1) ;
ts.add(s2) ;
ts.add(s3) ;
ts.add(s4) ;
ts.add(s5) ;
ts.add(s6) ;
ts.add(s7) ;
//增强for
for(Student s :ts) {
System.out.println(s.getName()+“—”+s.getAge());
}
}
以上代码输出:
kaka—21
kaka—23
kaaka—28
ka11ka—24
kakaaa—23
kkkkaka—26
构造方法:
- TreeSet():创建TreeSet集合对象使用自然排序
- TreeSet(Comparator comparatpr):比较器排序
* 构造方法的形式参数是一个接口类型:
1. 自定义类实现Comarator接口,重写compare(T o1 ,T o2)方法
2. 接口的匿名内部类
new 接口名(){
重写接口中的方法;
};
注:6.4.1和6.4.2学生类都是以下
/*
- 学生类
*/
public class Student {
private String name;
private int age;
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String name, int age) {
super();
this.name = name;
this.age = 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;
}
@Override
public String toString() {
return “Student [name=” + name + “, age=” + age + “]”;
}
}
6.4.1 自定义类实现Comparator接口
/*
- Comparator接口
*/
public class MyComparator implements Comparator{
public MyComparator() {
}
@Override
public int compare(Student s1, Student s2) {
//s1----->this
//s2---->传进来被比较的对象
//主要条件:按照学生年龄从小到大
int num = s1.getAge() - s2.getAge() ;
//次要条件:如果年龄一样,比较姓名的内容是否一样
int num2 = num == 0 ? (s1.getName().compareTo(s2.getName())) : num ;
return num2;
}
}
public static void main(String[] args) {
//创建一个TreeSet集合对象
//TreeSet(Comparator comparatpr):比较器排序
TreeSet ts = new TreeSet(new MyComparator()) ;
//创建几个学生对象
Student s1 = new Student(“kaka”,23);
Student s2 = new Student(“kaka”,21);
Student s3 = new Student(“kaaka”,28);
Student s4 = new Student(“kkkkaka”,26);
Student s5 = new Student(“ka11ka”,24);
Student s6 = new Student(“kakaaa”,23);
Student s7 = new Student(“kaka”,23);
//添加元素
ts.add(s1) ;
ts.add(s2) ;
ts.add(s3) ;
ts.add(s4) ;
ts.add(s5) ;
ts.add(s6) ;
ts.add(s7) ;
//遍历
for(Student s: ts) {
System.out.println(s.getName()+“—”+s.getAge());
}
}
以上代码输出:
kaka—21
kaka—23
kakaaa—23
ka11ka—24
kkkkaka—26
kaaka—28
6.4.2 直接接口的匿名内部类
public static void main(String[] args) {
//直接接口的匿名内部类
TreeSet ts = new TreeSet(new Comparator() {
@Override
public int compare(Student s1, Student s2) {
//s1----->this
//s2---->传进来被比较的对象
//主要条件:按照学生年龄从小到大
int num = s1.getAge() - s2.getAge() ;
//次要条件:如果年龄一样,比较姓名的内容是否一样
int num2 = num == 0 ? (s1.getName().compareTo(s2.getName())) : num ;
return num2;
}
});
//创建几个学生对象
Student s1 = new Student(“kaka”,23);
Student s2 = new Student(“kaka”,21);
Student s3 = new Student(“kaaka”,28);
Student s4 = new Student(“kkkkaka”,26);
Student s5 = new Student(“ka11ka”,24);
Student s6 = new Student(“kakaaa”,23);
Student s7 = new Student(“kaka”,23);
//添加元素
ts.add(s1) ;
ts.add(s2) ;
ts.add(s3) ;
ts.add(s4) ;
ts.add(s5) ;
ts.add(s6) ;
ts.add(s7) ;
//遍历
for(Student s: ts) {
System.out.println(s.getName()+“—”+s.getAge());
}
}
}
以上代码输出:
kaka—21
kaka—23
kakaaa—23
ka11ka—24
kkkkaka—26
kaaka—28
================================================================================
Map集合数据结构<K,V> 键值对存储一对数据;
Map接口的特点:
-
用于存储任意类型的键值对(Key-value)
-
键:无序、无下标、不允许重复(唯一)
-
值:无序、无下标、允许重复
-
针对键有效,跟值无关
Map接口和Collection接口的不同:
- Map是双列的,存储一堆键值对元素,特点针对键有效,键是唯一的可理解为(夫妻对),数据结构值针对键有效跟值无关;
- Collection是单列的 ,只能存储一种引用数据类型,子体系Set是唯一的,理解为光棍,数据结构是针对元素有效;
- V put(K key,V value) :添加一个键值对元素(后面的值会将前面的值覆盖,存储到集合,返回第一次存储的键对应的值)
- V remove(Object key) :删除键,返回键对应的值
- void clear() :暴力删除(删除全部键值对元素)
- boolean containsKey(Object key):判断是否包含指定的键
- boolean containsValue(Object value):判断是否包含指定的值
- boolean isEmpty() :判断Map集合是否为空
- int size() :获取集合的元素数
public static void main(String[] args) {
//创建Map集合对象
Map<String,String> map = new HashMap<String,String>();
//添加一个键值对元素
//后面的值会将前面的值覆盖,存储到集合,返回第一次存储的键对应的值
//第一次添加返回null
System.out.println(map.put(“卡卡”, “涛涛”));//null
System.out.println(map.put(“卡卡”, “牛牛”));//涛涛
System.out.println(map);//{卡卡=牛牛}
//删除键,返回键对应的值
System.out.println(“remove():”+map.remove(“杨过”));
//暴力清除
map.clear();
//判断是否包含指定的键
System.out.println(“containsKey():”+map.containsKey(“卡卡”));//true
System.out.println(“containsKey():”+map.containsKey(“唐唐”));//false
//判断是否包含指定的值
System.out.println(“containsValue():”+map.containsValue(“牛牛”));//true
//判断Map集合是否为空
System.out.println(“isEmpty():”+map.isEmpty());//false
//获取集合的元素数
System.out.println(map.size());//1
System.out.println(map);//{卡卡=牛牛}
}
- V get(Object key):通过键获取值
- Set < K> keySet() :获取所有的键的集合
- Collection< V> values():获取所有的值的集合
- Set<Map.Entry<K,V>> entrySet() :获取的是键值对对象(用于遍历详见7.4.2)
public static void main(String[] args) {
//创建Map集合
Map<String,String> map = new HashMap<String,String>() ;
//添加元素
map.put(“卡卡”, “小卡”) ;
map.put(“牛牛”, “小牛”) ;
map.put(“堂堂”, “小堂”) ;
map.put(“涛涛”, “小涛”) ;
// 获取所有的键的集合
Set set = map.keySet() ;
//增强for
for(String key : set) {
//通过键获取值
String value = map.get(key) ;
System.out.println(key+“=”+value);
}
System.out.println(“-----------------------”);
//获取所有的值的集合
Collection c = map.values() ;
for(String value : c) {
System.out.println(value);
}
}
上述代码输出:
卡卡=小卡
堂堂=小堂
涛涛=小涛
牛牛=小牛
小卡
小堂
小涛
小牛
7.4.1 通过键找值
set< K > keySet() {}
- 获取所有键的集合
- 遍历键的集合,获取到每一个键
- 根据键找值
public static void main(String[] args) {
Map<String,String> map = new HashMap<String,String>();
//添加元素
map.put(“卡卡”, “小卡”) ;
map.put(“牛牛”, “小牛”) ;
map.put(“堂堂”, “小堂”) ;
map.put(“涛涛”, “小涛”) ;
//获取所有的键的集合
Set set = map.keySet() ;
for(String key :set) {
//通过键获取值 V get(Object key)
String value = map.get(key) ;
System.out.println(key+“=”+value);
}
}
7.4.2 根据键值对对象找键和值
public Set<Map.Entry<K,V>> entrySet()
-
Map.Entry<K,V>接口中
-
K getKey():获取键
-
V getValue():获取值
- 获取所有键值对对象的集合
- 遍历键值对对象的集合,获取到每一个键值对对象
- 根据键值对对象找键和值
public static void main(String[] args) {
Map<String,String> map = new HashMap<String,String>() ; //HashMap:哈希表(元素唯一,无序!)
//添加元素
map.put(“卡卡”, “小卡”) ;
map.put(“牛牛”, “小牛”) ;
map.put(“堂堂”, “小堂”) ;
map.put(“涛涛”, “小涛”) ;
//通过map集合获取所有的键值对对象
Set<Map.Entry<String, String>> entrySet = map.entrySet() ;
for(Map.Entry<String, String> entry:entrySet ) {
//通过entry所有的键值对对象
String key = entry.getKey() ;
String value = entry.getValue() ;
System.out.println(key+“=”+value);
}
}
键是哈希表结构,可以保证键的唯一性;可以用null作为key或者value;
HashMap<K,V>:可以存储任意的引用类型数据;
- HashMap< String ,String>
- HashMap < String ,Integer>
- HashMap < String ,Student>
7.5.1 相同类型
public static void main(String[] args) {
//创建一个HashMap集合
HashMap<String, String> map = new HashMap<String,String>() ;
//添加元素
map.put(“卡卡”, “小卡”) ;
map.put(“牛牛”, “小牛”) ;
map.put(“堂堂”, “小堂”) ;
map.put(“涛涛”, “小涛”) ;
//直接遍历
Set set = map.keySet() ;
for(String key :set) {
String value = map.get(key) ;
System.out.println(key+“—”+value);
}
}
7.5.2 不同类型
public static void main(String[] args) {
//创建HashMap集合
HashMap<String, Student> hm = new HashMap<String,Student>() ;
hm.put(“1001”, new Student(“卡卡”,27)) ;
hm.put(“1002”, new Student(“牛牛”,25)) ;
hm.put(“1003”, new Student(“堂堂”,22)) ;
hm.put(“1004”, new Student(“涛涛”,20)) ;
hm.put(“1005”, new Student(“丫丫”,18)) ;
//遍历集合
Set set = hm.keySet() ;
for(String key :set ) {
//通过键获取值
Student s = hm.get(key) ;
System.out.println(key+“—”+s.getName()+“—”+s.getAge());
}
}
7.5.3 自定义类型
如果HashMap键的类型是自定义的,必须重写hashCode()和equals方法()保证元素唯一;
- String:学号
- Key:Student类型:学生信息
/*
- 自定义学生类
*/
public class Student {
private String name ;
private int age ;
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return “Student [name=” + name + “, age=” + 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;
}
@Override
public int 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) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) 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 true;
}
}
public static void main(String[] args) {
//创建一个HashMap集合
HashMap<Student, String> hm = new HashMap<Student,String>() ;
Student s1 = new Student(“卡卡”, 29) ;
Student s2 = new Student(“卡卡”, 25) ;
Student s3 = new Student(“卡卡”, 29) ;
Student s4 = new Student(“涛涛”, 30) ;
Student s5 = new Student(“涛涛”, 31) ;
Student s6 = new Student(“帆帆”, 22) ;
//添加元素
hm.put(s1, “1001”) ;
hm.put(s2, “1002”) ;
hm.put(s3, “1003”) ;
hm.put(s4, “1004”) ;
hm.put(s5, “1005”) ;
hm.put(s6, “1006”) ;
Set set = hm.keySet() ;
for(Student key :set) {
String value = hm.get(key) ;
System.out.println(key.getName()+“—”+key.getAge()+“—”+value);
}
}
需求:键盘录入,获取字符串中每一个字母出现的次数
步骤:
- 创建键盘录入对象,录入字符串内容
- 创建Map集合,TreeMap<Character,Integer>
- 将字符串转换成字符数组
- 遍历字符数组,获取到每一个字符
- 利用Map集合对象通过键获取值 ,判断当前获取的值是否null
* 如果为null,第一次添加,给值默认值1,map集合对象将键和值添加到集合
* 如果不为null,说明键不是第一次添加,值自增,重写map集合键和值添加到集合中
- 创建字符串缓冲区对象StringBuilder
- 遍历TreeMap<Character,Integer>
- 使用字符串缓冲区对象将键和值拼接起来,转换成字符串
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println(“输入内容:”);
String line = sc.next();
//创建Map集合
TreeMap<Character,Integer> tm = new TreeMap<Character,Integer>();
//字符串转化为数组
char[] chs = line.toCharArray();
//遍历数组
for(char ch :chs){
//通过键获取值
Integer i = tm.get(ch);
//判断是否为null
if(i == null){
tm.put(ch, 1);
}else{
i++;
tm.put(ch, i);
}
}
//创建字符串缓冲区对象
StringBuilder sb = new StringBuilder();
Set set = tm.keySet();//Map存到Set
for(Character key :set){
//获取值
Integer value = tm.get(key);
//拼接
sb.append(key).append(“(”).append(value).append(“)”);
}
String result = sb.toString();
System.out.println(result);
}
}
ArrayList集合嵌套HashMap集合 ArrayList<HashMap<String,String>>
public static void main(String[] args) {
//创建一个大集合
ArrayList<HashMap<String,String>> array = new ArrayList<HashMap<String,String>>();
//第一个子集合HashMap<String,String>
HashMap<String,String> hm1 = new HashMap<String,String>();
//添加元素
hm1.put(“卡卡”, “小卡”);
hm1.put(“牛牛”, “小牛”);
//将第一个集合添加到大集合中
array.add(hm1);
//第二个子集合
HashMap<String,String> hm2 = new HashMap<String,String>();
//添加元素
hm2.put(“欧欧”, “小欧”);
hm2.put(“QQ”, “小Q”);
array.add(hm2);
//第三个子集合
HashMap<String,String> hm3 = new HashMap<String,String>();
//添加元素
hm3.put(“发发”, “小发”);
hm3.put(“安安”, “小安”);
array.add(hm3);
for(HashMap<String,String> map : array){
//获取所有键的集合
Set set = map.keySet();
for(String key : set){
//键找值
String value = map.get(key);
System.out.println(“\t” + key +“—” +value);
}
}
}
HashMap集合嵌套ArrayList集合HashMap<String,ArrayList< String >>
- 键:String
- 值:HashMap<String,String>
public static void main(String[] args) {
//创建一个大集合
HashMap<String,ArrayList> hm = new HashMap<String,ArrayList>();
//Key:String类型
//value:ArrayList集合
ArrayList firstArray = new ArrayList();
firstArray.add(“刘备”);
firstArray.add(“曹操”);
//将子集合添加到大集合中
hm.put(“三国演义”, firstArray);
ArrayList secArray = new ArrayList();
secArray.add(“令狐冲”);
secArray.add(“林平之”);
//将子集合添加到大集合中
hm.put(“笑傲江湖”, secArray);
ArrayList thirArray = new ArrayList();
thirArray.add(“宋江”);
thirArray.add(“吴用”);
//将子集合添加到大集合中
hm.put(“水浒传”, thirArray);
//遍历
//获取所有集合
Set set = hm.keySet();
//遍历键
for(String key : set){
System.out.println(key);
//通过键获取值
ArrayList list = hm.get(key);
//遍历ArrayList
for(String value : list){
System.out.println(“\t” + value);
}
}
}
=====================================================================================
集合工具类,针对集合操作的工具类,定义了除了存取以外的集合常用方法。
- public static void sort(List list):针对集合进行默认的自然排序
- public static < T > void sort(List< T > list, Comparator<? super T> c):针对List集合的比较器排序
- public static int binarySearch(List<?> list,T key):集合中查询指定的元素出现的索引值(二分搜索法)
- public static T max(Collection<?> coll):获取集合中的最大值
- public static void reverse(List<?> list):直接集合的数据进行反转
- public static void shuffle(List<?> list):针对集合中元素随机置换
注:折半查找(二分搜索法)---->数组中的元素必须有序的 ,数组的元素是无序的,就不能够直接使用二分搜索法
public static void main(String[] args) {
//创建List集合对象
List list = new ArrayList();
//添加元素
list.add(50);
list.add(30);
list.add(79);
list.add(10);
list.add(49);
System.out.println(list);//[50, 30, 79, 10, 49]
//针对集合进行默认的自然排序
Collections.sort(list);
System.out.println(list);//[10, 30, 49, 50, 79]
//集合中查询指定的元素出现的索引值(二分搜索法)
System.out.println(“index:” + Collections.binarySearch(list, 30));//index:1
//获取集合中的最大值
System.out.println(“max:” + Collections.max(list));//max:79
//集合的数据进行反转
Collections.reverse(list);
System.out.println(list);//[79, 50, 49, 30, 10]
//针对集合中元素随机置换
Collections.shuffle(list);
System.out.println(list);//[30, 50, 79, 10, 49]每次不定是随机生成的
}
public static < T > void sort(List< T > list, Comparator<? super T> c):针对List集合的比较器排序
需求:List集合中存储的是Student类型,按照学生的年龄从小到大排序,,排序的过程还能够保证集合元素唯一
/*
- 学生类
*/
public class Student {
private String name;
private int age;
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String name, int age) {
super();
this.name = name;
this.age = 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;
}
@Override
public String toString() {
return “Student [name=” + name + “, age=” + age + “]”;
}
}
public static void main(String[] args) {
//创建一个List集合
List list = new ArrayList();
//创建学生对象
Student s1 = new Student(“kaka”, 25) ;
Student s2 = new Student(“kaka”, 25) ;
Student s3 = new Student(“zhangsan”, 20) ;
Student s4 = new Student(“lisi”, 20) ;
Student s5 = new Student(“wangwu”, 22) ;
Student s6 = new Student(“zhaoliu”, 30) ;
//添加到list集合中
list.add(s1);
list.add(s2);
list.add(s3);
list.add(s4);
list.add(s5);
list.add(s6);
//对当前学生排序,针对List集合的比较器排序
//list集合是可以重复的
Collections.sort(list, new Comparator() {
@Override
public int compare(Student s1, Student s2) {
//年龄从小到大排:主要条件
int num = s1.getAge() - s2.getAge() ;
//年龄如果一样,不一定是同一个人,比较姓名的内容是否相同
int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) :num ;
return num2 ;
}
});
//遍历集合
for(Student s :list){
System.out.println(s.getName() + “—”+ s.getAge());
}
}
=======================================================================================
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
- public static void sort(List list):针对集合进行默认的自然排序
- public static < T > void sort(List< T > list, Comparator<? super T> c):针对List集合的比较器排序
- public static int binarySearch(List<?> list,T key):集合中查询指定的元素出现的索引值(二分搜索法)
- public static T max(Collection<?> coll):获取集合中的最大值
- public static void reverse(List<?> list):直接集合的数据进行反转
- public static void shuffle(List<?> list):针对集合中元素随机置换
注:折半查找(二分搜索法)---->数组中的元素必须有序的 ,数组的元素是无序的,就不能够直接使用二分搜索法
public static void main(String[] args) {
//创建List集合对象
List list = new ArrayList();
//添加元素
list.add(50);
list.add(30);
list.add(79);
list.add(10);
list.add(49);
System.out.println(list);//[50, 30, 79, 10, 49]
//针对集合进行默认的自然排序
Collections.sort(list);
System.out.println(list);//[10, 30, 49, 50, 79]
//集合中查询指定的元素出现的索引值(二分搜索法)
System.out.println(“index:” + Collections.binarySearch(list, 30));//index:1
//获取集合中的最大值
System.out.println(“max:” + Collections.max(list));//max:79
//集合的数据进行反转
Collections.reverse(list);
System.out.println(list);//[79, 50, 49, 30, 10]
//针对集合中元素随机置换
Collections.shuffle(list);
System.out.println(list);//[30, 50, 79, 10, 49]每次不定是随机生成的
}
public static < T > void sort(List< T > list, Comparator<? super T> c):针对List集合的比较器排序
需求:List集合中存储的是Student类型,按照学生的年龄从小到大排序,,排序的过程还能够保证集合元素唯一
/*
- 学生类
*/
public class Student {
private String name;
private int age;
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String name, int age) {
super();
this.name = name;
this.age = 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;
}
@Override
public String toString() {
return “Student [name=” + name + “, age=” + age + “]”;
}
}
public static void main(String[] args) {
//创建一个List集合
List list = new ArrayList();
//创建学生对象
Student s1 = new Student(“kaka”, 25) ;
Student s2 = new Student(“kaka”, 25) ;
Student s3 = new Student(“zhangsan”, 20) ;
Student s4 = new Student(“lisi”, 20) ;
Student s5 = new Student(“wangwu”, 22) ;
Student s6 = new Student(“zhaoliu”, 30) ;
//添加到list集合中
list.add(s1);
list.add(s2);
list.add(s3);
list.add(s4);
list.add(s5);
list.add(s6);
//对当前学生排序,针对List集合的比较器排序
//list集合是可以重复的
Collections.sort(list, new Comparator() {
@Override
public int compare(Student s1, Student s2) {
//年龄从小到大排:主要条件
int num = s1.getAge() - s2.getAge() ;
//年龄如果一样,不一定是同一个人,比较姓名的内容是否相同
int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) :num ;
return num2 ;
}
});
//遍历集合
for(Student s :list){
System.out.println(s.getName() + “—”+ s.getAge());
}
}
=======================================================================================
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-KpHYcLT8-1715451516773)]
[外链图片转存中…(img-WYbKOA1N-1715451516774)]
[外链图片转存中…(img-fVdLfyJ1-1715451516774)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!