集合框架之Set

1.LinkedList实现堆栈

栈是一种仅支持在表尾进行插入和删除操作的线性表,这一端被称为栈顶,另一端被称为栈底。元素入栈指的是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;元素出栈指的是从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。栈中的元素遵守先出后进(LIFO)的原则。

Queue的数据结构:先进先出(FIFO)

public class MyStack {
    //定义子弹夹,装子弹
    private LinkedList linkedlist=new LinkedList();
    /**
     * 压栈(装子弹)
     * @param obj
     */
    public void push(Object obj) {
        linkedlist.addFirst(obj);
    }
    /**
     * 出栈(开枪)
     * @return
     */
    public Object pop() {
        Object obj=linkedlist.getFirst();
        linkedlist.removeFirst();
        return obj;
    }
    //实时计算弹夹子弹数
    public int size() {
        return linkedlist.size();
    }
    public static void main(String[] args) {
        MyStack myStack=new MyStack();
        //添加子弹
        myStack.push("a"); //第一粒子弹
        myStack.push("b"); //第二粒子弹
        myStack.push("c"); //第三粒子弹
        myStack.push("d"); //第四粒子弹
        myStack.push("e"); //第五粒子弹
        //模拟开枪
        //栈结构:先进后出
        while(myStack.size()!=0)
            System.out.println(myStack.pop());
    }
}

2.集合框架

集合框架之Set_第1张图片

3.Set集合

Set继承于Collection接口,是一个不允许出现重复元素,并且无序的集合,主要有HashSet和TreeSet两大实现类。

3.1.特点

  • 无序:Set集合数据添加的顺序和取出的顺序不一致

Set set=new HashSet();
set.add(2);
set.add(1);
set.add(5);
set.add(8);
System.out.println(set);

  • 唯一:List集合数据允许添加重复数据

Set set=new HashSet();
set.add(2);
set.add(1);
set.add(5);
set.add(8);
set.add(8);
System.out.println(set);

  • 问题:存储对象,验证Set集合唯一性

Set set=new HashSet();
set.add(new User(1,"zs"));
set.add(new User(2,"ls"));
set.add(new User(1,"zs"));
for (User user : set) {
    System.out.println(user);
}

查看结果:存储相同属性的User对象时,Set集合并未满足唯一性要求,打印输入了相同对象信息。 输出格式:类的全路径名+@+十六进制内存地址

User user = new User();
user.equals(null);  //跳转到equals方法查看源码

问题原因:判断重复元素的时候,Set集合会调用hashCode()和equal()方法来实现;而在没有重写equals方法之前默认比较的是Object(引用类型),实际上比较的是内存地址。

重写User对象中的equals方法,比较User对象中的属性。

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((id == null) ? 0 : id.hashCode());
    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;
    User other = (User) obj;
    if (id == null) {
        if (other.id != null)
            return false;
    } else if (!id.equals(other.id))
        return false;
    if (name == null) {
        if (other.name != null)
        return false;
    } else if (!name.equals(other.name))
        return false;
    return true;
}

当比较对象的属性相同时,已存在的对象信息不会被覆盖,而是过滤了。 结论:先比较hashcode值是否相同,再比较equals;

3.2.遍历方式

  • foreach

Set set=new HashSet();
set.add("zs");
set.add("ls");
set.add("ww");
for (String value : set) {
    System.out.println(value);
}
  • 迭代器

Set set=new HashSet();
set.add("zs");
set.add("ls");
set.add("ww");
Iterator it = set.iterator();
while(it.hasNext())
    System.out.println(it.next());

3.3.常见实现类

HashSet

  • 它不允许出现重复元素;

  • 不保证集合中元素的顺序

  • 允许包含值为null的元素,但最多只能有一个null元素。

  • HashSet的实现是不同步的。

LinkedHashSet

  • 哈希表和链表实现Set接口,具有可预测的迭代次序;

  • 由链表保证元素有序,也就是说元素的存储和取出顺序是一致的。

  • 由哈希值保证元素唯一,也就是说没有重复的元素

TreeSet

TreeSet 是一个有序的集合,它的作用是提供有序的Set集合。TreeSet是基于TreeMap实现的。TreeSet中的元素支持2种排序方式:自然排序 或者 根据创建TreeSet 时提供的 Comparator 进行排序。

  • java.lang.Comparable自然比较接口

public class User implements Comparable {
    private int id;
    private String name;
    ...
    @Override
    public int compareTo(Student b) {
        return this.id-b.id;
    }
}

  • java.util.Comparator比较器

public class NameComparator implements Comparator {
    @Override
    public int compare(User a, User b) {
        return a.getName()-b.getName();
    }
}

你可能感兴趣的:(J2EE,集合框架,java,算法,j2ee,前端框架)