Collection单列集合复习

集合

 

(Map中还有LinkedHashMap和TreeMap(二叉树存储))

Collection集合的遍历

1.集合转换成数组,然后再对数组进行遍历

Object[]

toArray()

返回一个包含此集合中所有元素的数组。

Object[] toArray();

2.获取迭代器、当于一个爪子

Iterator<E>

iterator()

返回此集合中的元素的迭代器。

boolean

hasNext()

如果迭代具有更多元素,则返回 true 。

E

next()

返回迭代中的下一个元素。

hesNext:判断是否有下一个元素

next:获取下一个元素,还会移动迭代器的位置

3.高级for循环(底层实现就是迭代器)

 

Collection集合三种通用遍历方式实例:

import java.util.ArrayList;

import java.util.Collection;

import java.util.Iterator;

 

public class Test02 {

 

public static void main(String[] args) {

Collection<Student> coll = new ArrayList<Student>();

//Collection是接口,不能创建对象,所以只能创建子类对象(多态)

Student s1 = new Student("熊落落",21);

Student s2 = new Student("杨梦梦",22);

Student s3 = new Student("李鹏鹏",25);

Student s4 = new Student("崔美娟",23);

Student s5 = new Student("孙二娜",22);

Student s6 = new Student("红果果",21);

coll.add(s1);coll.add(s2);

coll.add(s3);coll.add(s4);

coll.add(s5);coll.add(s6);

 

System.out.println("******第一种遍历方式******");

//单列集合通用的第一种遍历方式(调用toArray()方法,转为数组,然后遍历)

Object[] objs = coll.toArray();//注意单列集合的这个toArray()方法返回值是一个Object类型的数组

for(Object obj : objs) {

/*String string = obj.toString();

System.out.println(string);

多态(父类的引用指向子类的对象)中的成员方法的访问特点

1.编译看左边,运行看右边

2.编译的时候,要看父类中是否存在该方法,如果存在,编译通过,否则编译报错。

3.运行的时候,要运行子类的重写的方法,如果没有重写的方法,执行父类的方法。*/

Student stu = (Student)obj;

/*不强转为子类对象的引用stu时,obj只能调用两者共有的方法中的子类对象的方法而不能调用Student类中特有的方法.

这其实是多态的访问特点,好好学习吧!学完就忘,像个憨憨,丢人不*/

System.out.println(stu);

}

System.out.println("******第一种遍历方式******");

 

System.out.println();

 

System.out.println("******第二种遍历方式******");

//单列集合通用的第二种遍历方式(采用Iterator迭代器进行遍历)

Iterator<Student> it = coll.iterator();//使用泛型,声明迭代器类型

//Iterator迭代器是个接口,不能直接创建对象,但可以通过集合调用iterator()方法创建对象

while(it.hasNext()) {//如果集合中还有元素

System.out.println(it.next());//获取集合中下一个元素

}

System.out.println("******第二种遍历方式******");

 

System.out.println();

 

System.out.println("******第三种遍历方式******");

//单列集合通过的第三种遍历方式(采用高级for循环进行遍历)

for(Student stu : coll) {//由于前面声明了泛型,这里遍历就省去了很多麻烦

System.out.println(stu);

}

System.out.println("******第三种遍历方式******");

}

 

}

 

class Student{

private String name;

private int age;

public Student() {}

public Student(String name,int age) {

this.name = name;

this.age = age;

}

public void setName(String name) {

this.name = name;

}

public String getName() {

return name;

}

public void setAge(int age) {

this.age = age;

}

public int getAge() {

return age;

}

public String toString() {//由于在打印对象名的时候,虚拟机会自动调用toString方法,打印对象地址

//所以可以重写toString()方法,打印出我们希望看到的结果!注意:这个方法的返回类型是String类型!

//调用是虚拟机自动完成的!

return "name = " + name + ",age = " + age;

}

 

}

List集合中特有的遍历方式实例:

