复习java基础第三天(集合)

一、Collection常用的方法:

Java 集合可分为 Set、List 和 Map 三种体系:

Set:无序、不可重复的集合。

List:有序,可重复的集合。

Map:具有映射关系的集合。

Collection 接口是 List、Set 和 Queue 接口的父接口,

该接口里定义的方法既可用于操作 Set 集合,也可用于操作 List 和 Queue 集合:

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;

public class TestCollections {

public static void main(String[] args) {

//1. 创建一个 Collection 接口的对象.
Collection collection = new ArrayList();

//2. Collection 重要方法说明:
/**
* 2.1 用于添加元素的:
* add()
* addAll()
*/
Person p1 = new Person();
collection.add(p1);
collection.add(new Person());

Collection collection2 = new ArrayList();
collection2.add(new Person());
collection2.add(new Person());

collection.addAll(collection2);

System.out.println(collection.size());

/**
* 2.2 用于访问集合的方法:
* 获取集合的长度: size()
* 对集合进行遍历的方法: iterator() 可以得到对应的 Iterator 接口对象.
*
* Iterator: 迭代器
* ①. 获取 Iterator 接口对象:
* ②. 使用 while 循环和 Iterator 对象遍历集合中的每一个元素. 具体使用 Iterator 接口的
* hasNext() 和 next() 方法.
*/
Iterator iterator = collection.iterator();

while(iterator.hasNext()){
Object obj = iterator.next();
System.out.println(obj);
}

/**
* 2.3 移除集合中的元素:
* remove(): 移除某一个指定的对象. 通过 equals() 方法来判断要移除的那个元素在集合中是否存在.
以及是否能够成功移除.
* removeAll()
* clear(): 使集合中的元素置空.
*/
// collection.clear();

// boolean result = collection.remove(p1);
// System.out.println(result);
//
// result = collection.removeAll(collection2);
//
// System.out.println(collection.size());

/**
* 2.4 用于检测集合的方法
* retains()
* retainsAll()
* isEmpty()
*/
System.out.println(collection.contains(new Person()));//false
System.out.println(collection.contains(p1));//true
System.out.println(collection.containsAll(collection2));//true

System.out.println(collection.isEmpty()); //false
// collection.clear();
System.out.println(collection.isEmpty()); //true

/**
* 2.5 其他方法
* toArray():
* **T [] toArray(T[]): 涉及到泛型, 后面再说.
*
* equals(): 比较两个集合是否相等.
* hasCode():
*/
Object [] objs = collection.toArray();
System.out.println(objs.length); //4

Person p2 = new Person();

Collection collection3 = new HashSet();//可换ArrayList()试试
collection3.add(p1);
collection3.add(p2);

Collection collection4 = new HashSet();
collection4.add(p2);
collection4.add(p1);

System.out.println(collection3.equals(collection4));

/**
* 使用增强 for 循环的方式来对集合进行遍历
*/
for(Object obj: collection){
System.out.println(obj);
}
}
}
class Person(){}

练习代码

二、Set、HashSet、LinkedHashSet:

Set 集合不允许包含相同的元素,如果试把两个相同的元素加入同一个
Set 集合中,则添加操作失败。

Set 判断两个对象是否相同不是使用 == 运算符,而是根据 equals
方法。

注意:

1、当向 HashSet 集合中存入一个元素时,HashSet
会调用该对象的 hashCode() 方法来得到该对象的

hashCode 值, 然后根据 hashCode 值决定该对象在 HashSet 中的存储位置。

2、如果两个元素的 equals() 方法返回 true,但它们的 hashCode() 返回值不相等,hashSet 将会

把它们存储在不同的位置,但依然可以添加成功。

3、HashSet 集合判断两个元素相等的标准:两个对象通过
equals() 方法比较相等,并且两个对象的

hashCode() 方法返回值也相等。即:如果两个对象通过 equals() 方法返回 true,这两个对象的

hashCode
值也应该相同。

重写 hashCode() 方法的基本原则:

1、在程序运行时,同一个对象多次调用 hashCode() 方法应该返回相同的值。

2、当两个对象的 equals() 方法比较返回 true 时,这两个对象的 hashCode() 方法的返回值也应相等。

3、对象中用作 equals() 方法比较的 Field,都应该用来计算 hashCode 值。

另外:

1、LinkedHashSet 是 HashSet 的子类。

2、LinkedHashSet 集合根据元素的 hashCode 值来决定元素的存储位置,但它同时使用链表维护元素的次序,

这使得元素看起来是以插入顺序保存的。

3、LinkedHashSet 性能插入性能略低于 HashSet,但在迭代访问 Set 里的全部元素时有很好的性能。

