javaSE-(Collection)


  |-- List(列表):有索引,允许重复元素
  |-- Set(集)   :没有索引,不允许重复元素
  • 【java.util.List】

    ArrayList:底层数据结构是数组,数组的物理地址是连续的,可以通过位置快速定位到具体元素的地址,所以改查效率高 
    但是如果是增加和删除元素时,可能会涉及到新建数组,复制元素,移动元素等操作,比较耗时,所以增删效率低

    LinkedList:底层是靠节点相连的双向循环链表,物理地址不连续, 
    必须依靠头尾节点不断寻址,找到目标位置,而寻址的过程比较耗时,所以改查效率低; 
    而增删的时候只需要找到目标位置进行断开和连接节点的操作即可,所以增删效率高;


1.ArrayList

import java.util.ArrayList;
import java.util.Iterator;

/**
 * ArrayList
 * @author yujie
 *
 */
public class SN1_ArrayList {
    public static void main(String[] args) {
        // 1.构造一个初始容量为 10 的空列表——ArrayList
        ArrayList<Object> arrayList = new ArrayList<>();
        // 2.链表内添加数据(可以是数字、字符串、或者对象)
        for (int i = 0; i < 10; i++) {
            arrayList.add("小" + i);
        }
        // 3.显示列表内容
        for (int i = 0; i < arrayList.size(); i++) {
            System.out.print(arrayList.get(i) + " ");
        }
        System.out.println();
        // 4.删除小3
        arrayList.remove(3);
        // 5.添加一个 小A 在 小2 后面
        arrayList.add(3, "小A");
        // 6.修改小A的名字为小B
        arrayList.set(3, "小B");
        // 7.返回包含此列表中所有元素的数组
        Object[] array = arrayList.toArray();
        // 8.返回此列表中的元素数
        System.out.println("元素数: " + arrayList.size());
        // 9.判断链表是否包含 小8
        System.out.println(arrayList.contains("小8"));
        /**
         * 迭代器iterator
         */
        Iterator<Object> iterator = arrayList.iterator();
        while (iterator.hasNext()) {
            Object next = iterator.next();
            System.out.print(next+" ");
        }
        System.out.println();

        // 注意:删除链表不能使用普通for循环方法,需要使用迭代器,如下删除小1:
        Iterator<Object> it = arrayList.iterator();
        while (it.hasNext()) {
            Object next = it.next();
            if("小1".equals(next)) it.remove();
        }
        // 显示方法也可以使用如下
        for (Object s : arrayList) {
            System.out.print(s+" ");
        }

    }
}


演示: 
这里写图片描述


2.LinkedList

import java.util.LinkedList;

/**
 * LinkedList
 * @author yujie
 *
 */
public class SN2_LinkedList {
    public static void main(String[] args) {
        // 1.构造一个初始容量为 10 的空列表——ArrayList
        LinkedList<Object> linkedList = new LinkedList<>();
        // 2.链表内添加数据(可以是数字、字符串、或者对象)
        for (int i = 0; i < 10; i++) {
            linkedList.add("小" + i);
        }
        // 3.显示列表内容
        for (int i = 0; i < linkedList.size(); i++) {
            System.out.print(linkedList.get(i) + " ");
        }
        System.out.println();
        // 4.删除小3
        linkedList.remove(3);
        // 5.添加一个 小A 在 小2 后面
        linkedList.add(3, "小A");
        // 6.修改小A的名字为小B
        linkedList.set(3, "小B");
        // 7.返回包含此列表中所有元素的数组
        Object[] array = linkedList.toArray();
        // 8.返回此列表中的元素数
        System.out.println("元素数: " + linkedList.size());
        // 9.获取链表第一个元素和最后一个元素
        System.out.println("第一个:" + linkedList.getFirst() + " 最后一个:" + linkedList.getLast());
        // 10.判断链表是否包含 小8
        System.out.println(linkedList.contains("小8"));
        //11.移除并返回此列表的第一个元素。
        System.out.println(linkedList.removeFirst());
        System.out.println(linkedList.getFirst());

    }
}

演示:这里写图片描述


3. Collections工具类

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
/**
 * Collections工具类
 *
 */
public class SN3_Collections {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            list.add((int)(Math.random()*100));
            System.out.print(list.get(i)+" ");
        }
        //升序排序
        Collections.sort(list);
        //反转
        Collections.reverse(list);
        //打乱
        Collections.shuffle(list);
        //交换
        Collections.swap(list, 1, 2);
    }
}




Set集合

使用Set集合的主要原因是因为Set集合里面没有重复的元素。

