Java07-java集合

Java集合

java根据存储元素以及取出元素的特点不同,提供不同存储容器,统称为集合 

 一、数据结构

1.1、栈 

栈是一种特殊的线性表,只允许在栈的一段(栈顶)进行操作,其特点是先进后出、后进先出。

1.2、队列

队列和栈一样是一种线性表,其允许在栈的一端可以进行入队操作,在栈的另一端可以进行出队操作,特点是先进先出。

1.3、数组

数组是有序元素的序列,在内存中的分配是连续的,有索引概念,特点是查询快、增删慢。

1.4、链表

链表是由一系列节点组成,节点包含数据域和指针域,按照链表的指向又分为单向链表、双向链表、循环链表等,链表的特点是查询慢、增删快。

1.5、树

树是由n(n>=1)个节点组成的有层次的集合,特点有:

1)、每个节点有0个或多个子节点。

2)、没有父节点的节点称为根节点。

3)、每一个非根节点有且只有一个父节点。

4)、除了根节点外,每个子节点可以分为多个不相交的子树。

5)、右子树永远比左子树大,读取顺序为从左到右。

1.6、哈希表

哈希表又叫散列表,由键(key)和值(value)进行直接访问的一种数据结构,通过key和value映射到集合的某个位置,访问该位置上的元素。

1.7、图

图是一系列顶点的集合,顶点之间通过边进行连接,图分为无向图和有向图:

1)、无向图:边仅仅连接两个顶点,没有其他含义。

2)、有向图:边不仅连接两个顶点,并且具有方向。

二、集合体系

2.1、Collection(接口)

 集合是一组被称为其元素的对象,collection是一个接口无法直接对其创建对象,若想要使用collection中的方法可以实现其子接口(list和set)的具体子类

2.1.1、list

特点:元素有序且可以发生重复的集合,有索引下标的概念。

1)、ArrayList

底层数据结构是数组,查询快,增删慢,线程不安全的,效率高。

//创建List集合对象
List ls1 = new ArrayList;

//创建元素对象

Student s1 = new Student("zhangsan","21");
Student s2 = new Student("lisi","22");
Student s3 = new Student("wangwu","23");

将元素添加到List集合

ls1.add(s1);
ls1.add(s2);
ls1.add(s3);

void add(int index,Object element) 指定位置索引添加元素到集合中

//将s5添加在s2和s3之间
Student s5 = new Student("zzz", 20);
ls1.add(2,s5);

E remove(int index) 指定索引删除某个元素,返回被删除的元素 

//o 接收返回值
Object o = ls1.remove(2);
System.out.println("被删除的是: "+o);

Object get(int index) 根据索引获取集合中的元素对象

Object o = ls1.get(2);
System.out.println(o);

 Object set(int index,Object element) 指定位置索引,修改元素,返回原本位置上的元素对象

Student s6 = new Student("www", 31);
Object o = ls1.set(2, s6);
System.out.println("原数据为: "+o);

一个迭代器对象只有一个游标可以移动 ,ListIterator listIterator() List集合专有的迭代器

//listIterator()通过观察子类源码发现,底层是返回了一个ListItr类的对象
//ListItr类是继承自Itr类,也拥有hasNext()和next()方法
ListIterator listIterator = ls1.listIterator();
while (listIterator.hasNext()){
     Object o1 = listIterator.next();
     System.out.println(o1);
}
2)、Vector 

底层数据结构是数组,查询快,增删慢,线程安全的,效率低

3)、LinkedList

底层数据结构是双链表,增删快,查询慢,线程不安全的,效率高。

LinkedList类特有功能:
   public void addFirst(E e)及addLast(E e)
   public E getFirst()及getLast()
   public E removeFirst()及public E removeLast()
//public void addFirst(E e)及addLast(E e) 在List集合开头和结尾添加元素
ls1.addFirst("小胡");
ls1.addLast("小花"); 

//public E getFirst()及getLast() 获取List集合第一个和最后一个元素
System.out.println(ls1.getFirst());
System.out.println(ls1.getLast());

//public E removeFirst()及public E removeLast() 删除List集合第一个和最后一个元素
System.out.println(ls1.removeFirst());
System.out.println(ls1.removeLast());
2.1.2、Set

元素唯一且无序,没有索引

1)、HashSet

底层数据结构是哈希表

//创建set集合对象
HashSet<Student> set1 = new HashSet<>();
//创建元素对象
Student s1 = new Student("zhangsan",10);
Student s2 = new Student("lisi",12);
Student s3 = new Student("wangwu",13);

将元素添加到set集合

set1.add(s1);
set1.add(s2);
set1.add(s3);
2)、LinkedHashSet

 继承自HashSet类, 底层数据结构是哈希表和双链表,哈希表保证了元素的唯一性,双链表保证了元素的有序

