您的位置:首页 > 职场人生

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

2014-01-26 23:02 656 查看
    -------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培训、期待与您交流!
---------- 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: