Java—集合03

  1.List接口

     此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。与 set 不同,列表通常允许重复的元素

 

它是一个元素存取有序的集合。例如,存元素的顺序是11、22、33。那么集合中,元素的存储就是按照11、22、33的顺序完成的)。

 

它是一个带有索引的集合,通过索引就可以精确的操作集合中的元素(与数组的索引是一个道理)。

 

集合中可以有重复的元素,通过元素的equals方法,来比较是否为重复的元素。

 

 

 

List接口的常用子类有:

 

 ArrayList集合

 

LinkedList集合

 

 list接口中的一些常用方法:

 add(Object e)  /  boolean:向集合末尾处,添加指定的元素

 

 add(int index, Object e)  / void:向集合指定索引处,添加指定的元素,原有元素依次后移

 

 删除元素删除

 

 remove(Object e)  / E:将指定元素对象,从集合中删除,返回值为被删除的元素

 

 remove(int index)  / E:将指定索引处的元素,从集合中删除,返回值为被删除的元素

 

 替换元素方法

 

 set(int index, Object e) / E:将指定索引处的元素,替换成指定的元素,返回值为替换前的元素

 

 查询元素方法

 

 get(int index) / E:获取指定索引处的元素,并返回该元素

 

方法的代码演示:

List<String> list = new ArrayList<String>();

//1,添加元素。

list.add("小红");

list.add("小梅");

list.add("小强");

//2,插入元素。插入元素前的集合["小红","小梅","小强"]

list.add(1, "老王"); //插入元素后的集合["小红","老王","小梅","小强"]

//3,删除元素。

list.remove(2);// 删除元素后的集合["小红","老王","小强"]

//4,修改元素。

list.set(1, "隔壁老王");// 修改元素后的集合["小红","隔壁老王","小强"]

 

Iterator<String> it = list.iterator();

while (it.hasNext()) {

String str = it.next();

System.out.println(str);

}

由于List集合拥有索引,因此List集合迭代方式除了使用迭代器之外,还可以使用索引进行迭代。

for (int i = 0; i < list.size(); i++) {

String str = list.get(i);

System.out.println(str);

}

 

 

List集合存储数据的结构

 

ArrayList集合数据存储的结构是数组结构。元素增删慢,查找快,由于日常开发中使用最多的功能为查询数据、遍历数据,所以ArrayList是最常用的集合。

 

许多程序员开发时非常随意地使用ArrayList完成任何需求,并不严谨,这种用法是不提倡的。

LinkedList集合数据存储的结构是链表结构。方便元素添加、删除的集合。实际开发中对一个集合元素的添加与删除经常涉及到首尾操作。

LinkedList是List的子类,List中的方法LinkedList都是可以使用,这里就不做详细介绍,我们只需要了解LinkedList的特有方法即可。在开发时,LinkedList集合也可以作为堆栈,队列的结构使用。

 代码演示:

LinkedList<String> link = new LinkedList<String>();

 

//添加元素

 

link.addFirst("abc1");

 

link.addFirst("abc2");

 

link.addFirst("abc3");

 

//获取元素

 

System.out.println(link.getFirst());

 

System.out.println(link.getLast());

 

//删除元素

 

System.out.println(link.removeFirst());

 

System.out.println(link.removeLast());

 

 

 

while(!link.isEmpty()){ //判断集合是否为空

 

System.out.println(link.pop()); //弹出集合中的栈顶元素

 

       }

 

 

2.Set接口

  List中是可以存放重复元素的。那么不重复元素给哪里存放呢?那就是Set接口,它里面的集合,所存储的元素就是不重复的。

 

  HashSet集合

此类实现Set接口,由哈希表支持(实际上是一个 HashMap集合)。HashSet集合不能保证的迭代顺序与元素存储顺序相同。

 