4、LinkedHashSet 有序但不允许集合元素重复。

import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;

/**
* 1. Set 是 Collection 的子接口
* 2. Set 中不允许存放相同的元素. 判定相同元素的标准是, 两个对象各调用 equals() 方法, 返回 true
* 3. HashSet
* 3.1 基本特征:
* ①. 不能保证元素的排列顺序
* ②. HashSet 不是线程安全的
* ③. 集合元素可以使 null
* ④. 对于 HashSet: 如果两个对象通过 equals() 方法返回 true,这两个对象的 hashCode 值也应该相同。
*
* 4. LinkedHashSet:
* 4.1 LinkedHashSet 是 HashSet 的子类
* 4.2 使用链表维护元素的次序,这使得元素看起来是以插入顺序保存的
* 4.3 LinkedHashSet 不允许集合元素重复
*/
public class TestSet {

public static void main(String[] args) {

Set set = new LinkedHashSet();
//new HashSet();

set.add(null);
System.out.println(set.size()); //1

Person p1 = new Person();
set.add(p1);
set.add(p1);

System.out.println(set.size()); //2

set.add(new Person("AA", 12));
set.add(new Person("AA", 12));

System.out.println(set.size()); //3

set.add(new Person("FF", 13));

Iterator it = set.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}

class Person {

// @Override
// public boolean equals(Object obj) {
// return false;
// }

private String name;
private int 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;
}

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

public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}

// private static int init = 0;

@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;

// return init++;
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) 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 "Person [name=" + name + ", age=" + age + "]";
}
}

练习代码

三、TreeSet:

TreeSet 是 SortedSet 接口的实现类,TreeSet
可以确保集合元素处于排序状态。

TreeSet 支持两种排序方法:自然排序和定制排序。默认情况下,TreeSet 采用自然排序。

排序:

1、TreeSet 会调用集合元素的 compareTo(Object obj)
方法来比较元素之间的大小关系,

然后将集合元素按升序排列。

2、如果试图把一个对象添加到 TreeSet 时,则该对象的类必须实现
Comparable 接口。

3、实现 Comparable 的类必须实现 compareTo(Object
obj) 方法,两个对象即通过

compareTo(Object
obj)方法的返回值来比较大小。

Comparable 的典型实现:

BigDecimal、BigInteger
以及所有的数值型对应的包装类:按它们对应的数值大小进行比较。

Character:
  按字符的 UNICODE 值来进行比较。

Boolean:
    true 对应的包装类实例大于 false 对应的包装类实例。

String:
      按字符串中字符的 UNICODE 值进行比较。

Date、Time:  
后边的时间、日期比前面的时间、日期大。

注意:

因为只有相同类的两个实例才会比较大小,所以向 TreeSet
中添加的应该是同一个类的对象,

当需要把一个对象放入 TreeSet 中,重写该对象对应的 equals()
方法时,应保证该方法与

compareTo(Object obj) 方法有一致的结果:即如果两个对象通过
equals() 方法比较返回 true,

则通过 compareTo(Object obj) 方法比较应返回
0.

import java.util.*;

/*
Set:无序,不可以重复元素。
|--HashSet:数据结构是哈希表。线程是非同步的。
保证元素唯一性的原理:判断元素的hashCode值是否相同。
如果相同,还会继续判断元素的equals方法,是否为true。

|--TreeSet:可以对Set集合中的元素进行排序。
底层数据结构是二叉树。
保证元素唯一性的依据:
compareTo方法return 0.

TreeSet排序的第一种方式:让元素自身具备比较性。
元素需要实现Comparable接口,覆盖compareTo方法。
也种方式也成为元素的自然顺序,或者叫做默认顺序。

TreeSet的第二种排序方式。
当元素自身不具备比较性时,或者具备的比较性不是所需要的。
这时就需要让集合自身具备比较性。
在集合初始化时,就有了比较方式。

需求:
往TreeSet集合中存储自定义对象学生。
想按照学生的年龄进行排序。

记住,排序时,当主要条件相同时,一定判断一下次要条件。
*/

class TreeSetDemo
{
public static void main(String[] args)
{
TreeSet ts = new TreeSet();

ts.add(new Student("lisi02",22));
ts.add(new Student("lisi007",20));
ts.add(new Student("lisi09",19));
ts.add(new Student("lisi08",19));
//ts.add(new Student("lisi007",20));
//ts.add(new Student("lisi01",40));

Iterator it = ts.iterator();
while(it.hasNext())
{
Student stu = (Student)it.next();
System.out.println(stu.getName()+"..."+stu.getAge());
}
}
}

