黑马程序员技术交流社区
标题:
ArryList练习中,遇到的问题
[打印本页]
作者:
fufeng
时间:
2014-4-15 10:49
标题:
ArryList练习中,遇到的问题
import java.util.*;
class Person
{
private String name;
private int age;
Person(String name,int age)
{
this.name = name;
this.age = age;
}
public boolean equals(Object obj)
{
if(!(obj instanceof Person))
return false;
Person p = (Person)obj;
System.out.println(this.name+"======="+p.name);
return this.name.equals(p.name) && this.age == p.age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
class Noname9
{
public static void main(String[] args)
{
ArrayList al = new ArrayList();
al.add(new Person("zhangsan01",31));
al.add(new Person("zhangsan01",31));
al.add(new Person("zhangsan03",32));
al.add(new Person("zhangsan05",34));
al.add(new Person("zhangsan05",34));
Iterator it = al.iterator();
while(it.hasNext())
{
Person p = (Person) it.next();
sop("name: "+p.getName()+"--"+"age: "+p.getAge());
}
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
要实现的功能为:当向ArrayList中添加Person对象的时候,调用Person类中的equals方法,将name和age一样的对象,认为是相同的对象,在ArrayList只存储一个,保证里面没有重复对象,
但是结果却是
全部都添加进出了
这是为什么呢?
作者:
TTc
时间:
2014-4-15 11:12
ArraryList特点:底层实现数据结构是数组结构,查询效率高,增删效率低,且因为其存在角标,是有序的,所以可以储存相同的对象,其存入的地址(角标)不同。
作者:
759345779
时间:
2014-4-15 11:21
list集合的特点是有有序的,每次添加等于是从下一新的角标开始,存储不会自动调用equals比较内容的,其存储内容可以指向同一对象,或者具有相同内容的不同对象
比如下面代码
ArrayList al = new ArrayList();
Person per = new Person("zhangsan05",34);
al.add(per);
al.add(per);
al.add(per);
al.add(per);
al.add(per);
复制代码
添加了5次,都是同一对象,
打印结果是:
name: zhangsan05--age: 34
name: zhangsan05--age: 34
name: zhangsan05--age: 34
name: zhangsan05--age: 34
name: zhangsan05--age: 34
作者:
曹冬明
时间:
2014-4-15 11:27
ArrayList里是可以有重复元素的,所以你的equals方法不会调用,如果是其他集合就会调用了,因为其他集合元素必须唯一
作者:
宋超2356
时间:
2014-4-15 11:34
这样才是正常的啊,因为List本来就是不会自动调用equals方法的,它都是存于新的脚标下,所以重写是没意义的,估计是和Set弄混了
付Set的添加方法,过去写的博客....
import java.util.*;
public class Test
{
public static void main(String[] args)
{
HashSet hs = new HashSet();
hs.add(new Smile("呵呵"));
hs.add(new Smile("呵呵"));
System.out.println(hs);
System.out.println("------分割线------");
Smile s=new Smile("嘿嘿");
hs.add(s);
hs.add(s);
System.out.println(hs);
System.out.println("======分割线======");//Smile继承object的hashCode和equals方法
String s1 = new String("哈哈");
String s2 = new String("哈");
hs.add(s1);
hs.add(s2);
System.out.println(hs);//String类重写过hashCode与equals所以就不同于Smile,不能添加相同的
}
}
class Smile
{
String name;
Smile(String name)
{
this.name=name;
}
public String toString() {
return name;
}
}
输出结果是:[呵呵, 呵呵]
------分割线------
[呵呵, 呵呵, 嘿嘿]
======分割线======
[哈哈, 呵呵, 呵呵, 嘿嘿]
复制代码
作者:
也许依然
时间:
2014-4-15 12:17
|--List : 元素是有序的,元素可以重复。因为该集合体系有索引
|--ArrayList: 底层的数据结构使用的是数组结构。 线程不同步
|--LinkedList: 底层的数据结构使用的是链表结构
|--Vector: 底层是数组数据结构。 线程同步。被ArrayList替代了
|--Set :元素是无序,元素不可以重复
|--HashSet:数据结构是哈希表,线程时非同步的
保证元素唯一性的原理:判断hashCode值是否相同,如果相同继续判断equals方法,是否为true
|--TreeSet:可以对Set集合中的元素进行排序,底层数据结构是二叉树
保证元素唯一性的依据:compareTo方法返回值是否为0
TreeSet集合的第一种排序方式:让元素自身具备比较性
元素需要实现Comparable接口,覆盖compareTo方法,这种方式称为元素的自然顺序
TreeSet集合的第二种排序方式:当元素自身不具备比较性,或者具备的比较性不是所需要的
这时需要让容器自身具备比较性
定义比较器,将比较器对象作为参数传递给TreeSet集合的构造函数
ArrayList集合中可以存储相同的元素,在存储中不会判断equals方法,按下标的顺序依次存入,如果要存入不同的元素,需要使用Set集合,覆盖hashCode方法,equals方法,并实现Comparable接口覆盖compareTo方法
代码演示:
public class Set {
public static void main(String[] args){
TreeSet<Person> ts = new TreeSet<Person>();
ts.add(new Person("lisi01",11));
ts.add(new Person("lisi02",12));
ts.add(new Person("lisi01",13));
ts.add(new Person("lisi04",11));
Iterator<Person> it = ts.iterator();
while(it.hasNext()){
Person p = it.next();
System.out.println(p);
}
}
}
class Person implements Comparable<Person>{
private int age;
private String name;
Person(String name,int age){
this.name = name;
this.age = age;
}
@Override
public int compareTo(Person p){
int num = new Integer(this.age).compareTo(new Integer(p.age));
if(num==0)
return this.name.compareTo(p.name);
return num;
}
@Override
public int hashCode(){
return name.hashCode()+age*39;
}
@Override
public boolean equals(Object obj){
if(obj instanceof Person)
throw new RuntimeException("error");
Person p = (Person)obj;
return name.equals(p.name) && age==p.age;
}
public int getAge(){
return age;
}
public void setAge(int age){
this.age = age;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
@Override
public String toString(){
return age+" "+name;
}
}
复制代码
作者:
491138002
时间:
2014-4-15 12:42
ArrayList里是可以有重复元素的,可以通过HashSet剔除
// 删除ArrayList中重复元素
public static void removeDuplicateBySet(List list) {
HashSet h = new HashSet(list);
list.clear();
list.addAll(h);
System.out.println(list);
}
作者:
shi0000
时间:
2014-4-15 12:44
本帖最后由 shi0000 于 2014-4-15 12:50 编辑
看系统调用什么方法,就看集合是什么结构,如: 数组结构的是系统使用a【i】=“”来存储到栈中, 底层是二叉树是,系统会
调用hashcode()和equals()方法,先赋给他一个hash值,再比较其大小,最后按照二叉树的形式保存起来。
底层是hash表时,系统也是会有hashcode()和equals()方法,先赋hash值,再比较hash是否相等,当相等时,就会将新进来的对象存入,
覆盖掉原来的对象。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2