黑马程序员_Java基础_集合框架(四)_17

来源:互联网 发布:网络理财产品收益 编辑:程序博客网 时间:2024/04/19 13:43

                                        -------android培训、java培训、期待与您交流! ----------

 

导读:Collection(sort,max,binarySearch,替换反转,SynList),Arrays,集合转化为数组,增强for循环,可变参数,静态导入

 

1、集合(Collection-sort,max,binarySearch)

  • Collections做为一个工具类,它中的方法都是静态的。它没有构造函数是不需要创建对象的。因为它的对象中并没有去封装特有的数据。都是共享的情况下共享的最方便。我现在有一堆元素,我不需要保证唯一,要用List集合,可是我想对这里面的集合里进行排序,不能和Tree了,Tree是Set集合中的List集合中没有排序的方式,集合框架也想到了。它给你提供了工具来完成这样的动作。Collections这个对象,是专门用来对于集合进行操作的工具类。
  • java.util 中Collections<Textends Comparable<? super T>>

void sort(List<T> list):根据元素的自然顺序 对指定列表按升序进行排序。

  • List中的元素想要进行排序是不是都要进行比较,如果要是存入两个以上的学生的时候,比不了。因为学生本身不具有比较性。
  • 集合框架的工具类。
  • Collections:集合框架的工具类。里面定义的都是静态方法。
  • Collections和Collection有什么区别?
Collection是集合框架中的一个顶层接口,它里面定义了单列集合的共性方法。

Ø它有两个常用的子接口,

ØList:对元素都有定义索引。有序的。可以重复元素。

ØSet:不可以重复元素。无序。

Collections是集合框架中的一个工具类。该类中的方法都是静态的

Ø 提供的方法中有可以对list集合进行排序,二分查找等方法。

Ø 通常常用的集合都是线程不安全的。因为要提高效率。

Ø 如果多线程操作这些集合时,可以通过该工具类中的同步方法,将线程不安全的集合,转换成安全的。

  • import java.util.*;

class CollectionsDemo

{

       publicstatic void main(String[] args)

       {

              sortDemo();

       }

       //publicstatic <T> int binarySearch(List<? extends Comparable<? superT>> list,T key),如果搜索键包含在列表中,则返回搜索键的索引;否则返回 (-(插入点) - 1)。

       publicstatic void binarySearchDemo()

       {

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

              list.add("abcd");

              list.add("aaa");

              list.add("zz");

              list.add("kkkkk");

              list.add("qq");

              list.add("z");

              Collections.sort(list,newStrLenComparator());

              sop(list);

              //intindex = Collections.binarySearch(list,"aaaa");//将aaaa放在索引为1的位置上,才能保证还是有序的。结果为-2。即:-(1)-1

              //intindex = halfSearch(list,"cc");

              intindex = halfSearch2(list,"aaaa",new StrLenComparator());

              sop("index="+index);

       }

       publicstatic int halfSearch(List<String> list,String key)

       {

              intmax,min,mid;

              max= list.size()-1;

              min= 0;

              while(min<=max)

              {

                     mid= (max+min)>>1;//  /2;

                     Stringstr = list.get(mid);

                     intnum = str.compareTo(key);

                     if(num>0)

                            max= mid -1;

                     elseif(num<0)

                            min= mid + 1;

                     else

                            returnmid;

              }

              return-min-1;

       }

       publicstatic int halfSearch2(List<String> list,Stringkey,Comparator<String> cmp)   //如果List中的元素没有比较性,用比较器。

       {

              intmax,min,mid;

              max= list.size()-1;

              min= 0;

              while(min<=max)

              {

                     mid= (max+min)>>1;//  /2;

                     Stringstr = list.get(mid);

                     intnum = cmp.compare(str,key);

                     if(num>0)

                            max= mid -1;

                     elseif(num<0)

                            min= mid + 1;

                     else

                            returnmid;

              }

              return-min-1;

       }

       //publicstatic <T extends Object & Comparable<? super T>> Tmax(Collection<? extends T> coll)