3)、TreeSet

底层数据结构是红黑树,存在两种排序方式:自然排序和比较器排序

public class TreeSetTest {
    public static void main(String[] args) {
        //创建键盘录入对象
        Scanner sc = new Scanner(System.in);

        //创建TreeSet集合
        TreeSet<Student> set1 = new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                //显式条件:按照总分从高到低输出到控制台
                int i = o2.getSumScore() - o1.getSumScore();
                //隐式条件
                //总分一样,各科的分数不一定一样
                //总分一样,语文成绩不一定一样
                int i2 = (i == 0) ? o2.getChinese() - o1.getChinese() : i;
                //总分,语文成绩一样,数学成绩不一定一样
                int i3 = (i2 == 0) ? o2.getMath() - o1.getMath() : i2;
                //各科分数都一样,姓名不一定一样
                return (i3 == 0) ? o2.getName().compareTo(o1.getName()) : i3;
            }
        });

        Student student;

        for (int i = 1; i <= 5; i++) {
            System.out.println("请输入第 "+i+" 个学生的信息:");
            System.out.print("姓名:");
            String name = sc.next();
            System.out.print("语文成绩:");
            int chinese = sc.nextInt();
            System.out.print("数学成绩:");
            int math = sc.nextInt();
            System.out.print("英语成绩:");
            int english = sc.nextInt();

            //创建一个学生对象,将当前学生的信息进行封装
            student = new Student(name,chinese,math,english);

            //将学生对象添加到集合中
            set1.add(student);

            System.out.println("----------------------------");
        }
        System.out.println("所有学生信息添加完毕!具体信息如下:");
        System.out.println("姓名\t\t语文成绩\t\t数学成绩\t\t英语成绩\t\t英语成绩");
        //遍历集合
        for (Student student1 : set1) {
            System.out.println(student1.getName()+"\t\t"+student1.getChinese()+"\t\t"+student1.getMath()+"\t\t"+student1.getEnglish()+"\t\t"+student1.getSumScore());
        }


    }
}

 两种排序方式:

自然排序:使用无参构造方法创建TreeSet集合对象,要求元素类实现Comparable<元素类>接口,重写compareTo方法。

Comparable接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序。
实现Comparable的类必须实现 compareTo(Object obj) 方法,两个对象即通过compareTo(Object obj)方法的返回值来比较大小。如果当前对象this大于形参对象obj,则返回正整数,如果当前对象this小于形参对象obj,则返回负整数,如果当前对象this等于形参对象obj,则返回零。
实现Comparable接口的对象列表(和数组)可以通过 Collections.sort 或 Arrays.sort进行自动排序。

class Student implements Comparable { 
   private String name;
	private Integer age;

  @Override 
  public int compareTo(Object o) { 
  	   //下面那一片代码都可以用注释这个代替,因为age可以直接比较大小
  	   //为了写的更详细,所以展开弄得
  	   //return this.age.compareTo(o.getAge());
    if(o instanceof Student) { 
      Student other = (Student) o; 
      if (this.age > other.age) {
        return 1; 
      } else if (this.age < other.age) { 
        return -1;
      } 
      return 0;
     } 
     throw new RuntimeException("输入的数据类型不一致");
   } //构造器、getter、setter、toString()方法略
}

比较器排序:使用有参构造方法创建TreeSet集合对象,将实现了Comparator接口且重写compare方法的对象当作构造方法的参数使用。

当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码,或者实现了java.lang.Comparable接口的排序规则不适合当前的操作,那么可以考虑使用 Comparator的对象来排序,强行对多个对象进行整体排序的比较
重写compare(Object o1,Object o2)方法,比较o1和o2的大小:如果方法返 回正整数,则表示o1大于o2;如果返回0,表示相等;返回负整数,表示 o1小于o2
可以将 Comparator传递给 sort方法(如 Collections.sort或 Arrays.sort), 从而允许在排序顺序上实现精确控制。

public static void main(String[] args) {

		TestA testA1 = new TestA("老张", 3);
		TestA testA2 = new TestA("老李", 1);
		TestA testA3 = new TestA("老王", 2);
		List<TestA> list  = new ArrayList<>();
		list.add(testA1);
		list.add(testA2);
		list.add(testA3);
		System.out.println("排序前--:"+list.toString());
		Collections.sort(list, new Comparator<TestA>() {
            @Override
            public int compare(TestA o1, TestA o2) {
                //升序
                return o1.getAge().compareTo(o2.getAge());
            }
        });
		System.out.println("升序排序后--:"+list.toString());
		
		Collections.sort(list, new Comparator<TestA>() {
            @Override
            public int compare(TestA o1, TestA o2) {
                //降序
                return o2.getAge().compareTo(o1.getAge());
            }
        });
		System.out.println("降序排序后--:"+list.toString());
	}