HashSet集合,采用哈希表结构存储数据,保证元素唯一性的方式依赖于:hashCode()与equals()方法。

 当向哈希表中存放元素时,需要根据元素的特有数据结合相应的算法,这个算法其实就是Object类中的hashCode方法。由于任何对象都是Object类的子类,所以任何对象有拥有这个方法。即就是在给哈希表中存放对象时,会调用对象的hashCode方法,算出对象在表中的存放位置,这里需要注意,如果两个对象hashCode方法算出结果一样,这样现象称为哈希冲突,这时会调用对象的equals方法,比较这两个对象是不是同一个对象,如果equals方法返回的是true,那么就不会把第二个对象存放在哈希表中,如果返回的是false,就会把这个值存放在哈希表中。

 总结:保证HashSet集合元素的唯一,其实就是根据对象的hashCode和equals方法来决定的。如果我们往集合中存放自定义的对象,那么保证其唯一,就必须复写hashCode和equals方法建立属于当前对象的比较方式。

 

代码演示:

创建HashSet集合,存储String对象。

public class HashSetDemo {

public static void main(String[] args) {

//创建HashSet对象

HashSet<String> hs = new HashSet<String>();

//给集合中添加自定义对象

hs.add("zhangsan");

hs.add("lisi");

hs.add("wangwu");

hs.add("zhangsan");

//取出集合中的每个元素

Iterator<String> it = hs.iterator();

while(it.hasNext()){

String s = it.next();

System.out.println(s);

}

}

}

输出结果如下,说明集合中不能存储重复元素:

wangwu

lisi

zhangsan

 

自定义存储HashSet代码演示:

创建自定义对象Student

public class Student {

private String name;

private int age;

public Student(String name, int age) {

super();

this.name = name;

this.age = 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;

}

@Override

public String toString() {

return "Student [name=" + name + ", 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 instanceof Student)){

System.out.println("类型错误");

return false;

}

Student other = (Student) obj;

return this.age ==  other.age && this.name.equals(other.name);

}

}

 

创建HashSet集合,存储Student对象。

public class HashSetDemo {

public static void main(String[] args) {

//创建HashSet对象

HashSet hs = new HashSet();

//给集合中添加自定义对象

hs.add(new Student("zhangsan",21));

hs.add(new Student("lisi",22));

hs.add(new Student("wangwu",23));

hs.add(new Student("zhangsan",21));

//取出集合中的每个元素

Iterator it = hs.iterator();

while(it.hasNext()){

Student s = (Student)it.next();

System.out.println(s);

}

}

}

输出结果如下,说明集合中不能存储重复元素:

Student [name=lisi, age=22]

Student [name=zhangsan, age=21]

Student [name=wangwu, age=23]

 

 

 

 

LinkedHsahSet

 

HashSet保证元素唯一,可是元素存放进去是没有顺序的,那么我们要保证有序,怎么办呢?

 

HashSet下面有一个子类LinkedHashSet,它是链表和哈希表组合的一个数据存储结构。

代码演示:

public class LinkedHashSetDemo {

public static void main(String[] args) {

Set<String> set = new LinkedHashSet<String>();

set.add("bbb");

set.add("aaa");

set.add("abc");

set.add("bbc");

Iterator it = set.iterator();

while (it.hasNext()) {

System.out.println(it.next());

}

}

}

输出结果如下,LinkedHashSet集合保证元素的存入和取出的顺序:

bbb

aaa

abc

bbc

 

 

3.Map接口

 Collection中的集合,元素是孤立存在的(理解为单身),向集合中存储元素采用一个个元素的方式存储。

 Map中的集合,元素是成对存在的(理解为夫妻)。每个元素由键与值两部分组成,通过键可以找对所对应的值。

 Collection中的集合称为单列集合,Map中的集合称为双列集合。

 需要注意的是,Map中的集合不能包含重复的键,值可以重复;每个键只能对应一个值。

 Map中常用的集合为HashMap集合、LinkedHashMap集合。

 

通过查看Map接口描述,看到Map有多个子类,这里我们主要讲解常用的HashMap集合、LinkedHashMap集合。

HashMap<K,V>:存储数据采用的哈希表结构,元素的存取顺序不能保证一致。由于要保证键的唯一、不重复,需要重写键的hashCode()方法、equals()方法。

