【Java笔记】 Week07

来源:互联网 发布:js弹出路径选择对话框 编辑:程序博客网 时间:2024/06/17 23:56

写在前面的部分

本周主要学习了list和set集合下面的具体实现类

1.List集合子实现类

a. ArrayList :底层数据结构是数组的形式,满足数组结构的特点:查询快,增删慢
从线程安全问题来看:线程不安全的,不同步,执行效率高
b. Vector :底层数据结构是数组的形式,查询快,增删慢
   从线程角度看:线程安全的类,同步,执行效率低
c. LinkedList: 底层数据结构是链接列表,特点:查询慢,增删快
从线程角度看:线程不安全的一个类,不同步,执行效率高
d. 如果在一般的需求中没有指明使用集合去完成,都默认采用ArrayList如果需求中要考虑线程安全,那么使用Vector

2.ArrayList

a. 和List集合一样,存储的元素可以是相同的,存储和取出的顺序一致
b. ArrayList去除集合中字符串的重复元素

package org.westos_04;import java.util.ArrayList;import java.util.Iterator;/** * 需求:ArrayList去除集合中字符串的重复元素 * 1)首先创建一个集合 * 2)给集合中添加很多重复元素 * 3)再次创建一个新集合 * 4)获取迭代器遍历 * 5)获取到该集合中的每一个元素 * 判断新集合中是否包含这些有素 * 有,不搭理它 * 没有.说明不重复,添加进来 *  6)遍历新集合 * @author Apple */public class ArrayListTest {public static void main(String[] args) {//1)创建一个集合ArrayList array = new ArrayList() ;//2)给集合中添加多个重复元素array.add("hello") ;array.add("hello") ;array.add("hello") ;array.add("world") ;array.add("world") ;array.add("world") ;array.add("Java") ;array.add("Java") ;array.add("hello") ;array.add("Javaweb") ;array.add("JavaEE") ;array.add("JavaEE") ;//3)创建一个新的集合ArrayList newArray = new ArrayList() ;//4)遍历旧集合,获取当前迭代器对象Iterator it = array.iterator() ;while(it.hasNext()){String s = (String) it.next() ;//拿到了每一个字符串元素//判断新集合是否包含旧集合中的元素if(!newArray.contains(s)){//不包含,就将元素直接添加到新集合中newArray.add(s) ;}}//遍历新集合Iterator it2 = newArray.iterator() ;while(it2.hasNext()){String s = (String) it2.next() ;System.out.println(s);}}}
c.去除自定义对象的重复值
package org.westos_04;import java.util.ArrayList;import java.util.Iterator;/** *  需求:ArrayList去除集合中自定义对象的重复值(对象的成员变量值都相同) *   *  发现问题: *  使用刚才创建新集合的思想,逻辑步骤和去除集合中重复的字符串是一样,但是出现了并没有将自定义对象的重复值(成员变量值一样)并没有去除掉 *   *  contains()底层依赖于一个equals()方法,equals()方法是Object类的中的方法,该法默认比较的是对象的地址值是否相同,必须要重写Object中的eqauls() *  方法,才能比较内容是否相同; *  在自定义对象的类中重写Object中的equasl()方法,才能比较成员变量的值是否相同 *  看源码: *   *  ArrayList集合的Contains()源码 *    public boolean contains(Object o) {        return indexOf(o) >= 0;    }      public int indexOf(Object o) {        if (o == null) {            for (int i = 0; i < size; i++)                if (elementData[i]==null)                    return i;        } else {            for (int i = 0; i < size; i++)                if (o.equals(elementData[i]))                    return i;        }        return -1;    } *   * @author Apple */public class ArrayListTest3 {public static void main(String[] args) {//创建一个ArrayList集合对象ArrayList array = new ArrayList() ;//2)创建学生对象Student s1 = new Student("高圆圆", 27) ;Student s2 = new Student("高圆圆", 20) ;Student s3 = new Student("邓超", 29) ;Student s4 = new Student("邓超", 25) ;Student s5 = new Student("黄晓明", 30) ;Student s6 = new Student("高圆圆", 27) ;//将学生对象添加到array集合中array.add(s1) ;array.add(s2) ;array.add(s3) ;array.add(s4) ;array.add(s5) ;array.add(s6) ;//3)创建一个新集合ArrayList newArray = new ArrayList() ;//遍历旧集合,获取迭代器对象Iterator it = array.iterator() ;while(it.hasNext()){Student s = (Student) it.next() ;//判断新集合中是否包含这些对象if(!newArray.contains(s)){//不包含的对象才能添加新集合newArray.add(s) ;}}//遍历新集合Iterator it2 = newArray.iterator() ;while(it2.hasNext()){Student s = (Student) it2.next() ;System.out.println(s.getName()+"---"+s.getAge());}}}


3.Vector

a. 查询快,增删慢
b. 特有方法 :
(1)public void addElement(E obj   ——  相当于:add(Object e)
(2)public Enumeration<E> elements() ——  相当于:Iterator iterator()
(3)Enumeration<E>接口 :
1)boolean hasMoreElements() —— 相当于 hasNext()
2)Object nextElement(): —— 相当于Next()

通过Enumeration实现遍历

public class VectorDemo {public static void main(String[] args) {//创建一个Vector集合对象Vector v = new Vector() ;//添加元素//public void addElement(E obj)v.addElement("hello");v.addElement("hello");v.addElement("world");v.addElement("Java");//public Enumeration<E> elements()----->相当于:Iterator iterator() ;Enumeration en = v.elements() ;//遍历元素/** * boolean hasMoreElements():------>相当于:hasNext()Object nextElement():----------->相当于:next(); */while(en.hasMoreElements()){//获取元素String s = (String)en.nextElement() ;System.out.println(s);}}}

4.  LinkedList

(1) 查询慢,增删快

(2) 特有功能:

1) 添加功能::

(i)public void addFirst(E e)将指定元素插入此列表的开头

(ii)public void addLast(E e)将指定元素添加到此列表的结尾。

2)获取功能::

(i)public Object getFirst()返回此列表的第一个元素

(ii)public Object getLast()返回此列表的最后一个元素。

3) 删除功能::

(i)public Object removeFirst()移除并返回此列表的第一个元素。

(ii)public Object removeLast()移除并返回此列表的最后一个元素。


public class LinkedListDemo {public static void main(String[] args) {//创建LinkedList集合LinkedList link = new LinkedList() ;//添加元素link.addFirst("hello") ;link.addFirst("world") ;link.addFirst("Java") ;//public void addFirst(E e)将指定元素插入此列表的开头/*link.addFirst("android") ;link.addLast("JavaWeb") ;*//** * public Object getFirst()返回此列表的第一个元素public Object getLast()返回此列表的最后一个元素。 *//*Object obj = link.getFirst() ;System.out.println(obj);Object obj2 = link.getLast() ;System.out.println(obj2);*//** * public Object removeFirst()移除并返回此列表的第一个元素。public Object removeLast()移除并返回此列表的最后一个元素。 *//*System.out.println("removeFirst:"+link.removeFirst());System.out.println("removeLast:"+link.removeLast());*///输出集合System.out.println("link:"+link);}}


5. 增强for循环

a. 书写格式 :
for(集合或者数组中的数据类型 变量名:集合或者数组的对象名){
  输出变量名;
  }

b.  弊端:

对象不能为null,所以要加上非空判断

c.  增强for循环的出现就是为了替代迭代器遍历集合的,以后开发中就是用增强for遍历元素

d.  集合的嵌套遍历

(1) 

for(ArrayList<Student> array :bigArray){//子集合:ArrayList<Student>for(Student s : array){System.out.println(s.getName()+"---"+s.getAge());}}

6. 泛型

a. 把数据类型的明确工作提供提前到了创建对象或者是调用方法的时期明确的一种特殊类型.参数化类型,可以像参数一样进行传递
b. 格式 :  <引用类型>     ——>:泛型只能放引用类型
c. 好处:
   1)将运行时期异常提前到了编译时期
  2)解决了黄色警告线问题
  3)获取数据的时候,不用强制类型转换了
d. 泛型的应用 :、
(1)泛型定义在类上:
class A<T>{}

(2)泛型定义在方法上:

public <T> void show(T t) {}

//将泛型定义在方法上public <T> void show(T t){System.out.println(t);}

(3)泛型定义在接口上

1)第一种情况 接口的子实现类已经知道传递的是什么数据类型

public class InterImpl<String> implements Inter<String> {

@Override
public void show(String t) {
System.out.println(t);}

}

(2)第二种情况 :接口的子实现类在实现接口的时候,不知道具体的数据类型是什么(在测试类的时候,传入具体数据类型)

public class InterImpl<T> implements Inter<T>{

@Override
public void show(T t) {
System.out.println(t);
}

}

e. 泛型的高级通配符

(1) <?> :可以是任意类型,包括Object类型以及任意的Java类

(2)<? extends E>:向下限定,E类型以及E类型的子类

(3)<? super E>:向上限定,E类型以及E类型的父类


7.set

a. Set接口:Set集合继承自Collection集合
b. 特点:Set:底层数据结构是一个哈希表,能保证元素是唯一的,元素不重复!(存储与取出不一致)
       它通过它的子实现了HashSet集合去实例化,HashSet集合底层是HashMap集合的实例!

8.HashSet

a. hashCode()和equals()方法;HashSet底层是依赖于这两个实现来保证元素的唯一性!
b. 不保证迭代顺序的恒定 —— 因为底层是由HashMap的put实现
添加时先看hashcode值是否相同,若相同再比较equals(若重写)方法

9.LinkedHashSet

a. 通过哈希表实现数据的唯一性,通过链表实现元素的有序性

10.TreeSet

a. TreeSet集合底层是依赖于TreeMap的实例,而TreeMap<K,V>是依赖于红黑树结构实现的
b. TreeSet中可以实现两种排序方法 自然排序和比较器排序 ,取决于用哪个构造方法
c. 无参构造实现TreeSet的自然排序(升序)
一个类若想实现自然排序,必须要实现Comparaable接口,重写compareTo()方法

class TreeMap<K,V> implements NavigableMap<K,V>{private transient int modCount = 0; 该变量不会被序列化//Map集合中添加元素的方法public V put(K key, V value) {///20,18,23,22,17,24,19,18,24 = key         Entry<K,V> t = root;//root=第一次存储的20这个元素        if (t == null) {            compare(key, key); // type (and possibly null) check            root = new Entry<>(key, value, null);            size = 1;            modCount++;            return null;        }        int cmp;        Entry<K,V> parent;//父节点==t==20        // split comparator and comparable paths        //比较器排序        Comparator<? super K> cpr = comparator;//this.comparaptr;        if (cpr != null) {            do {                parent = t;                cmp = cpr.compare(key, t.key);//t.key==通过根节点和后面依次传来的元素进行比较                if (cmp < 0)                    t = t.left;                else if (cmp > 0)                    t = t.right;                else                    return t.setValue(value);            } while (t != null);//键值对象不能为null        }        else {        //自然排序:由于创建TreeSet集合对象TreeSet():无参构造形式            if (key == null)//key=需要存储的元素://20,18,23,22,17,24,19,18,24--->Integer类型                throw new NullPointerException();//一定空指针异常            Comparable<? super K> k = (Comparable<? super K>) key; //声明了一个接口对象:Comparable接口对象 :this.key            do {                parent = t;//20                cmp = k.compareTo(t.key);////t.key==通过根节点和后面依次传来的元素进行比较                if (cmp < 0)                    t = t.left;                else if (cmp > 0)                    t = t.right;                else                    return t.setValue(value);            } while (t != null);        }                //存储元素        Entry<K,V> e = new Entry<>(key, value, parent); //创建新的键值对象        if (cmp < 0)            parent.left = e;        else            parent.right = e;        fixAfterInsertion(e);        size++;        modCount++;//将元素分别依次取出来        return null;    }}结论:对于TreeSet集合要实现自然排序,那么该集合该集合中存储自定义类型必须实现一个接口:Comparable,并且重写该接口中的compareTo()方法使用TreeSet集合存储自定义对象并遍历


d. 比较器排序

(1)实现方式:有参构造:public TreeSet(Comparator<E> comparator)

(2)使用方法: 1)方式1:自定义一个类,类实现Comparator接口,作为子实现类

package org.westos_06;import java.util.Comparator;//MyComparatpr是Comparator接口的子实现类public class MyComparator implements Comparator<Student> {@Overridepublic int compare(Student s1, Student s2) {//return 0;//按照学生姓名长度从小到大进行排序//int num = this.name.lengt()-s.name.length();//this--:s1//s---:s2int num = s1.getName().length() - s2.getName().length() ;//次要条件:姓名长度一样,还要比较姓名的内容是否一样int num2 = num==0 ? s1.getName().compareTo(s2.getName()): num ;//姓名长度和内容都一样,还需比较两个人的年龄是否一样int num3 = num2 ==0 ? s1.getAge() - s2.getAge() : num2 ;return num3 ;}}

     2)可以使用接口的匿名内部类来实现:开发中,由于减少代码书写量,不需要自定义接口的子实现类,直接这种格式

new 接口名或者类名(){

重写方法()

}

//TreeSet<Student> ts = new TreeSet<Student>(new MyComparator()) ;TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {@Overridepublic int compare(Student s1, Student s2) {//return 0;int num = s1.getName().length() - s2.getName().length() ;//次要条件:姓名长度一样,还要比较姓名的内容是否一样int num2 = num==0 ? s1.getName().compareTo(s2.getName()): num ;//姓名长度和内容都一样,还需比较两个人的年龄是否一样int num3 = num2 ==0 ? s1.getAge() - s2.getAge() : num2 ;return num3 ;}}) ;