(使用size(),get()等方法进行遍历

import java.util.ArrayList;

import java.util.List;

//List集合中特有的遍历(使用size(),get()等方法进行遍历)

public class Test03 {

public static void main(String[] args) {

/*List list = new ArrayList();

list.add(0, 3);

list.add(0, 4);

System.out.println(list);

list.remove(0);

System.out.println(list);

list.set(0, 6);

System.out.println(list);

System.out.println(list.get(0));*/

 

List list = new ArrayList();

list.add("我和我的祖国");

list.add("一刻也不能分割");

list.add("只愿天长地久");

list.add("与我意中人儿紧相随");

list.add(123);

list.add(456);

 

for(int n = 0;n < list.size();n++) {

System.out.println(list.get(n));

}

 

}

 

}

并发修改异常

java.util.ConcurrentModificationException

原因:在使用迭代器操作集合时,集合本身也在操作集合,所以出现并发修改的异常。

解决方式:要么集合本身在操作集合,要么迭代器在操作集合。

Vector:

public class Test04 {

 

public static void main(String[] args) {

Vector vector = new Vector();

vector.addElement("abc");

vector.addElement("bbb");

vector.addElement("ccc");

vector.addElement("ddd");

System.out.println(vector);

System.out.println(vector.removeElement("abc"));

System.out.println(vector);

//遍历 枚举器

Enumeration elements = vector.elements();

while(elements.hasMoreElements()) {

System.out.println(elements.nextElement());

}

}

 

}

枚举器中的两个方法

boolean

hasMoreElements() 

测试此枚举是否包含更多元素。

E

nextElement() 

如果此枚举对象至少有一个要提供的元素,则返回此枚举的下一个元素。

LinkedList练习一:

import java.util.LinkedList;

 

public class LinkedList01 {

 

public static void main(String[] args) {

LinkedList ll = new LinkedList();

ll.addFirst("abc");

ll.addFirst("aaa");

ll.addLast("ccc");

System.out.println(ll);

//[aaa, abc, ccc]

Object obj = ll.removeLast();

System.out.println(obj);

//ccc

System.out.println(ll);

//[aaa, abc]

System.out.println(ll.getFirst());

//aaa

 

}

 

}

LinkedList练习二:

模拟栈和队列的操作

import java.util.LinkedList;

 

/*4.模拟栈和队列的操作(LinkedList)

栈:先进后出 自定义异常抛出

队列:先进先出*/

public class Test02LinkedList {

 

public static void main(String[] args) throws Exception {

MyStack<String> ms = new MyStack<String>();

ms.push("123");

ms.push("我爱你,祖国!");

ms.push("wakaka");

System.out.println(ms);

System.out.println(ms.pop());

System.out.println(ms.pop());

System.out.println(ms.pop());

System.out.println(ms.pop());

}

}

 

class MyStack<E>{//栈本身就是一种操作受限的链表

LinkedList<E> linkedList = new LinkedList<E>();

public MyStack() {}

public void push(E e) {

linkedList.addLast(e);//进栈,加元素

}

public E pop() throws Exception {

if(isEmpty()) {

throw new MyStackEmptyException("感觉身体被掏空!");

}

return linkedList.removeLast();//这里出栈应该用移除来代替

}

public boolean isEmpty() {

return linkedList.isEmpty();

}

}

 

class MyStackEmptyException extends Exception{

public MyStackEmptyException(String str) {

super(str);

}

}

 

Set:元素无序,不重复

练习一:

随机生成10个20-40之间的(不重复的)随机数,存储在合适的集合中,并且进行遍历

/*6.练习

随机生成10个20-40之间的(不重复的)随机数,存储在合适的集合中,并且进行遍历*/

public class Test01Set {

 

public static void main(String[] args) {

Random r = new Random();

Set<Integer> set = new HashSet<Integer>();

while(set.size()<10) {

int num = r.nextInt(21)+20;

set.add(num);

}

for(Integer n : set) {

System.out.println(n);

}

 

}

 

}

练习二:

键盘录入一个字符串,输出其中的字符,相同的字符只输出一次。

import java.util.HashSet;

import java.util.Scanner;

import java.util.Set;

 

/*2.键盘录入一个字符串,输出其中的字符,相同的字符只输出一次。*/

public class Test02Set {

 

public static void main(String[] args) {

Scanner sc = new Scanner(System.in);

System.out.println("请录入一个字符串:");

String line = sc.nextLine();

char[] chs = line.toCharArray();

Set<Character> set = new HashSet<Character>();

for(int n = 0;n < chs.length;n++) {

char c = chs[n];

set.add(c);

}

for(Character c : set) {

System.out.println(c);

}

 

}

 

}

HashSet

哈希表,HashSet保证了元素的唯一性,值相同的元素都去掉。

HashSet存储自定义类型的元素

如何保证元素唯一呢?

hashCode()

   |--哈希值相同:再进去比较equals()

|--equals值返回为true:认为是重复元素,不进行存储

       |--equals值返回为false:认为不是重复元素,进行存储

   |--哈希值不相同:直接进行存储

HashSet保证自定元素唯一性的实例:

import java.util.HashSet;

import java.util.Iterator;

import java.util.Objects;

 

//测试HashSet如何保证自定义元素唯一

public class Test01HashSet {

 

public static void main(String[] args) {

HashSet hs = new HashSet();

hs.add(new Student("熊落落",21));

hs.add(new Student("杨梦梦",22));

hs.add(new Student("李鹏鹏",25));

hs.add(new Student("孙二娜",24));

hs.add(new Student("熊落落",23));

hs.add(new Student("熊落落",21));

 

Iterator it = hs.iterator();

while(it.hasNext()) {

Student stu = (Student)it.next();

System.out.println(stu);

}

/*输出结果:

29015722

26296872

26711470

23119401

29015722

29015722

name = 熊落落,age = 21

name = 熊落落,age = 23

name = 杨梦梦,age = 22

name = 李鹏鹏,age = 25

name = 孙二娜,age = 24

根据定义的规则,线比较对象name的哈希码值,如果不一致,直接存储,

如果一致,再去比较姓名和年龄的值是否一样,不一致,存储.一致,不存储.

 */

 

}

 

}

 

class Student{

private String name;

private int age;

public Student() {}

public Student(String name,int age) {

this.name = name;

this.age = age;

}

public void setName(String name) {

this.name = name;

}

public String getName() {

return name;

}

public void setAge(int age) {

this.age = age;

}

public int getAge() {

return age;

}

public String toString() {//由于在打印对象名的时候,虚拟机会自动调用toString方法,打印对象地址

//所以可以重写toString()方法,打印出我们希望看到的结果!注意:这个方法的返回类型是String类型!

//调用是虚拟机自动完成的!

return "name = " + name + ",age = " + age;

}

public int hashCode() {

/*Objects.hash()与Objects.hashCode()

 * static int hash(Object... values)

为(多个)输入值序列生成哈希码,最好不要输入单个(返回的可能不是哈希码值);

static int hashCode(Object o)

返回单个输入值的哈希码值 */

 

/*System.out.println(Objects.hashCode(age));

return Objects.hashCode(age);*///如果年龄的哈希值一样(int类型的哈希码值就是它本身,没什么意义

 

System.out.println(Objects.hashCode(name));

return name.hashCode();//字符串是引用数据类型,可直接调用hashCode()方法

}

public boolean equals(Object obj) {//注意,它的返回值是boolean类型

Student stu = (Student)obj;

return name.equals(stu.name)&&age==stu.age;//认真,别写错了

//比较姓名和年龄是否一样

}

}

 

TreeSet:

也是一个Set子类,也可以保证元素的唯一,底层结构是二叉树。

既可以保证元素唯一,也可能进行自动排序

TreeSet可以保证元素唯一,也可以自动排序。

|--使元素本身具有比较性,自定义类实现Comparable接口,重写comparTo()方法

|--使集合本身具有比较性,自定义比较器实现Comparator接口,重写compare()方法

如果两者同时存在呢???

使用集合本身的比较性,元素本身的比较效失效!!

TreeSet集合保证自定义元素唯一的两种方式

TreeSet集合保证自定义对象唯一的实例一():

自定义类实现一个Comparable接口,重写compareTo()

返回值:正整数、零、负整数

题目:如果本书书名价格一致认为同一本书,不进行存储

按照书名进行升序排序,如果书名相同,按照价格降序排序(用TreeSet存储)

import java.util.Iterator;

import java.util.TreeSet;

 

/*题目:如果本书的书名和价格一致认为同一本书,不进行存储

按照书名进行升序排序,如果书名相同,按照价格降序排序(用TreeSet存储)*/

public class Test01TreeSet {

 

public static void main(String[] args) {

TreeSet ts = new TreeSet();

Book b1 = new Book("活着",25);

Book b2 = new Book("果宝",21);

Book b3 = new Book("王者",22);

Book b4 = new Book("活着",23);

Book b5 = new Book("活着",25);

ts.add(b1);ts.add(b2);

ts.add(b3);ts.add(b4);

ts.add(b5);

Iterator it = ts.iterator();

while(it.hasNext()) {

Book b = (Book)it.next();

System.out.println(b);

}

 

}

 

}

 

class Book implements Comparable{

String bookName;

double bookPrice;

public Book() {

super();

// TODO Auto-generated constructor stub

}

 

public Book(String bookName, double bookPrice) {

super();

this.bookName = bookName;

this.bookPrice = bookPrice;

}

 

public String getBookName() {

return bookName;

}

public void setBookName(String bookName) {

this.bookName = bookName;

}

public double getBookPrice() {

return bookPrice;

}

public void setBookPrice(double bookPrice) {

this.bookPrice = bookPrice;

}

@Override

public String toString() {

return "Book [bookName=" + bookName + ", bookPrice=" + bookPrice + "]";

}

/*题目:如果本书的书名和价格一致认为同一本书,不进行存储

按照书名进行升序排序,如果书名相同,按照价格降序排序(用TreeSet存储)*/

public int compareTo(Object obj) {

Book b = (Book)obj;

int result = bookName.compareTo(b.getBookName());

if(result==0) {//如果书名一致,判断价格

return -(new Double(bookPrice).compareTo(new Double(b.getBookPrice())));

//降序  Double也继承了Compareble类,重写了compareTo方法,所以可以这么写

}else if(result > 0) {

return 1;//名字升序

}

return -1;

}

}

运行结果:

Book [bookName=果宝, bookPrice=21.0]

Book [bookName=活着, bookPrice=25.0]

Book [bookName=活着, bookPrice=23.0]

Book [bookName=王者, bookPrice=22.0]

 

TreeSet集合保证自定义对象唯一的实例二():

TreeSet集合本身具有比较性,在创建集合对象时添加一个比较器,自定义比较器实现Comparator,重写compare方法,使添加的元素按照集合本身的比较规则去进行添加

题目:如果本书书名价格一致认为同一本书,不进行存储

按照书名进行降序排序,如果书名相同,按照价格升序排序(用TreeSet存储)

import java.util.Comparator;

import java.util.Iterator;

import java.util.TreeSet;

 

/*题目:如果本书的书名和价格一致认为同一本书,不进行存储

按照书名进行降序排序,如果书名相同,按照价格升排序(用TreeSet存储)*/

public class Test02TreeSet {

 

public static void main(String[] args) {

TreeSet ts = new TreeSet(new Comparator() {

public int compare(Object o1,Object o2) {

Book b1 = (Book)o1;

Book b2 = (Book)o2;

int result = b1.getBookName().compareTo(b2.getBookName());

if(result==0) {

return new Double(b1.getBookPrice()).compareTo(new Double(b2.getBookPrice()));

}else if(result >  0) {

return -1;

}

return 1;

}

});

Book b1 = new Book("活着",25);

Book b2 = new Book("果宝",21);

Book b3 = new Book("王者",22);

Book b4 = new Book("活着",23);

Book b5 = new Book("活着",25);

ts.add(b1);ts.add(b2);

ts.add(b3);ts.add(b4);

ts.add(b5);

Iterator it = ts.iterator();

while(it.hasNext()) {

Book b = (Book)it.next();

System.out.println(b);

}

 

}

 

}

class Book implements Comparable{

String bookName;

double bookPrice;

public Book() {

super();

// TODO Auto-generated constructor stub

}

 

public Book(String bookName, double bookPrice) {

super();

this.bookName = bookName;

this.bookPrice = bookPrice;

}

 

public String getBookName() {

return bookName;

}

public void setBookName(String bookName) {

this.bookName = bookName;

}

public double getBookPrice() {

return bookPrice;

}

public void setBookPrice(double bookPrice) {

this.bookPrice = bookPrice;

}

@Override

public String toString() {

return "Book [bookName=" + bookName + ", bookPrice=" + bookPrice + "]";

}

/*题目:如果本书的书名和价格一致认为同一本书,不进行存储

按照书名进行升序排序,如果书名相同,按照价格降序排序(用TreeSet存储)*/

public int compareTo(Object obj) {

Book b = (Book)obj;

int result = bookName.compareTo(b.getBookName());

if(result==0) {//如果书名一致,判断价格

return -(new Double(bookPrice).compareTo(new Double(b.getBookPrice())));

//降序  Double也继承了Compareble类,重写了compareTo方法,所以可以这么写

}else if(result > 0) {

return 1;//名字升序

}

return -1;

}

}

运行结果:

Book [bookName=王者, bookPrice=22.0]

Book [bookName=活着, bookPrice=23.0]

Book [bookName=活着, bookPrice=25.0]

Book [bookName=果宝, bookPrice=21.0]

可见,当两者同时存在时,TreeSet会按照Comparator定义的规则去存储,排序

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值