       publicstatic void maxDemo()

       {

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

              list.add("abcd");

              list.add("aaa");

              list.add("zz");

              list.add("kkkkk");

              list.add("qq");

              list.add("z");

              Collections.sort(list);

              sop(list);

              Stringmax = Collections.max(list/*,new StrLenComparator()*/);

              sop("max="+max);   //打印结果:max=zz

       }

       publicstatic void sortDemo()

       {

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

              list.add("abcd");

              list.add("aaa");

              list.add("zz");

              list.add("kkkkk");

              list.add("qq");

              list.add("z");

              sop(list);

              //Collections.sort(list);       //它不能给Set排序,因为Set有TreeSet。publicstatic <T extends Comparable<? super T>> void sort(List<T>list)

            Collections.sort(list,newStrLenComparator()); //如果不想用自然排序,可以传进来一个比较器。public static <T> voidsort(List<T> list,Comparator<? super T> c)

              //Collections.swap(list,1,2); //交换第一个元素和第二个元素中的内容。

              sop(list);

       }

       publicstatic void sop(Object obj)

       {

              System.out.println(obj);

       }

}

class StrLenComparator implementsComparator<String>

{

       publicint compare(String s1,String s2) //对象比大小,不是compareTo()就是compare

       {

              if(s1.length()>s2.length())

                     return1;

              if(s1.length()<s2.length())

                     return-1;

              returns1.compareTo(s2);

       }

}

/*

class Student

{

}

list.add(new Student());

//加泛型的目的就是为了编译的时候更安全,在编译时期做了限定。T可以任意,但是你必须具备比较性。因此T必须是Comparable的子类。一般Comparable和Comparator的后面都是super,因为接收的时候可以接收很多子类进来,用父类方法比。

public static <T extends Comparable<?super T>> void sort(List<T> list)

{

}

*/

 

2、集合(Collections-替换反转)

  • 一定要想集合框架那个工具类有没有提供这个方法,如果没有我才干这件事,如果有,我打死都不干。static <T>Comparator<T>
  • reverseOrder():返回一个比较器,它强行逆转实现了 Comparable 接口的对象 collection 的自然顺序。传进来一个逆项的比较器。reverseOrder返回的是一个比较器。
  • import java.util.*;

class StrComparator implementsComparator<String>

{

       publicint compare(String s1,String s2)

       {

              /*

              intnum = s1.compareTo(s2);  //s1和s2比较是正着的

              if(num>0)

                     return-1;

              if(num<0)

                     return1;

              returnnum;

              */

              returns2.compareTo(s1);          //s2和要s1比是正着的。

       }

}

class StrLenComparator implementsComparator<String>

{

       publicint compare(String s1,String s2)

       {

              if(s1.length()>s2.length())         //按照长度排

                     return1;

              if(s1.length()<s2.length())

                     return -1;

              returns1.compareTo(s2);         //长度按照相同的话,按照字母来排。

       }

}

class CollectionsDemo2

{

       publicstatic void main(String[] args)

       {

              shuffleDemo();

       }

       publicstatic void shuffleDemo()

       {

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

              list.add("abcd");

              list.add("aaa");

              list.add("zz");

              list.add("kkkkk");

              list.add("qq");

              list.add("z");

              sop(list);

              Collections.shuffle(list); //将集合中的元素随机的顺序进行排放。

              sop(list);

       }

       publicstatic void orderDemo()

       {

              TreeSet<String>ts = new TreeSet<String>(Collections.reverseOrder(newStrLenComparator())); //static <T> Comparator<T> reverseOrder(Comparator<T>cmp):返回一个比较器,它强行逆转指定比较器的顺序。结果为:将长度的比较器输出的结果,逆转,即长度最长的在最上面,最短的在最下面。

              ts.add("abcde");

              ts.add("aaa");

              ts.add("k");

              ts.add("cc");

              Iteratorit = ts.iterator();

              while(it.hasNext())

              {

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

              }

       }

       publicstatic void replaceAllDemo()