class Student implements Comparable//该接口强制让学生具备比较性。
{
private String name;
private int age;

Student(String name,int age)
{
this.name = name;
this.age = age;
}

public int compareTo(Object obj)
{

//return 0;
if(!(obj instanceof Student))
throw new RuntimeException("不是学生对象");
Student s = (Student)obj;

System.out.println(this.name+"....compareto....."+s.name);
if(this.age>s.age)
return 1;
if(this.age==s.age)
{
return this.name.compareTo(s.name);
}
return -1;
}

public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}

练习代码(自然排序)

import java.util.*;

/*
当元素自身不具备比较性,或者具备的比较性不是所需要的。
这时需要让容器自身具备比较性。
定义了比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。

当两种排序都存在时,以比较器为主。

定义一个类,实现Comparator接口,覆盖compare方法。
*/
class Student implements Comparable//该接口强制让学生具备比较性。
{
private String name;
private int age;

Student(String name,int age)
{
this.name = name;
this.age = age;
}

public int compareTo(Object obj)
{

//return 0;

if(!(obj instanceof Student))
throw new RuntimeException("不是学生对象");
Student s = (Student)obj;

//System.out.println(this.name+"....compareto....."+s.name);
if(this.age>s.age)
return 1;
if(this.age==s.age)
{
return this.name.compareTo(s.name);
}
return -1;
}

public String getName()
{
return name;

}
public int getAge()
{
return age;
}
}
class TreeSetDemo2
{
public static void main(String[] args)
{
TreeSet ts = new TreeSet();

ts.add(new Student("lisi02",22));
ts.add(new Student("lisi02",21));
ts.add(new Student("lisi007",20));
ts.add(new Student("lisi09",19));
ts.add(new Student("lisi06",18));
ts.add(new Student("lisi06",18));
ts.add(new Student("lisi007",29));
//ts.add(new Student("lisi007",20));
//ts.add(new Student("lisi01",40));

Iterator it = ts.iterator();
while(it.hasNext())
{
Student stu = (Student)it.next();
System.out.println(stu.getName()+"..."+stu.getAge());
}
}
}

class MyCompare implements Comparator
{
public int compare(Object o1,Object o2)
{
Student s1 = (Student)o1;
Student s2 = (Student)o2;

int num = s1.getName().compareTo(s2.getName());
if(num==0)
{

return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
/*
if(s1.getAge()>s2.getAge())
return 1;
if(s1.getAge()==s2.getAge())
return 0;
return -1;
*/
}

return num;
}
}

练习代码(定制排序)

比较推荐的定制排序做法:

1、首先,定义一个Person类

public class Person {
private String name;
private int 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;
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Person(){}
}

Person类

(附加的练习:Student类)

public class Student implements Comparable{

private String name;
private int 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;
}
public Student(String name, int age) {
super();
this.name = name;
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;
}

@Override
public int compareTo(Object o) {
int result;
if(o instanceof Student){
Student stu = (Student)o;
result = this.age-stu.age;
if(result==0){
return this.getName().compareTo(stu.getName());
}
}else{
throw new ClassCastException("不是一个学生对象!");
}
return result;
}

public Student(){}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}

Student类

2、然后写主程序类

import java.util.Comparator;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

public class TestTreeSet {
public static void main(String []args){
/* Set set = new TreeSet();
// set.add("123");
// set.add(123);
// set.add(null);
// set.add(new Student());
set.add(new Student("lisi07",22));
set.add(new Student("lisi02",16));
set.add(new Student("lisi008",22));
set.add(new Student("lisi10",19));

Iterator iterator = set.iterator();
while(iterator.hasNext()){
Student stu = (Student) iterator.next();
System.out.println(stu.getName()+"...."+stu.getAge());
}

for(Object obj:set){
System.out.println(obj);
}*/

Comparator comparator = new Comparator() {

@Override
public int compare(Object o1, Object o2) {
int result;
if(o1 instanceof Person&& o2 instanceof Person){
Person p1 = (Person) o1;
Person p2 = (Person) o2;
result = p1.getAge() - p2.getAge();
if(result == 0){
return p1.getName().compareTo(p2.getName());
}
}else{
throw new ClassCastException("不能转换为Person");
}
return result;
}
};

Set set2 = new TreeSet(comparator);
set2.add(new Person("lisi006",12));
set2.add(new Person("lisi002",6));
set2.add(new Person("lisi015",20));
set2.add(new Person("lisi013",20));

Iterator iterator = set2.iterator();
while(iterator.hasNext()){
Person p = (Person) iterator.next();
System.out.println(p.getName()+" "+p.getAge()+"\t");
}
}
}

