目录
学习内容:
延伸:
Comparator类
comparator 是javase中的接口,位于java.util包下,该接口抽象度极高,有必要掌握该接口的使用
使用场景:
1. 排序,需要比较两个对象谁排在前谁排在后(排序也可以让类实现Comparable接口,实现后该类的实例也具有排序能力)。
2. 分组,需要比较两个对象是否是属于同一组。
Comparator原始方法:
public interface Comparator<T> {
int compare(T o1, T o2);
1)如果o1大于o2,则返回正整数;
2)如果o1小于o2,则返回负整数
3)如果o1等于o2,则返回零
}
//
负数:表示第一个参数排在前面
正数:表示第二个参数排在前面
零:表示两个参数相等
排序:
在List或数组中的对象如果没有实现Comparable接口时,那么就需要调用者为需要排序的数组或List设置一个Compartor,Compartor的compare方法用来告诉代码应该怎么去比较两个实例,然后根据比较结果进行排序
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class SortTest {
class Child{
public int age;
public String name;
public Child(int age, String name) {
super();
this.age = age;
this.name = name;
}
@Override
public String toString() {
return "Dog [age=" + age + ", name=" + name + "]";
}
}
public static void main(String[] args) {
List<Child> list= new ArrayList<>();
list.add(new SortTest().new Child(5, "ChildA"));
list.add(new SortTest().new Child(7, "ChildB"));
list.add(new SortTest().new Child(6, "ChildC"));
Collections.sort(list, new Comparator<Child>() {
@Override
public int compare(Child o1, Child o2) {
return o2.age - o1.age;
}
});
System.out.println("给小孩按照年龄倒序:"+list);
//[Dog [age=7, name=ChildB], Dog [age=6, name=ChildC], Dog [age=5, name=ChildA]]
Collections.sort(list, new Comparator<Child>() {
@Override
public int compare(Child o1, Child o2) {
return o1.name.compareTo(o2.name);
}
});
System.out.println("给小孩按名字字母顺序排序:"+list);
//[Dog [age=5, name=ChildA], Dog [age=7, name=ChildB], Dog [age=6, name=ChildC]]
}
}
分组:
使用Comparator和for循环处理列表,来进行分类;通过调用者实现Comparator接口的比较逻辑,来告诉程序应该怎么比较,通过比较之后得结果来进行分组。比如生活中的拳击比赛,会有公斤级的概念,那么程序中应该实现的处理逻辑是只要两个人的体重在同一个区间则为同一组公斤级的选手。下面例子中分别按照狗狗的颜色和体重级别两个维度来进行分组,因此分组的核心逻辑其实就是比较逻辑。相面我抽了一个工具方法:dividerList,第一个参数为需要处理的数据源,第二参数是分组时的比较逻辑。
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
public class GroupTest {
class Apple {
public String color;
public int weight;
public Apple(String color, int weight) {
super();
this.color = color;
this.weight = weight;
}
@Override
public String toString() {
return "Apple [color=" + color + ", weight=" + weight + "]";
}
}
public static <T> List<List<T>> divider(Collection<T> datas, Comparator<? super T> c) {
List<List<T>> result = new ArrayList<List<T>>();
for (T t : datas) {
boolean isSameGroup = false;
for (int j = 0; j < result.size(); j++) {
if (c.compare(t, result.get(j).get(0)) == 0) {
isSameGroup = true;
result.get(j).add(t);
break;
}
}
if (!isSameGroup) {
// 创建
List<T> innerList = new ArrayList<T>();
result.add(innerList);
innerList.add(t);
}
}
return result;
}
public static void main(String[] args) {
List<Apple> list = new ArrayList<>();
list.add(new GroupTest().new Apple("黄", 4));
list.add(new GroupTest().new Apple("黄", 224));
list.add(new GroupTest().new Apple("红", 205));
list.add(new GroupTest().new Apple("绿", 153));
list.add(new GroupTest().new Apple("红", 131));
list.add(new GroupTest().new Apple("黄", 119));
list.add(new GroupTest().new Apple("绿", 248));
List<List<Apple>> byColors = divider(list, new Comparator<Apple>() {
@Override
public int compare(Apple o1, Apple o2) {
// 按颜色分组
return o1.color.compareTo(o2.color);
}
});
System.out.println("按颜色分组" + byColors);
//[[Apple [color=黄, weight=4], Apple [color=黄, weight=224], Apple [color=黄, weight=119]],
//[Apple [color=红, weight=205], Apple [color=红, weight=131]],
//[Apple [color=绿, weight=153], Apple [color=绿, weight=248]]]
List<List<Apple>> byWeight = divider(list, new Comparator<Apple>() {
@Override
public int compare(Apple o1, Apple o2) {
// 按重量级
return (o1.weight / 100 == o2.weight / 100) ? 0 : 1;
}
});
System.out.println("按重量级分组" + byWeight);
//按重量级分组[[Apple [color=黄, weight=4]],
//[Apple [color=黄, weight=224], Apple [color=红, weight=205], Apple [color=绿, weight=248]],
//[Apple [color=绿, weight=153], Apple [color=红, weight=131], Apple [color=黄, weight=119]]]
}
}
LintCode刷题:
·将集合中的元素排序
延伸->(Comparator)
·根据学生的成绩等级,判断学生的成绩范围
switch语句来判断返回不同的str即可
public class Solution {
public String getRange(String level) {
String str="";
switch (level){
case "A":
str="90~100";
break;
case "B":
str="80~89";
break;
case "C":
str="70~79";
break;
case "D":
str="60~69";
break;
case "E":
str="0~59";
break;
default:
str="Unknown level";
}
return str;
}
}
· 判断2的幂
不停把n除以2,当除时有有余则返回一个false指针,根据这个指针来决定输出是不是2的幂
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
int n=scanner.nextInt();
boolean ispower=true;
while (n!=1){
if (n%2==1)
ispower=false;
n/=2;
}
if (ispower)
System.out.println("It's a power of two");
else
System.out.println("It's not a power of two");
}
}
·打印每个月含有的天数
运用switch判断月份,再根据year判断是不是闰年即可.
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
int year=scanner.nextInt();
int month=scanner.nextInt();
switch (month){
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
System.out.println("31 days");
break;
case 4:
case 6:
case 9:
case 11:
System.out.println("30 days");
break;
case 2:
if (year%4==0&&year%100!=0||year%400==0)
System.out.println("29 days");
else
System.out.println("28 days");
break;
}
}
}
· 获取索引为最后一位的元素
运用str的charAt方法即可
public class Solution {
public char getLastIndex(String str) {
return str.charAt(str.length()-1);
}
}
·最频繁的单词
public class Solution {
public String mostCommonWord(String paragraph, String[] banned) {
String[] paragraphs = (paragraph + " ").toLowerCase().split("[!?',;.]{0,1}[ ]");
Map<String,Integer> map = new HashMap<>();
for(String word:paragraphs){
map.put(word,map.getOrDefault(word,0)+1);
}
for(String word:banned){
map.remove(word);
}
String s = "";
int max = 0;
for(String key:map.keySet()){
if(map.get(key)>max){
max = map.get(key);
s = key;
}
}
return s;
}
}
学习时间:
2021-8-22 17:00-20:20、21:43-22:51
学习产出:
刷题*6
学习博客*1