       {

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

              list.add("abcd");

              list.add("aaa");

              list.add("zz");

              list.add("kkkkk");

              sop(list);

              Collections.replaceAll(list,"aaa","pp");

              //List是按角标替换,replaceAll()可以按照内容替换。实际里面是按set(index,“pp”);封装,按角标找到元素后替换。static <T> Boolean replaceAll(List<T>list, T oldVal, T newVal):使用另一个值替换列表中出现的所有某一指定值。

              sop(list);

              Collections.reverse(list); //static void reverse(List<?> list):反转指定列表中元素的顺序。它实际用的是static void swap(List<?> list, int i,int j):在指定列表的指定位置处交换元素。

              sop(list);

       }

       /*

       练习。fill方法可以将list集合中所有元素替换成指定元素。

       ,将list集合中部分元素替换成指定元素。

       */

       publicstatic void fillDemo()

       {

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

              list.add("abcd");

              list.add("aaa");

              list.add("zz");

              list.add("kkkkk");

              sop(list);

              Collections.fill(list,"pp");   

//将集合中的元素全部替换成pp。static <T> void fill(List<? superT> list, T obj):使用指定元素替换指定列表中的所有元素。

              sop(list);

       }

       publicstatic void sop(Object obj)

       {

              System.out.println(obj);

       }

}

 

3、集合(Collections-SynList)(代码见上面)

  • 集合中那么多的对象,它们都有一个共同的特点,那就是线程不安全。如是真的用到多线程的话,怎么办?自己加锁很麻烦,添加有一个方法,删除有一个方法,你是不是要把它的方法都添加到一个锁中去。在某一个时刻只能有一个线程进行添加或者删除动作。
  • static <T> List<T> synchronizedList(List<T>list):返回指定列表支持的同步(线程安全的)列表。

static <K,V> Map<K,V> synchronizedMap(Map<K,V>m):返回由指定映射支持的同步(线程安全的)映射。

static <T> Set<T> synchronizedSet(Set<T>s):返回指定 set 支持的同步(线程安全的)set。

  • 它们的底层是怎么实现的?

应用内部类,在添加,删除等方法的的前面加上了synchronized

 

4、集合(Arrays)

Ø binarySearch():二分法查找

Ø copyOf():数组复制

Ø copyOfRange:将数组中的指定范围复制到一个新的数组。

Ø equals():比较两个数组中的内容中否相同。

Ø deepEquals():不仅比较数组,还比较数组中元素的内容。

Ø fill():替换数组中的值。(可以替换数组中的一个范围)

Ø sort():排序。(还可以局部排序)

Ø toString():转化这字符串。

  • Arrays:用于操作数组的工具类。[此类包含用来操作数组(比如排序和搜索)的各种方法]
  • 里面都是静态方法。
  • asList:将数组变成list集合
  • import java.util.*;

class ArraysDemo

{

       publicstatic void main(String[] args)

       {

//            int[]arr = {2,4,5};

//            System.out.println(Arrays.toString(arr));

              String[]arr = {"abc","cc","kkkk"};

              /*

把数组变成list集合有什么好处?

              可以使用集合的思想和方法来操作数组中的元素。(操作起来也比较方便)

              注意:将数组变成集合,不可以使用集合的增删方法。

                 因为数组的长度是固定。

              contains。

              get

              indexOf()

              subList();

              如果你增删。那么会反生UnsupportedOperationException,

              */

              List<String>list = Arrays.asList(arr); //住这里面放字符串可以。//sop("contains:"+list.contains("cc"));

              //list.add("qq");//UnsupportedOperationException,不能增删

              //sop(list);

              //int[]nums = {2,4,5};

              Integer[]nums = {2,4,5};

              List<Integer>li = Arrays.asList(nums); //这里要字为Integer数组做为集合中的元素存在。

              /*

              如果数组中的元素都是对象。那么变成集合时,数组中的元素就直接转成集合中的元素。如,String[] arr ={"abc","cc","kkkk"}; abc,cc都作为集合中的元素存在。

              如果数组中的元素都是基本数据类型,那么会将该数组作为集合中的元素存在。

              */

              sop(li);

       }

