9.5 算法

9.5.1 排序与混排

List<String> staff = new LinkedList<>();
Collections.sort(staff);
//第二种方法
staff.sort((Comparator.comparingDouble(Employee::getSalary)));
//降序对列表进行排序
staff.sort(Comparator.reverseOrder())
staff.sort((Comparator.comparingDouble(Employee::getSalary))).reversed();

对列表进行随机访问效率很低。实际上,可以使用归并排序对列表进行高效的排序。然而,Java程序设计语言并不是这样实现的。它直接将所有元素转入一个数组,对数组进行排序,然后,再将排序后的序列复制回列表。

  • 如果列表支持set方法,则是可修改的。
  • 如果列表支持add和remove方法,则是可改变大小的。

Collections类有一个算法shuffle,其功能与排序正好相反,即随机地混排列表中元素的顺序。

public static void main(String[] args) {
   List<Integer> integers = new ArrayList<>();
   for (int i = 0; i < 30; i++) {
       integers.add(i);
   }
   Collections.shuffle(integers);

   List<Integer> integers1 = integers.subList(0,6);
   integers1.sort(Integer::compareTo);
   System.out.println(integers1);
   integers1.sort(Collections.reverseOrder());
   System.out.println(integers1);
   Collections.sort(integers1);

   System.out.println(integers1);
}

运行结果

[1, 6, 12, 22, 24, 25]
[25, 24, 22, 12, 6, 1]
[1, 6, 12, 22, 24, 25]

Random类的使用

9.5.2 二分查找

二分查找的前提:集合是排好序的;

i = Collections.binarySearch(c,element);

如果binarySearh方法的返回值>=0,则表示匹配对象的索引,c.get(i)等于在这个比较顺序下的elment。如果返回负值,则表示没有匹配的元素。但是可以根据返回值计算应该将elment插入到集合的哪个位置,以保持集合的有序性。插入的位置是:

insertionPoint = -i -1;

这并不是简单的 -i,因为0值是不确定的。也就是说,下面这个操作:

if(i < 0){
    c.add(-i-1,element) ;
}

-i是取绝对值,-i之后为正数
如果为binarySearch算法提供一个链表,它将自动变为线性查找。

List<Integer> integers2 = integers;
integers2.sort(Integer::compareTo);
System.out.println();
int index = Collections.binarySearch(integers2,56);
if(index < 0){
   integers2.add(Math.abs(index) - 1,56);
}
System.out.println(Collections.binarySearch(integers2,56));

9.5.3简单算法

Java SE 8增加了默认方法Collection.removeIf和List.replaceAll,参数需要提供一个lambda表达式。

List<String> strings = new ArrayList<>();
strings.add("java");
strings.add("python");
strings.add("php");
strings.removeIf(s -> s.length()>4);
strings.replaceAll(String::toLowerCase);
System.out.println(strings);

Collections文档,需要自己查找

9.5.4 批操作

将从coll1中删除coll2中出现的所有元素

coll1.removeAll(coll2);

从coll1中删除所有未在coll2中出现的所有元素:

coll1.retainAll(coll2);

代码示例:

List<String> strings = new ArrayList<>();
strings.add("java");
strings.add("python");
strings.add("php");
System.out.println(strings);

List<String> string3 = new ArrayList<>(strings);
//Collections.copy(string3,strings);
System.out.println("strings " + strings.size() + " string3 " + string3.size());
System.out.println("string3\t" + string3);

List<String> strings2 = new ArrayList<>();
strings2.add("i");
strings2.add("love");
strings2.add("java");
strings2.add("util");
strings2.add("world");
strings2.add("end");
strings.removeAll(strings2);
System.out.println(strings);
System.out.println(strings2);

System.out.println(string3);
string3.retainAll(strings2);
System.out.println(string3);

运行结果

[java, python, php]
strings 3 string3 3
string3	[java, python, php]
[python, php]
[i, love, java, util, world, end]
[java, python, php]
[java]

总结: 在不了解Collections.copy的时候最好不要使用,会出现异常。如果想将一个list复制给另外一个list,请使用ArrayList的构造方法。

public ArrayList(Collection<? extends E> c) 
Collections.copy
public static <T> void copy(List<? super T> dest,List<? extends T> src)

Copies all of the elements from one list into another. After the operation, the index of each copied element in the destination list will be identical to its index in the source list. The destination list must be at least as long as the source list. If it is longer, the remaining elements in the destination list are unaffected.
This method runs in linear time.
Type Parameters:
T - the class of the objects in the lists
Parameters:
dest - The destination list.
src - The source list.
Throws:
IndexOutOfBoundsException - if the destination list is too small to contain the entire source List.
UnsupportedOperationException - if the destination list’s list-iterator does not support the set operation.

9.5.5集合与数组的转换

String [] values = ...;
HashSet<String> staff = new HashSet<>(Arrays.asList(values));
Object [] values = staff.toArray();

toArray方法返回的是一个Object[]数组,不能改变它的类型。必须用toArray方法的一个变体形式,提供一个所需类型而且长度为0的数组。这样,返回的数组就会创建为相同的数组类型:

String [] values = staff.toArray(new String[0]);

9.5.6编写自己的算法

public List<JMenuItem> getAllItems(JMenu jMenu){
   return new AbstractList<JMenuItem>() {
       @Override
       public JMenuItem get(int index) {
           return jMenu.getItem(index);
       }

       @Override
       public int size() {
           return jMenu.getItemCount();
       }
   };
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值