Set集合有三个常见的实现类:HashSet,TreeSet,LinkedHashSet。

简单的说,如果你关注性能,应该使用HashSet

如果你需要一个有序的Set集合,应该使用TreeSet

如果你需要一个Set集合保存了原始的元素插入顺序,应该使用LinkedHashSet

Set接口

Set接口继承Collection接口。Set集合不允许里面存在重复元素,每个元素都必须是唯一的。你只需要往Set集合简单的添加元素,重复元素会被自动移除

HashSet,TreeSet,LinkedHashSet对比

  HashSet是基于散列表实现的,元素没有顺序;add、remove、contains方法的时间复杂度为O(1)。(contains为false时,就直接往集合里存)

  TreeSet是基于树实现的(红黑树),元素是有序的;add、remove、contains方法的时间复杂度为O(log (n))(contains为false时,插入前需要重新排序)。

因为元素是有序的,它提供了若干个相关方法如first(), last(), headSet(), tailSet()等;

  LinkedHashSet介于HashSet和TreeSet之间,是基于哈希表链表实现的,支持元素的插入顺序;基本方法的时间复杂度为O(1);

TreeSet例子

TreeSet<Integer>tree=newTreeSet<Integer>();

tree.add(12);tree.add(63);tree.add(34);tree.add(45);Iterator<Integer> iterator = tree.iterator();System.out.print("Tree set data: ");while (iterator.hasNext()) {    System.out.print(iterator.next() + " ");}

结果:Tree setdata:12 34 45 63

现在,我们换个元素类型,在进行插入,首先定义一个Dog类,如下class Dog {

   intsize;

   publicDog(int s) {

       size=s;

   }

   public String toString() {

       return size+ "";

   }

}

public class Q17 {

   public static void main(String[] args) {

       TreeSet<Dog>dset= newTreeSet<Dog>();

       dset.add(newDog(2));

       dset.add(newDog(1));

       dset.add(newDog(3));

       Iterator<Dog>iterator=dset.iterator();

       while(iterator.hasNext()){

           System.out.print(iterator.next()+"");

       }

   }

}

报错:Exceptioninthread"main"java.lang.ClassCastException: simplejava.Dog cannotbecasttojava.lang.Comparable

因为TreeSet是有序的,Dog类需要实现java.lang.Comparable接口的compareTo(),如下:

class Dog implements Comparable{

   int size;

   public Dog(int s) {

       size=s;

   }

   public String toString() {

       returnsize+ "";

   }

   @Override

   public int compareTo(Dog o) {

   return size - o.size;

   }

}

输出:1 2 3

HashSet例子排序

HashSet<Dog> dset = newHashSet<Dog>();

dset.add(new Dog(2));

dset.add(new Dog(1));

dset.add(new Dog(3));

dset.add(new Dog(5));

dset.add(new Dog(4));

Iterator<Dog>iterator = dset.iterator();

while(iterator.hasNext()) {

      System.out.print(iterator.next() + " ");

}

结果:5 3 2 1 4

排序:HashSet排序Set<Object> set = new HashSet<Object>();          set.add("aaa");        set.add("ccc");        set.add("bbb");System.out.println(sortByValue(set));//set转ArrayList,利用sort排序public static Set<Object> sortByValue(Set<Object> set){    List<Object> setList= new ArrayList<Object>(set);    Collections.sort(setList,new Comparator<Object>(){        public int compare(Objecto1,Object o2) {            return o1.toString().compareTo(o2.toString());        }    });    set = new LinkedHashSet<Object>(setList);//这里注意使用LinkedHashSet(TreeSet存还要排序)    return set;}

LinkedHashSet例子

LinkedHashSet<Dog>dset = newLinkedHashSet<Dog>();

dset.add(new Dog(2));

dset.add(new Dog(1));

dset.add(new Dog(3));

dset.add(new Dog(5));

dset.add(new Dog(4));

Iterator<Dog>iterator= dset.iterator();

while(iterator.hasNext()) {

   System.out.print(iterator.next()+" ");

}

结果:2 1 35 4

性能测试(add方法)

Random r= newRandom();

HashSet<Dog>hashSet = new HashSet<Dog>();

TreeSet<Dog>treeSet = new TreeSet<Dog>();

LinkedHashSet<Dog>linkedSet= new LinkedHashSet<Dog>();

// start time

long startTime = System.nanoTime();

for (inti = 0; i < 1000; i++){

int x =r.nextInt(1000 - 10) + 10;

hashSet.add(new Dog(x));

}

// end time

 

