-------
android培训、
java培训、期待与您交流! ----------
数组和集合类有何不同?
数组虽然可以存储对象,但长度是固定的;
集合长度是可变的,数组中可以存储基本数据类型,集合只能存储对象
例子1:
迭代器: 就是集合的取出元素的方式
每一个容器的数据结构不同,取出的细节也是不一样的,但都是有共性内容的
那么这些内部类都符合一个规则,该规则就是Iterator
如何获取集合的去除对象?
通过一个对外提供的方法
iterator();
JDK1.6出现了替代方法:
需求:使用LinkedList模拟一个堆栈或者队列数据结构
集合框架:
为什么会出现那么多容器?
因为每一个容器 对数据的存储方式是不一样的
这个存储方式称之为:数据结构。
因为每一个容器 对数据的存储方式是不一样的
这个存储方式称之为:数据结构。
数组和集合类有何不同?
数组虽然可以存储对象,但长度是固定的;
集合长度是可变的,数组中可以存储基本数据类型,集合只能存储对象
集合类的特点:
集合只用于存储对象,集合长度是可以改变的,集合可以存储不同类型的对象
集合只用于存储对象,集合长度是可以改变的,集合可以存储不同类型的对象
1. add方法的参数类型是Object.与便于接受任意类型对象
2. 集合中存储的都是对象的引用(对象地址)
Conllection
|--List:元素是有序的,元素可以重复,因为该集合体系有索引
|--ArrayList:底层的数据结构使用的是数组结构。 特点:查询速度很快,但是增删稍慢,线程不同步。 1.2版本出现
|--LinkedList:底层使用的是链表结构, 特点:增删速度很快,查询速度稍慢。
|--Vector:底层使用的是数组数据结构。 线程同步。被ArrayList替代了。 1.0版本出现
|--Set:元素是无序的,元素不可以重复
例子1:
public class ConllectionDemo {
/**
* @param args
*/
public static void main(String[] args) {
// base_mentod();
metod02();
}
public static void metod02() {
ArrayList al = new ArrayList();
al.add("java01");
al.add("java02");
al.add("java03");
al.add("java04");
ArrayList al01 = new ArrayList();
al01.add("java03");
al01.add("java04");
al01.add("java05");
al01.add("java06");
///去交集,al01中只会保留和al02中相同的元素。
// al.retainAll(al01);
print(al);
//al去掉与al01中相同的元素,保留剩下的元素
al.removeAll(al01);
print(al);
}
public static void base_mentod() {
// 创意一个容器,使用Conllection接口的子类ArryList类进行创建
ArrayList al = new ArrayList();
// 1.添加元素
al.add("java01");
al.add("java02");
al.add("java03");
al.add("java04");
// 打印集合
print(al);
// 2.判断元素是否存在
print("java02时候存在:" + al.contains("java02"));
print("集合是否为空:" + al.isEmpty());
// 3.获取元素个数,集合长度
print("size:" + al.size());
// 4.删除元素
al.remove("java02");
// 5.清空集合
al.clear();
print(al);
}
// 打印
public static void print(Object obj) {
System.out.println(obj);
}
}
List :
特有方法:方式可以操作的角标的方法都是该体系特有的方法
特有方法:方式可以操作的角标的方法都是该体系特有的方法
增
add(index,element); 添加一个元素
addAll(index,Conllection); 添加一个集合
add(index,element); 添加一个元素
addAll(index,Conllection); 添加一个集合
删
removed(index);
removed(index);
改
set(index,element);
set(index,element);
查
get(index);
subList(from, to);
listIterator();
List集合特有的迭代器。 ListIterator是Iterator的子接口。
在迭代时,不可以通过集合对象的方法操作集合中的元素。
因为会发生ConcurrentModificationException异常
所以,在迭代器时,只能用迭代器的方法操作元素,可是Iterator方法是有限的
只能对元素进行判断,取出,删除的操作
如果想要其他的操作如添加、修改等,就需要使用其子接口,ListIterator
get(index);
subList(from, to);
listIterator();
List集合特有的迭代器。 ListIterator是Iterator的子接口。
在迭代时,不可以通过集合对象的方法操作集合中的元素。
因为会发生ConcurrentModificationException异常
所以,在迭代器时,只能用迭代器的方法操作元素,可是Iterator方法是有限的
只能对元素进行判断,取出,删除的操作
如果想要其他的操作如添加、修改等,就需要使用其子接口,ListIterator
该接口只能通过List集合的listIterator方法获取(因为List集合有下标,这方法是唯一的)
ListIterator常见方法:
add(E e) 将指定的元素插入列表
set(E e) 用指定元素替换 next 或 previous 返回的最后一个元素
hasNext() 以正向遍历列表时,如果列表迭代器有多个元素,则返回 true(换句话说,如果 next 返回一个元素而不是抛出异常,则返回 true)。
next() 返回列表中的下一个元素。
hasPrevious() 如果以逆向遍历列表,列表迭代器有多个元素,则返回 true。
previous() 返回列表中的前一个元素。
例子2:
add(E e) 将指定的元素插入列表
set(E e) 用指定元素替换 next 或 previous 返回的最后一个元素
hasNext() 以正向遍历列表时,如果列表迭代器有多个元素,则返回 true(换句话说,如果 next 返回一个元素而不是抛出异常,则返回 true)。
next() 返回列表中的下一个元素。
hasPrevious() 如果以逆向遍历列表,列表迭代器有多个元素,则返回 true。
previous() 返回列表中的前一个元素。
例子2:
public class ListDemo {
public static void main(String[] args) {
// 创建一个容器
ArrayList list = new ArrayList();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
//使用ListIterator在迭代过程中,可以进行对元素集合的操作
ListIterator it = list.listIterator();
System.out.println(list);
//从头部来时遍历
while(it.hasNext()){
Object obj = it.next();
if(obj.equals("2")){
// it.add("5"); //可以在ListIterator迭代过程中对元素进行操作
// it.remove();
// it.set("5"); //替换
}
}
System.out.println(list);
System.out.println("List hasPrevicous"+it.hasPrevious());
//从尾部开始进行遍历
while(it.hasPrevious()){
System.out.println(it.previous());
}
}
public static void method(){
// 创建一个容器
ArrayList list = new ArrayList();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
// 创建一个新的容器
ArrayList list_1 = new ArrayList();
list_1.add("5");
list_1.add("6");
// 将集合list_1添加到list中
list.add(4, list_1);
// 查
Iterator ite = list.iterator();
while (ite.hasNext()) {
System.out.println("list:" + ite.next());
}
//改
list.set(0, "***");
System.out.println("修改后:"+list);
//删除
list.remove(0);
System.out.println("删除第一个下标:"+list);
}
}
例子3:
需求:去除ArrayList集合中重复的元素
public class ArrayListTest {
/**
* @param args
*/
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add("1");
list.add("2");
list.add("1");
list.add("3");
list.add("2");
list.add("4");
System.out.println(list);
//去除重复元素之后
list = singleElement(list);
System.out.println(list);
}
public static ArrayList singleElement(ArrayList list){
ArrayList temp = new ArrayList();
Iterator it = list.iterator();
while(it.hasNext()){
Object obj= it.next();
if(!temp.contains(obj))
temp.add(obj);
}
return temp;
}
}
例子4:
将自定义对象作为元素存放在ArrayList集合中, 并去除重复的元素
将自定义对象作为元素存放在ArrayList集合中, 并去除重复的元素
比如: 存人对象,同性名同年龄,视为同一个人能,为重复元素
思路:
对人描述,将数据封装到人对象中
定义容器,将人存入
取出
对人描述,将数据封装到人对象中
定义容器,将人存入
取出
class Person {
private String name;
private int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Person))
return false;
Person person = (Person) obj;
return this.name.equals(person.name) && this.age == person.age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
public class ArrayListTest1 {
public static void main(String[] args) {
ArrayList<Person> list = new ArrayList<Person>();
list.add(new Person("李四01", 20));
list.add(new Person("李四02", 22));
list.add(new Person("李四03", 23));
list.add(new Person("李四02", 22));
list.add(new Person("李四02", 22));
list.add(new Person("李四04", 24));
list = singleElement(list);
Iterator it = list.iterator();
while(it.hasNext()){
Person p = (Person) it.next();
print(p.getName()+"---"+p.getAge());
}
}
public static ArrayList singleElement(ArrayList list) {
ArrayList temp = new ArrayList();
Iterator it = list.iterator();
while (it.hasNext()) {
Object obj = it.next();
if (!temp.contains(obj)) //这里的contains依赖Object中的equals方法
temp.add(obj);
}
return temp;
}
public static void print(Object obj){
System.out.println(obj);
}
}
迭代器: 就是集合的取出元素的方式
每一个容器的数据结构不同,取出的细节也是不一样的,但都是有共性内容的
那么这些内部类都符合一个规则,该规则就是Iterator
如何获取集合的去除对象?
通过一个对外提供的方法
iterator();
public class IteratorDemo {
public static void main(String[] args) {
//创建一个容器
ArrayList list = new ArrayList();
list.add("java01");
list.add("java02");
list.add("java03");
list.add("java04");
// 第一中方式:
// Iterator ite = list.iterator(); //获取迭代器
// while(ite.hasNext())
// System.out.println(ite.next());
// 第二种方式:国外流行是用,比较减少资源消耗
for(Iterator ite = list.iterator(); ite.hasNext();)
System.out.println(ite.next());
}
}
LinkedList特有方法: (它都会集成List接口的所有方法,我们这里不在说,只介绍一下它特有的方法)
addFirst();
addLast();
addLast();
getFirst();
getLast();
获取元素,但不删除元素。 如果集合中没有元素,会穿线NoSuchElementException异常
getLast();
获取元素,但不删除元素。 如果集合中没有元素,会穿线NoSuchElementException异常
removeFirst();
removeLast();
获取元素,但是元素被删除。 如果集合中没有元素,会穿线NoSuchElementException异常
removeLast();
获取元素,但是元素被删除。 如果集合中没有元素,会穿线NoSuchElementException异常
JDK1.6出现了替代方法:
offerFirst();
offerLast();
offerLast();
peekFirst();
peekLast();
获取元素,但不删除元素。 如果集合中没有元素,会返回nul
peekLast();
获取元素,但不删除元素。 如果集合中没有元素,会返回nul
pollFirst();
pollLast();
获取元素,但是元素被删除。 如果集合中没有元素,会返回nul
pollLast();
获取元素,但是元素被删除。 如果集合中没有元素,会返回nul
public class LinkedListDemo {
public static void main(String[] args) {
LinkedList link = new LinkedList();
//从第一位添加
// link.addFirst("1");
// link.addFirst("2");
// link.addFirst("3");
// link.addFirst("4");
print(link);
// print(link.getFirst()); //当集合没有元素时,这个方法会抛出异常
print(link.pollFirst()); //删除
// print(link.getLast());
print(link.pollLast());
// print(link.removeFirst()); //获取并删除元素 当集合没有元素时,这个方法会抛出异常
print(link.peekFirst()); //获取
print(link.peekLast());
LinkedList link1 = new LinkedList();
//从最后以为添加
link1.addLast("5");
link1.addLast("6");
link1.addLast("7");
link1.addLast("8");
print(link1);
// print(link1.getFirst());
// print(link1.getLast());
//遍历
while(!link1.isEmpty()){
print(link1.removeFirst());
}
}
public static void print(Object obj){
System.out.println(obj);
}
}
需求:使用LinkedList模拟一个堆栈或者队列数据结构
堆栈:先进后出
队列:先进先出 (FIFO)
枚举就是Vector特有的取出方式(线程安全,但效率不高)
发现枚举和迭代器很像
其实枚举和迭代器是一样的(可以查文档看看)
需求: 将自定义对象作为元素存放在HashSet集合中, 并去除重复的元素
实现
队列:先进先出 (FIFO)
//队列类
class Queue{
private LinkedList link;
Queue(){
link = new LinkedList();
}
public void add(Object obj){
link.addFirst(obj);
}
public Object get(){
return link.removeLast();
}
public boolean isNull(){
return link.isEmpty();
}
}
public class LinkedListTest {
public static void main(String[] args) {
Queue que = new Queue();
que.add("1");
que.add("2");
que.add("3");
que.add("4");
while(!que.isNull()){
System.out.println(que.get());
}
}
}
枚举就是Vector特有的取出方式(线程安全,但效率不高)
发现枚举和迭代器很像
其实枚举和迭代器是一样的(可以查文档看看)
因为枚举的名称以及方法的名称都过长。
所以被迭代器取代了
所以被迭代器取代了
public class VectorDemo {
public static void main(String[] args) {
//使用Vector创建一个新的容器
Vector vec = new Vector();
vec.add("1");
vec.add("2");
vec.add("3");
vec.add("4");
Enumeration enu = vec.elements();
while(enu.hasMoreElements()){
System.out.println( enu.nextElement());
}
}
}
Set:元素是无序的(存入和取出的顺序不一定一致) 元素不可以重复
|---HashSet:顶层数据结构是哈希表。
|--hashSet是如何保证元素唯一性的呢?
是通过元素的两个方法,hashCode和equals来完成。
如果元素的HashConde值相同,才会判断equals是否为true
如果元素的HashConde值不同,不会调 用equals.
注意:对于判断元素是否存在,以及删除等操作,(依赖的方法是元素的hashCode和equals方法)
|---TreeSet:
|--hashSet是如何保证元素唯一性的呢?
是通过元素的两个方法,hashCode和equals来完成。
如果元素的HashConde值相同,才会判断equals是否为true
如果元素的HashConde值不同,不会调 用equals.
注意:对于判断元素是否存在,以及删除等操作,(依赖的方法是元素的hashCode和equals方法)
|---TreeSet:
Set集合的功能和Collection是一致的
例子:
例子:
public class HashSetDemo {
public static void main(String[] args) {
HashSet hs = new HashSet();
// HashSet集合是没有重复元素的
hs.add("1"); // 方法返回的是boolean true
hs.add("1"); // false 重复添加的元素都无false的
hs.add("2"); // true
hs.add("3");// true
hs.add("3");// false
hs.add("4");// true
Iterator it = hs.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
需求: 将自定义对象作为元素存放在HashSet集合中, 并去除重复的元素
实现
public class HashSetTest {
public static void main(String[] args) {
HashSet hash = new HashSet();
hash.add(new Student("lisi01", 21));
hash.add(new Student("lisi01", 21));
hash.add(new Student("lisi02", 22));
hash.add(new Student("lisi03", 23));
hash.contains(new Student("lisi01", 21));//true 判断集合中是否有这一元素,依赖该元素的hashCode和equals方法
hash.remove(new Student("lisi01", 21)); // 删除也依赖该元素的hashCode和equals方法
Iterator it = hash.iterator();
while (it.hasNext()) {
Student p = (Student) it.next();
System.out.println(p.getName() + ":" + p.getAge());
}
}
}
class Student {
private String name;
private int age;
Student(String name, int age) {
this.name = name;
this.age = age;
}
public int hashCode() {
return name.hashCode() + age * 37; // 这是为了让哈希表唯一(必须的*重点)
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Student))
return false;
Student person = (Student) obj;
return this.name.equals(person.name) && this.age == person.age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
TreeSet:可以对Set集合中的元素进行排序
底层数据结构是二叉树。
保证元素唯一性的依据:compareTo方法return 0.
TreeSet排序的第一种方式:让元素自身具备比较性。
元素需要实现Comparable接口,覆盖compareTo方法
这种方式也成为元素的自然排序,或者叫做默认排序
TreeSet的第二种排序方式:
当元素自身不具备比较性是,或者具备比较性不是所需要的。
这是就需要让集合自身具备比较性
在集合初始化时,就有了比较方式;(创建一个类,实现Comparator比较器,复写compareTo方法,将该类放到TreeSet的构造函数中)
底层数据结构是二叉树。
保证元素唯一性的依据:compareTo方法return 0.
TreeSet排序的第一种方式:让元素自身具备比较性。
元素需要实现Comparable接口,覆盖compareTo方法
这种方式也成为元素的自然排序,或者叫做默认排序
TreeSet的第二种排序方式:
当元素自身不具备比较性是,或者具备比较性不是所需要的。
这是就需要让集合自身具备比较性
在集合初始化时,就有了比较方式;(创建一个类,实现Comparator比较器,复写compareTo方法,将该类放到TreeSet的构造函数中)
需求:
往TreeSet集合中存储自定义对象人
想按照人的年龄进行排序
往TreeSet集合中存储自定义对象人
想按照人的年龄进行排序
记住,排序是,当主要条件相同时,一定判断一下次要条件
例子1:
例子1:
public class TreeSetTest {
public static void main(String[] args) {
TreeSet tree = new TreeSet();
tree.add(new People("lisi001",21));
tree.add(new People("lisi001",21)); //去掉重复对象
tree.add(new People("lisi002",22));
tree.add(new People("lisi005",22)); //当年龄相同时,判断姓名进行排序
tree.add(new People("lisi003",23));
tree.add(new People("lisi004",24));
Iterator it = tree.iterator();
while(it.hasNext()){
People p = (People) it.next();
System.out.println(p.getName()+"_____"+p.getAge());
}
}
}
class People implements Comparable{ //一定要实现Comparable接口,为TreeSet排序时使用到 (重点)
private String name;
private int age;
People(String name ,int age){
this.name = name;
this.age = age;
}
@Override
public int compareTo(Object obj) {
if(!(obj instanceof People))
throw new RuntimeException("不是People类对象");
People p = (People) obj;
if(this.age > p.age)
return 1;
if(this.age == p.age){
return this.name.compareTo(p.name); //当年龄相同时,还用对姓名进行排序,String类应实现了Comparable接口
}
return -1;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
当元素自身不具备比较性,或者具备的比较性不是所需要的
这时需要让容器自身具备比较性
定义了比较器,将比较器对象作为参观传递给TreeSet集合的构造函数
定义了比较器,将比较器对象作为参观传递给TreeSet集合的构造函数
当两种排序都存在时,以比较器为主
定义一个类,实现Comparator接口,覆盖compareTo方法
例子2:
例子2:
public class TreeSetTest01 {
public static void main(String[] args) {
TreeSet tree = new TreeSet(new MyComparator()); //使用构造函数进行排序
tree.add(new People01("lisi001", 21));
tree.add(new People01("lisi001", 21)); // 去掉重复对象
tree.add(new People01("lisi002", 22));
tree.add(new People01("lisi005", 22)); // 当年龄相同时,判断姓名进行排序
tree.add(new People01("lisi003", 23));
tree.add(new People01("lisi004", 24));
Iterator it = tree.iterator();
while (it.hasNext()) {
People01 p = (People01) it.next();
System.out.println(p.getName() + "_____" + p.getAge());
}
}
}
class MyComparator implements Comparator{
@Override
public int compare(Object o1, Object o2) {
People01 p1 = (People01) o1;
People01 p2 = (People01) o2;
int num = p1.getName().compareTo(p2.getName());
//姓名相同
if(num == 0){
//当姓名相同时,比较年龄
return new Integer(p1.getAge()).compareTo(new Integer(p2.getAge()));
}
return num;
}
}
class People01 {//implements Comparable { // 一定要实现Comparable接口,为TreeSet排序时使用到 (重点)
private String name;
private int age;
People01(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
练习:按照字符串长度排序。
字符串本书具备比较性,但是它的比较方式不是锁所需要的
我们只能使用比较器
例子3:
例子3:
public class TreeSetTest02 {
public static void main(String[] args) {
TreeSet ts = new TreeSet(new Comparator(){
@Override
public int compare(Object o1, Object o2) {
String s1 = (String) o1;
String s2 = (String) o2;
int num = new Integer(s1.length()).compareTo(s2.length());
if(num == 0){
return s1.compareTo(s2);
}
return num;
}
});
ts.add("t");
ts.add("ac");
ts.add("zcf");
ts.add("acdr");
ts.add("acf");
ts.add("dddd");
Iterator it = ts.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}