LinkedHashMap<K,V>HashMap下有个子类LinkedHashMap,存储数据采用的哈希表结构+链表结构。通过链表结构可以保证元素的存取顺序一致;通过哈希表结构可以保证的键的唯一、不重复,需要重写键的hashCode()方法、equals()方法。

注意Map接口中的集合都有两个泛型变量<K,V>,在使用时,要为两个泛型变量赋予数据类型。两个泛型变量<K,V>的数据类型可以相同,也可以不同。

 

 

Map接口中常用的方法:

put方法:将指定的键与值对应起来,并添加到集合中

 方法返回值为键所对应的值

使用put方法时,若指定的键(key)在集合中没有,则没有这个键对应的值,返回null,并把指定的键值添加到集合中;

使用put方法时,若指定的键(key)在集合中存在,则返回值为集合中键对应的值(该值为替换前的值),并把指定键所对应的值,替换成指定的新值。

get方法:获取指定键(key)所对应的值(value)

 remove方法:根据指定的键(key)删除元素,返回被删除元素的值(value)。

代码演示:

public class MapDemo {

public static void main(String[] args) {

//创建Map对象

Map<String, String> map = new HashMap<String,String>();

//给map中添加元素

map.put("星期一", "Monday");

map.put("星期日", "Sunday");

System.out.println(map); // {星期日=Sunday, 星期一=Monday}

 

//当给Map中添加元素,会返回key对应的原来的value值,若key没有对应的值,返回null

System.out.println(map.put("星期一", "Mon")); // Monday

System.out.println(map); // {星期日=Sunday, 星期一=Mon}

 

//根据指定的key获取对应的value

String en = map.get("星期日");

System.out.println(en); // Sunday

 

//根据key删除元素,会返回key对应的value值

String value = map.remove("星期日");

System.out.println(value); // Sunday

System.out.println(map); // {星期一=Mon}

}

}

 

Map集合遍历键找值方式

键找值方式:即通过元素中的键,获取键所对应的值

步骤:

1.获取Map集合中所有的键,由于键是唯一的,所以返回一个Set集合存储所有的键

 

2.遍历键的Set集合,得到每一个键

 

3.根据键,获取键所对应的值

用到的方法:

KeySet() / Set(K):得到Map集合中所有的键

代码演示:

public class MapDemo {

public static void main(String[] args) {

//创建Map对象

Map<String, String> map = new HashMap<String,String>();

//给map中添加元素

map.put("邓超", "孙俪");

map.put("李晨", "范冰冰");

map.put("刘德华", "柳岩");

//获取Map中的所有key

Set<String> keySet = map.keySet();

//遍历存放所有key的Set集合

Iterator<String> it =keySet.iterator();

while(it.hasNext()){

//得到每一个key

String key = it.next();

//通过key获取对应的value

String value = map.get(key);

System.out.println(key+"="+value);

}

}

}

 

 

Entry键值对对象(结婚对象)

 

Map类设计时,提供了一个嵌套接口:Entry。Entry将键值对的对应关系封装成了对象。即键值对对象,这样我们在遍历Map集合时,就可以从每一个键值对(Entry)对象中获取对应的键与对应的值。

用到的方法:

getKey() / K:获取Entry对象中的键

 getValue() / V:获取Entry对象中的值

entrySet() /  Set<Map.Entry<K,V>>:用于返回Map集合中所有的键值对(Entry)对象,以Set集合形式返回。

 

  Map集合遍历键值对方式:

即通过集合中每个键值对(Entry)对象,获取键值对(Entry)对象中的键与值。

操作步骤与图解:

1.获取Map集合中,所有的键值对(Entry)对象,以Set集合形式返回。

2.遍历包含键值对(Entry)对象的Set集合,得到每一个键值对(Entry)对象

3.通过键值对(Entry)对象,获取Entry对象中的键与值。

 

代码演示:

public class MapDemo {

public static void main(String[] args) {

//创建Map对象

Map<String, String> map = new HashMap<String,String>();

//给map中添加元素

map.put("邓超", "孙俪");

map.put("李晨", "范冰冰");

map.put("刘德华", "柳岩");

//获取Map中的所有key与value的对应关系

Set<Map.Entry<String,String>> entrySet = map.entrySet();

//遍历Set集合

Iterator<Map.Entry<String,String>> it =entrySet.iterator();

while(it.hasNext()){

//得到每一对对应关系

Map.Entry<String,String> entry = it.next();

//通过每一对对应关系获取对应的key

String key = entry.getKey();

//通过每一对对应关系获取对应的value

String value = entry.getValue();

System.out.println(key+"="+value);

}

}

}

增强for循环遍历上述代码:

Set<Map.Entry<String,String>> entry=map.entry();

for(Map.Entry<String,String> e:map){

    String key=e.getKey();

   String value=e.getValue();

   System.out.print(key+"..."+value);

}

 

遍历Map嵌套集合(): 

public static void main(String[] args) {
        //基地
        HashMap<String, HashMap<Person,String>> oracle=
        new HashMap<String, HashMap<Person,String>>();
        //每个班级
        HashMap<Person,String> java0611=new HashMap<Person,String>();
        HashMap<Person,String> java0322=new HashMap<Person,String>();
        
        //添加班级
        java0611.put(new Person("悟空",18), "80");
        java0611.put(new Person("悟能",10), "60");
        java0322.put(new Person("唐僧",10), "90");
        java0322.put(new Person("悟净",10), "70");
        
        oracle.put("java0611", java0611);
        oracle.put("java0322", java0322);
        //遍历  keyset+增强for
        //获取所有的班级名称
        Set<String> className=oracle.keySet();
        //遍历
        for(String cls:className){
            //班级名称
            String key1=cls;
            //每个班的map集合
            HashMap<Person,String> value=oracle.get(key1);
            //获取所有key所在的集合
            Set<Person> persons=value.keySet();
            //遍历
            for(Person p:persons){
                Person key2=p;
                String value2=value.get(key2);
                System.out.println(key1+"..."+key2+"..."+value2);
            }
        }
        
        
        
        
    }

 

静态导入

 

在导包的过程中我们可以直接导入静态部分,这样某个类的静态成员就可以直接使用了。在源码中经常会出现静态导入。

 

静态导入格式:

 

import static XXX.YYY;   导入后YYY可直接使用。

代码演示:

例如:Map.Entry的访问,简化后为Entry

import static java.util.Map.Entry;

public class HashMapTest {

public static void main(String[] args) {

//1,创建hashmap集合对象。

Map<Student,String> map = new HashMap<Student,String>();

 

//取出元素。键值对方式

//Set<Map.Entry<Student, String>> entrySet = map.entrySet();

Set<Entry<Student, String>> entrySet = map.entrySet();

 

//for (Map.Entry<Student, String> entry : entrySet) {

for (Entry<Student, String> entry : entrySet) {

Student key = entry.getKey();

String value = entry.getValue();

System.out.println(key.toString()+"....."+value);

}

}

 

Collections集合工具类

Collections是集合工具类,用来对集合进行操作。部分方法如下:

public static <T> void sort(List<T> list) // 集合元素排序

//排序前元素list集合元素 [33,11,77,55]

Collections.sort( list );

//排序后元素list集合元素 [11,33,55,77]

public static void shuffle(List<?> list) //  集合元素存储位置打乱

//list集合元素 [11,33,55,77]

Collections.shuffle( list );

//使用shuffle方法后,集合中的元素为[77,33,11,55],每次执行该方法,集合中存储的元素位置都会随机打乱

 

集合继承体系的面向对象思想

 接口:用来明确所有集合中该具有的功能,相当于在定义集合功能标准;

 抽象类:把多个集合中功能实现方式相同的方法,抽取到抽象类实现,具体集合不再遍写,继承使用即可;

具体类:继承抽象类,实现接口,重写所有抽象方法,达到具备指定功能的集合。每个具体集合类,根据自身的数据存储结构方式,对接口中的功能方法,进行不同方式的实现。

 

 

 

 

 

 

 

posted on 2019-09-14 18:22  小蜘zhu  阅读(180)  评论(0编辑  收藏  举报