JAVA Class16

学习内容:

1.List接口:

List接口的实现类有如下特点:

有顺序(存取顺序相同),值可以重复,有索引。

常用方法:

a. add()方法,返回布尔值

b. set(),返回被修改的值(注意,是修改前而不是修改后的值!)

c.remove()方法,返回被删除的值

d.addAll()方法,将另外一个集合的所有元素添加到当前集合,返回布尔值

public class Test {
    public static void add() {
        List<String> list = new ArrayList<String>();
        //有顺序,值可以重复,有索引
        list.add("one");
        list.add("two");
        list.add("three");
        list.add(3,"four");可以顺序添加
        list.add(4, "four");
        System.out.println(list);    
        String s = list.remove(0);//删除时返回被删除的值
        System.out.println(s);
        String e = list.set(0, "who");//修改时返回被修改的值(注意,是修改前而不是修改后的值!)
        System.out.println(e);
        System.out.println(list);
   }
}

并发修改异常、无此元素异常:

public class Test {
    public static void add() {
        List<String> list = new ArrayList<String>();
        list.add("one");
        list.add("two");
        list.add("three");
        Iterator<String> it = list.iterator();
        while(it.hasNext()) {
            String str = it.next();
            if(str.equals("one")) {
                int i = list.indexOf("one");
                list.add(i, "who");
            }
            //System.out.println(str);
            /*java.util.ConcurrentModificationException*/
            //并发修改异常
        }
    }
}

public class Test{
    public static void main(String[] args){
        List<String> list2 = new ArrayList<String>();
        list2.add("nihao");
        list2.add("wohao");
        list2.add("dajiahao");
        list2.add("nihao");
        list2.add(1, "tahao");
        for(Iterator<String> it = list2.iterator();it.hasNext();) 
                {
                String str = it.next();
            if(str.equals("nihao")) {
                int i = list2.indexOf(str);
                list2.set(i,"nibuhao");    
            }
            //System.out.println(it.next());
           //无此元素异常,NoSuchElementException
        }
    }
}

e.contains(),是否包含某个元素,返回布尔值,配合迭代可以实现去重,例:

ArrayList<Student> list = (ArrayList<Student>)ois.readObject();
ArrayList<Student> filterlist = new ArrayList<Student>();
Iterator<Student> it = list.iterator();
while(it.hasNext()){
  Student stu = it.next();
  if(!filterlist.contains(stu)){
    filterlist.add(stu);
  }
}

 

2.数据存储的常用结构有:堆栈、队列、数组、链表。

(1)堆栈:数据先进后出。

(2)队列:数据先进先出。

(3)数组:查找快,增删慢,因为每次增删都要创建一个新数组。

(4)链表:增删快,查询慢,各个元素之间通过地址指向互相连接。

3.LinkedList

链表结构,数据先进先出,可以很方便的向集合首尾添加、删除数据

常用方法:addFirst,addLast,removFirst,removeLast

public Test{
  public static void main(String[] args){
       LinkedList<String> list = new LinkedList<String>();
       list.add("123");
       list.addFirst("123");
       list.addLast("456");
       list.removeFirst();
       list.removeLast();
  }  
}

4.Set接口

特点:无序(存取顺序不同),数据不重复,无索引

因为Set的实现类没有下标,所以只能通过迭代器或者增强型for循环来遍历

public Test{
  public static void main(String[] args){
      Set<String> set = new HashSet<String>();
        set.add("Cross");
        set.add("bingo");
        set.add("where");
        set.add("are");
        set.add("you");
        for(Iterator it = set.iterator();it.hasNext();) {
            System.out.println(it.next());
        }
        for(String str:set) {
            System.out.println(str);
        }
  }  
}

实现类:

HashSet:

注意add方法:默认会调用父类的hashcode、equals方法,先比较hashcode,如果相同,直接返回false,不存入,

如果不同,用equals比较,如果相同,返回false,不存入,如果不同,返回true,存入。

HashSet 如何add机制

   假如我们有一个数据(散列码76268),而此时的HashSet有128个散列单元,那么这个数据将有可能插入到数组的第108个链表中(76268%128=108)。
但这只是有可能,如果在第108号链表中发现有一个老数据与新数据equals()=true的话,这个新数据将被视为已经加入,而不再重复丢入链表。 HashSet的散列单元大小如何指定? Java默认的散列单元大小全部都是2的幂,初始值为16(2的4次幂)。假如16条链表中的75%链接有数据的时候,则认为加载因子达到默认的0.75
HahSet开始重新散列,也就是将原来的散列结构全部抛弃,重新开辟一个散列单元大小为32(2的5次幂)的散列结果,并重新计算各个数据的存储位置。
以此类推下去.....

如果HashSet的泛型是字符串或者基本数据类型的的封装类,这样不会有问题,但是如果存入的是实例化的对象,因为每个实例化的对象其hashcode不同,即使其成员变量相同(即本质上是相同的对象),也会存入HashSet,所以必须重写继承自父类的hashcode、equals方法!

public Test {
  public static void main(String[] args){
    HashSet<String> hs = new HashSet<String>();
        hs.add("one");
        hs.add("one");//重复的值只会保留一个,hashcode相同
        hs.add("two");
        System.out.println(hs);
        HashSet<Person> hp = new HashSet<Person>();
        hp.add(new Person("a","nan",20));//哈希值不同,导致全部存入,需要重写Person类内的hashcode、equals方法
        hp.add(new Person("a","nan",20));//默认调用父类的hashcode与equals方法
        hp.add(new Person("a","nan",20));
        System.out.println(hp);
        Person p1 = new Person("1","a",20);
        Person p2 = new Person("1","a",20);
        System.out.println(p1.hashCode());//
        System.out.println(p2.hashCode());//这两个对象hashcode不同,但本质上是一个对象
  }
}
public class Person {
    String name;
    String sex;
    int age;
    public Person() {};
    public    Person(String name,String sex,int age) {
        this.name = name;
        this.sex = sex;
        this.age = age;
    }
    public String toString() {
        return name+'\t'+sex+'\t'+age;
    }
    public int hashCode() {//重写父类方法
        return name.hashCode()*55;
    }
    public boolean equals(Object obj) {//方法重写,根据对象属性判断是否为同一对象
        if(obj==null) {
            return false;
        }
        if(this==obj) {
            return true;
        }
        if(obj instanceof Person) {
            Person person = (Person)obj;
            return ((Person)obj).age==this.age&&((Person)obj).name==this.name&&((Person)obj).sex==this.sex;
        }
        return super.equals(obj);
    }
}

 LinkedHashSet:

可以实现元素的顺序存取

public Test{
  public static void main(String[] args){
     LinkedHashSet<String> lhs = new LinkedHashSet<String>();//按顺序存取
        lhs.add("123");
        lhs.add("456");
        lhs.add("7889");
        lhs.add("412");
        lhs.add("017");
        System.out.println(lhs);
  }  
}
posted @ 2018-04-17 15:15  0==1&1==0  阅读(224)  评论(0编辑  收藏  举报