2.2、Map(接口)

HashMap(由键决定特点):无序、不重复、无索引。(用的最多)
LinkedHashMap (由键决定特点):由键决定的特点:有序、不重复、无索引。
TreeMap(由键决定特点):按照大小默认升序排序、不重复、无索引。

2.2.1、创建方法
    //创建Map集合的对象
        Map<String,String> m= new HashMap<>();
        //2.添加元素
        //put方法的细节:
        //添加/覆盖
    //在添加数据的时候,如果键不存在,那么直接把键值对对象添加到map集合当中,方法返回nu11
    //在添加数据的时候,如果键是存在的,那么会把原有的键值对对象覆盖,会把被覆盖的值进行返回。
        m.put("白月初","苏苏");
        m.put("东方月初","红红");
        m.put("戴沐白","朱竹清");
 
        String value = m.put("白月初", "涂山苏苏");
        System.out.println(value);//返回覆盖的值 苏苏
 
    //删除
        String result = m.remove("东方月初");
        System.out.println(result); //返回 删除键的值 红红
 
    //清空
    //m.clear();
 
    //判断是否包含键
        boolean keyResult = m.containsKey("戴沐白");
        System.out.println(keyResult);//true
    //是否包含 值
        boolean valueResult = m.containsValue("朱竹清");
        System.out.println(valueResult);//true
 
        boolean empty = m.isEmpty();
        System.out.println(empty);//false
 
        int size = m.size();
        System.out.println(size);//2
 
    //打印
        System.out.println(m);//{白月初=涂山苏苏, 戴沐白=朱竹清}
2.2.2、遍历方法

1)、通过键遍历集合

//创建Map集合的对象
        Map<String,String> map= new HashMap<>();
 
//添加元素
        map.put("白月初","苏苏");
        map.put("东方月初","红红");
        map.put("戴沐白","朱竹清");
//通过键找值
        //3.1获取所有的键,把这些键放到一个单列集合当中
        Set<String> keys = map.keySet();
        //3.2遍历单列集合,得到每一个键
        for (String key : keys){
            //3.3利用map集合中的键获取对应的值 get
            String value = map.get(key);
            System.out.println(key+"="+value);
        }
/* 运行结果:
白月初=苏苏
东方月初=红红
戴沐白=朱竹清
*/

2)、通过键值对遍历集合

//Map创建以及添加元素同上
//通过键值对对象进行遍历
        //3.1通过一个方法获取所有的键值对对象,返回一个Set集合
        Set<Map.Entry<String, String>> entries = map.entrySet();
        //3.2遍历entries这个集合,去得到里面的每一个键值对对象
        for (Map.Entry<String, String>entry :entries){ //entries 可以换为map.entrySet()
            //3.3利用entry调用get方法获取键和值
            String key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key+"="+value);
        }
2.2.3、TreeMap的排序方式

1)、实现Comparable接口

//创建集合
        TreeMap<Student,String>tm = new TreeMap<>();
 
//创建学生对象
        Student s1 = new Student("zhangsan",23);
        Student s3 = new Student("wangwu",25);
        Student s2 = new Student("lisi",24);
        Student s4 = new Student("lisi",24);
//添加元素
        tm.put(s1,"江苏");
        tm.put(s2,"天津");
        tm.put(s3,"北京");
        tm.put(s4,"南京");
 
//打印
        System.out.println(tm);
/*运行结果:
{Student{name = zhangsan, age = 23}=江苏, Student{name = lisi, age = 24}=南京, Student{name = wangwu, age = 25}=北京}
*/

2)、比较器排序

//Integer、Double 默认情况下都是按照升序排列的
//String 按照字母再ASCII码表中对应的数字升序排列
//创建集合对象
        TreeMap<Integer,String> tm =new TreeMap<>();
 
//添加元素
        tm.put(5,"ab");
        tm.put(4,"cd");
        tm.put(3,"ef");
        tm.put(2,"hi");
        tm.put(1,"gk");
 
        System.out.println(tm); //默认升序排序
 
//要求:按照降序排序   使用比较器对象
        TreeMap<Integer,String> tm2 =new TreeMap<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                //o1:当前要添加的元素
                //o2:表示已经在红黑树中存在的元素
                return o2-o1;
            }
        });
 
        //2.添加元素
        tm2.put(5,"ab");
        tm2.put(4,"cd");
        tm2.put(3,"ef");
        tm2.put(2,"hi");
        tm2.put(1,"gk");
 
        System.out.println(tm2);
/*运行结果:
{1=gk, 2=hi, 3=ef, 4=cd, 5=ab}
{5=ab, 4=cd, 3=ef, 2=hi, 1=gk}
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

网络!搬运工

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值