主程序

复习java基础第三天(集合)

时间: 2024-12-16 11:38:35

复习java基础第三天(集合)的相关文章

复习java基础第四天(集合)

List 代表一个元素有序.且可重复的集合,集合中的每个元素都有其对应的顺序索引 List 允许使用重复元素,可以通过索引来访问指定位置的集合元素. List 默认按元素的添加顺序设置元素的索引. List 集合里添加了一些根据索引来操作集合元素的方法: 另外: List 额外提供了一个 listIterator() 方法,该方法返回一个 ListIterator 对象, ListIterator 接口继承了 Iterator 接口,提供了专门操作 List 的方法: boolean hasPr

复习java基础第一天

一:static static: 静态的.   1. 若需要一个类的多个对象共享一个变量,则该变量需要使用 static 修饰.   2. 因为 static 修饰的变量为类的所有的实例所共享,所以 static 成员不属于某个类的实例, 而属于整个类.     所以在访问权限允许的情况下,可以使用 "类名." 直接访问静态成员(成员包括属性和方法).  3. 注意: 在静态方法里只能直接调用同类中其它的静态成员(包括变量和方法),而不能直接访问类中的非静态成员.     这是因为,对

复习java基础第二天(异常处理)

一.常见的异常类型: public class TestException { public static void main(String[] args) { int i = 10; //数学异常: java.lang.ArithmeticException int j = i / 0; System.out.println(j); int [] scores = new int[]{1, 2, 4, 5}; //数组下标越界异常: java.lang.ArrayIndexOutOfBound

复习java基础第七天(反射)

一:目标 Ø理解 Class 类 Ø理解 Java 的类加载机制 Ø学会使用 ClassLoader 进行类加载 Ø理解反射的机制 Ø掌握 Constructor.Method.Field 类的用法 Ø理解并掌握动态代理 1.Class类 –对象照镜子后可以得到的信息:某个类的数据成员名.方法和构造器.某个类到底实现了哪些接口. 对于每个类而言,JRE 都为其保留一个不变的 Class 类型的对象. 一个 Class 对象包含了特定某个类的有关信息. –  Class 对象只能由系统建立对象.

复习java基础第六天(IO)

一:File 类 • 输入:读取外部数据(磁盘.光盘等存储设备的数据)到程序(内存)中. • 输出:将程序(内存)数据输出到磁盘.光盘等存储设备中 • Java 的 IO 流主要包括输入.输出两种 IO 流,每种输入.输出流有可分为字节流和字符流两大类: – 字节流以字节为单位来处理输入.输出操作 – 字符流以字符为单位来处理输入.输出操作 注意:输入.输出是以程序为参照. • File 类代表与平台无关的文件和目录. • File  能新建.删除.重命名文件和目录,但 File 不能访问文件内

java基础(三章)

java基础(三章) 一.基本if结构 1.流程图 l  输入输出 l  判断和分支 l  流程线 1.1              简单的if条件判断 if(表达式){            //表达式为true,执行{}中的代码 } 1.2              简单的if条件判断 if(表达式){            //表达式为true,执行这里 }else{            //表达式为false,这行这里 } 说明:如果if或else后面,有且仅有一行代码,{ }可以省略

Java基础(三)选择结构

Java基础(三)选择结构回顾:1.什么是变量 2.变量三要素 3. ++和--  &&和|| 本章内容1.if选择结构 4种 2.switch 小知识:三元运算符: 条件?“x”:“Y” 条件为真X,条件为假Y 1.掌握if条件的结构①基础if选择结构 if(条件){ //条件成立执行的代码}123****e ②if-else 选择结构(互斥) if(条件){ //条件成立则执行}else{ //条件不成立则执行}12345③多重if选择结构 if(条件1){ }else if(条件2)

Java 基础(三)| IO流之使用 File 类的正确姿势

为跳槽面试做准备,今天开始进入 Java 基础的复习.希望基础不好的同学看完这篇文章,能掌握泛型,而基础好的同学权当复习,希望看完这篇文章能够起一点你的青涩记忆. 一.什么是 File 类? java.io.File 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建.查找和删除等操作. 二.File 类的使用 2.1 构造方法 File 类的构造有三种: public File(String pathname) : 直接通过文件路径字符串创建 public File(String par

Java基础知识强化之集合框架笔记07:Collection集合的遍历之迭代器遍历

1. Collection的迭代器: 1 Iterator iterator():迭代器,集合的专用遍历方式 2. 代码示例: package cn.itcast_03; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; /* * Iterator iterator():迭代器,集合的专用遍历方式 * Iterator(迭代器): * Object next():获取元素,并移动