       publicstatic boolean myContains(String[] arr,String key)

       {

              for(intx=0;x<arr.length; x++)

              {

                     if(arr[x].equals(key))

                            returntrue;

              }

              returnfalse;

       }

       publicstatic void sop(Object obj)

       {

              System.out.println(obj);

       }

}

 

5、集合(集合转化为数组)

  • 集合变数组:Collection接口中的toArray方法。
  • Object[] toArray():返回包含此 collection 中所有元素的数组。
  • <T> T[] toArray(T[] a):返回包含此 collection 中所有元素的数组;返回数组的运行时类型与指定数组的运行时类型相同。
  • import java.util.*;

class CollectionToArray

{

       publicstatic void main(String[] args)

       {

              ArrayList<String>al = new ArrayList<String>();

              al.add("abc1");

              al.add("abc2");

              al.add("abc3");

              /*

              1,指定类型的数组到底要定义多长呢?

              当指定类型的数组长度小于了集合的size,那么该方法内部会创建一个新的数组。长度为集合的size。

            当指定类型的数组长度大于了集合的size,就不会新创建了数组。而是使用传递进来的数组。

              所以创建一个刚刚好的数组最优。(如果创建的短了,数组中多了一个数组,对于内存空间比较耗费)

              2,为什么要将集合变数组?

              为了限定对元素的操作。不需要进行增删了。(你在存储的时候不知道元素的个数,因此选用集合来存储。当操作完成了,集合固定后,你把集合返回过来是可以的。当你返回集合给我对方,对于方是否可以对于集合进行增删,而你还要需要对集合进行增删。这时候可以把它转化为数组给返回去。一返回数组的话,还能增删吗?不能了。)

              */

              String[]arr = al.toArray(new String[al.size()]); //创建一个大小刚好的数组。

              System.out.println(Arrays.toString(arr));

       }

}

 

6、集合(增强for循环)

JDK1.5版本出现后的新特性:

  • ArrayList取出数据的方式有两种,一种是是迭代,一种是for循环。Set集合只有一种取出方式,就是迭代器。
  • Collection中定义了iterator():1.4版本是定义在它里面的1.5以后,给我它找了一个爹(publicinterface Collection<E>extends Iterable<E>),Iterable是从1.5后开始的一个接口,这个接口的出现实际上就是将迭代器,给抽取出来了。它还给我集合框架提供了一个新功能,那就是高级for循环:foreach循环。
  • 高级for循环

格式:

for(数据类型 变量名 : 被遍历的集合(Collection)或者数组)    //没有Map,Map中不支持迭代。

{

      

}

  • 对集合进行遍历。

只能获取集合元素。但是不能对集合进行操作。

迭代器除了遍历,还可以进行remove集合中元素的动作。

如果是用ListIterator,还可以在遍历过程中对集合进行增删改查的动作。

  • 传统for和高级for有什么区别呢?

高级for有一个局限性。必须有被遍历的目标。

  • 建议在遍历数组的时候,还是希望是用传统for。因为传统for可以定义脚标。
  • import java.util.*;

class ForEachDemo

{

       publicstatic void main(String[] args)