long endTime = System.nanoTime();

long duration =endTime - startTime;

System.out.println("HashSet:" + duration);

// start time

startTime= System.nanoTime();

for (inti = 0; i < 1000; i++){

int x =r.nextInt(1000 - 10) + 10;

treeSet.add(new Dog(x));

}

// end time

endTime= System.nanoTime();

duration = endTime - startTime;

System.out.println("TreeSet:" + duration);

// start time

startTime= System.nanoTime();

for (inti = 0; i < 1000; i++){

int x =r.nextInt(1000 - 10) + 10;

linkedSet.add(new Dog(x));

}

// end time

endTime= System.nanoTime();

duration = endTime - startTime;

System.out.println("LinkedHashSet:" + duration);

结果是:HashSet最好,TreeSet最差

 

/**一、是迭代遍历:*/Set<String> set = new HashSet<String>();Iterator<String> it = set.iterator();while (it.hasNext()) {  String str = it.next();  //it.remove();  System.out.println(str);}/** "只有" 用iterator遍历时才可以进行删除元素*//**二、for循环遍历:*/for (String str : set) {      System.out.println(str);}/**优点还体现在泛型 假如 set中存放的是Object*/Set<Object> set = new HashSet<Object>();/**for循环遍历:*/for (Object obj: set) {   if(obj instanceof Integer){       int aa= (Integer)obj;   }else if(obj instanceof String){       String aa = (String)obj   }          ........}



如何根据对象的属性,对集合(list / set)中的对象进行排序

7
  • 48

通过java.util.Collections的sort方法,有2个参数,第一个参数是list对象,第二个参数是new Comparator<对象类>(){}方法,这个方法实现了compare()方法,具体代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package  test2;
import  java.util.ArrayList;
import  java.util.Collections;
import  java.util.Comparator;
import  java.util.List;
 
public  class  ListSort {
  
     public  static  void  main(String[] args) {
         List<Person> personList =  new  ArrayList<Person>();
         personList.add( new  Person( "王五" , 32 )) ;
         personList.add( new  Person( "张三" , 30 )) ;
         personList.add( new  Person( "赵六" , 33 )) ;
         personList.add( new  Person( "李四" , 31 )) ;
         personList.add( new  Person( "孙七" , 33 )) ;
          
         Collections.sort(personList,  new  Comparator<Person>() {
             @Override
             public  int  compare(Person p1, Person p2) {
                 if (p1.age>p2.age){
                     return  1 ;
                 }
                 else  if (p1.age<p2.age){
                     return  0 ;
                 }
                 else {
                     return  p1.name.compareTo(p2.name) ;  // 调用String中的compareTo()方法
                 }
             }
         });
         System.out.println(personList);
     }
  
}
 
class  Person {
     public  String name ;
     public  int  age ;
     
     public  Person(String name, int  age){
         this .name = name ;
         this .age = age ;
     }
     public  String toString(){
         return  "姓名:"  this .name +  ";年龄:"  this .age ;
     }
}

代码执行的结果为:

  [姓名:张三;年龄:30, 姓名:李四;年龄:31, 姓名:王五;年龄:32, 姓名:孙七;年龄:33, 姓名:赵六;年龄:33]



二:针对set

     要排序的对象所属的类implements  Comparable接口,重写了compareTo()方法,具体代码如下所示:


package test1;
import java.util.Set ;
import java.util.TreeSet ;

public class TreeSetDemo4{
    public static void main(String args[]){
        Set<Person> allSet = new TreeSet<Person>() ;
        allSet.add(new Person("赵六",33)) ;
        allSet.add(new Person("张三",30)) ;
        allSet.add(new Person("王五",32)) ;
        allSet.add(new Person("李四",31)) ;
        allSet.add(new Person("孙七",33)) ;
        System.out.println(allSet) ;
    }
}

class Person implements Comparable<Person>{
    private String name ;
    private int age ;
    
    public Person(String name,int age){
        this.name = name ;
        this.age = age ;
    }
    public String toString(){
        return "姓名:" + this.name + ";年龄:" + this.age ;
    }
    public int compareTo(Person per){
        if(this.age>per.age){
            return 1 ;
        }else if(this.age<per.age){
            return -1 ;
        }else{
            return this.name.compareTo(per.name) ; // 调用String中的compareTo()方法
        }
    }
}

代码执行的结果为:

  [姓名:张三;年龄:30, 姓名:李四;年龄:31, 姓名:王五;年龄:32, 姓名:孙七;年龄:33, 姓名:赵六;年龄:33]



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值