       {

              ArrayList<String>al = new ArrayList<String>();//在这里带着泛型,下面for就能用泛型的类型。

              al.add("abc1");

              al.add("abc2");

              al.add("abc3");

              for(Strings : al)          //它在底层原理用的还是Iterator。封装了之后,把复杂的代码变成了简单的代码。这个升级是简化了书写。这个s的指向在做着变化。这个循环是有局限性的,它只能对集合中的元素进行取出,不能做修改动作。迭代器,至少能用一个remove(),如果你用的是列表迭代器的话,你还可以做增删改查。

              {

                     //s= "kk";

                     System.out.println(s);

              }

              System.out.println(al);

              /*

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

              while(it.hasNext())

              {

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

              }

              */

              int[]arr = {3,5,1};

              for(intx=0; x<arr.length; x++)

              {

                     System.out.println(arr[x]);

              }

              for(inti : arr)

              {

                     System.out.println("i:"+i);

              }

              //凡是支持迭代器的集合,它们都支持高级for

              HashMap<Integer,String>hm = new HashMap<Integer,String>();

              hm.put(1,"a");

              hm.put(2,"b");

              hm.put(3,"c");

              Set<Integer>keySet = hm.keySet();

              for(Integeri : keySet)

              {

                     System.out.println(i+"::"+hm.get(i));

              }

//            Set<Map.Entry<Integer,String>>entrySet = hm.entrySet();

//            for(Map.Entry<Integer,String>me : entrySet)

              for(Map.Entry<Integer,String>me : hm.entrySet())

              {

                     System.out.println(me.getKey()+"------"+me.getValue());

              }

       }

}

 

7、集合(可变参数)

JDK1.5版本出现的新特性。

  • 方法的可变参数。在使用时注意:可变参数一定要定义在参数列表最后面

class ParamMethodDemo

{

       publicstatic void main(String[] args)

       {

              //show(3,4);

              /*

              //虽然少定义了多个方法。但是每次都要定义一个数组。作为实际参数。

              int[]arr = {3,4};

              show(arr);

              int[]arr1 = {2,3,4,5};

              show(arr1);

              */

              /*

              可变参数。

其实就是上一种数组参数的简写形式。不用每一次都手动的建立数组对象。只要将要操作的元素作为参数传递即可。隐式将这些参数封装成了数组。

              */

              show("haha",2,3,4,5,6); //我们只要往里面传元素就行了,封装数组的动作不需要你来做,而是由虚拟机来帮你完成。数组不用new了,你爱传几个传几个。

              //show(2,3,4,5,6,4,2,35,9);

              //show();

       }

       publicstatic void show(String str,int... arr)//不要写[]了,还要接收一个数字进来。写三个点,叫可变参数。简化了代码,提高了开发的速度。Arr代表数组,先把前面的匹配完,剩下的都给我后面的了。

       {

              System.out.println(arr.length);

       }

       /*

       publicstatic void show(int[] arr)

       {

       }

       */

       /*

       publicstatic  void show(int a,int b)

       {

              System.out.println(a+","+b);

       }

       publicstatic  void show(int a,int b,int c)

       {}

       */

}

  • static <T> List<T> asList(T...a):Arrays中的asList()方法,就是一个可变参数。

 

8、集合(静态导入)

  • StaticImport  静态导入。

当类名重名时,需要指定具体的包名。(new packa.Demo();)

当方法重名是,指定具备所属的对象或者类。

  • 如果没有静态的话导入的都是类。Import后写static的时候,你导入的都是某一个类的静态成员。
  • import java.util.*;

import static  java.util.Arrays.*;//导入的是Arrays这个类中的所有静态成员。

import static java.util.Collections.*;

/*

packa/Demo.class

packb/Demo.class

import packa.*;

import packb.*;

*/

import static java.lang.System.*;//导入了System类中所有静态成员。System中的都是静态的方法。

class StaticImport //extends Object,Object类先进来,接着导入的进来。

{

       publicstatic void main(String[] args)

       {

              out.println("haha");

              int[]arr = {3,1,5};

              sort(arr); //Arrays中都是一个静态的方法,把Arrays这个类导进来的话,是不是不用写类名点了。

              intindex = binarySearch(arr,1);

              out.println(Arrays.toString(arr)); //虽然已经导入了Arrays,如果不写Arrays,就不知道是要用Object中的toString方法,还是Arrays中的toString()方法。

              System.out.println("Index="+index);

              ArrayListal = new ArrayList();

              al.add(1);

              al.add(3);

              al.add(2);

              out.println(al);

              sort(al);

              out.println(al);

       }

}

 

                                   -------android培训java培训、期待与您交流! ---------- 

0 0
原创粉丝点击