一. 查看class编译版本
1. javap命令
javap 命令行工具是用作反编译的,在反编译信息中,可以看到编译的版本信息。
其中 major version 就是编译的版本号,这里的 52 代表 JDK1.8。
编译版本与 JDK 版本对照表
JDK 版本号 | Class 版本号 | 16 进制 |
---|---|---|
1.1 | 45.0 | 00 00 00 2D |
1.2 | 46.0 | 00 00 00 2E |
1.3 | 47.0 | 00 00 00 2F |
1.4 | 48.0 | 00 00 00 30 |
1.5 | 49.0 | 00 00 00 31 |
1.6 | 50.0 | 00 00 00 32 |
1.7 | 51.0 | 00 00 00 33 |
1.8 | 52.0 | 00 00 00 34 |
2. Linux中hexdump命令
hexdump主要用来查看“二进制”文件的十六进制编码。注意:它能够查看任何文件,不限于与二进制文件。
二. List集合去重方法
为了在下文中进行测试内容讲解,我们先做一些初始化数据
public class ListRmDuplicate {
private List<String> list;
private List<Player> playerList;
@BeforeEach
public void setup() {
list = new ArrayList<>();
list.add("kobe");
list.add("james");
list.add("curry");
list.add("zimug");
list.add("zimug");
playerList= new ArrayList<>();
playerList.add(new Player("kobe","10000")); //科比万岁
playerList.add(new Player("james","32"));
playerList.add(new Player("curry","30"));
playerList.add(new Player("zimug","27")); // 注意这里名字重复
playerList.add(new Player("zimug","18")); //注意这里名字和年龄重复
playerList.add(new Player("zimug","18")); //注意这里名字和年龄重复
}
}
1. 集合元素整体去重
下文中四种方法对List中的String类型以集合元素对象为单位整体去重。如果你的List放入的是Object对象,需要你去实现对象的equals和hashCode方法,去重的代码实现方法和
List<String>
去重是一样的。
1.1 放入Set集合
是大家最容易想到的,先把List数据放入Set,因为Set数据结构本身具有去重的功能,所以再将SET转为List之后就是去重之后的结果。这种方法在去重之后会改变原有的List元素顺序,因为HashSet本身是无序的,而TreeSet排序也不是List种元素的原有顺序。
@Test
void testRemove1() {
/*Set<String> set = new HashSet<>(list);
List<String> newList = new ArrayList<>(set);*/
//去重并排序的方法(如果是字符串,按字母表排序。如果是对象,按Comparable接口实现排序)
//List<String> newList = new ArrayList<>(new TreeSet<>(list));
//简写的方法
List<String> newList = new ArrayList<>(new HashSet<>(list));
System.out.println( "去重后的集合: " + newList);
}
控制台打印结果如下:
去重后的集合: [kobe, james, zimug, curry]
1.2 Stream流distinct去重
使用就比较简单,先用stream方法将集合转换成流,然后distinct去重,最后在将Stream流collect收集为List。
@Test
void testRemove2() {
List<String> newList = list.stream().distinct().collect(Collectors.toList());
System.out.println( "去重后的集合: " + newList);
}
控制台打印结果如下:
去重后的集合: [kobe, james, curry, zimug]
1.3 利用set.add(T)
这种方法利用了set.add(T)
,如果T元素已经存在集合中,就返回false。利用这个方法进行是否重复的数据判断,如果不重复就放入一个新的newList中,这个newList就是最终的去重结果
//三个集合类list、newList、set,能够保证顺序
@Test
void testRemove3() {
Set<String> set = new HashSet<>();
List<String> newList = new ArrayList<>();
for (String str :list) {
if(set.add(str)){ //重复的话返回false
newList.add(str);
}
}
System.out.println( "去重后的集合: " + newList);
}
控制台打印结果和第二种方法一致。
1.4 newList.contains(T)
方法
这种方法已经脱离了使用Set集合进行去重的思维,而是使用newList.contains(T)
方法,在向新的List添加数据的时候判断这个数据是否已经存在,如果存在就不添加,从而达到去重的效果。
//优化 List、newList、set,能够保证顺序
@Test
void testRemove4() {
List<String> newList = new ArrayList<>();
for (String cd:list) {
if(!newList.contains(cd)){ //主动判断是否包含重复元素
newList.add(cd);
}
}
System.out.println( "去重后的集合: " + newList);
}
控制台打印结果和第二种方法一致。
2. 按照集合元素对象属性去重
其实在实际的工作中,按照集合元素对象整体去重的应用的还比较少,更多的是要求我们按照元素对象的某些属性进行去重。 看到这里请大家回头去看一下上文中,构造的初始化数据playerList
,特别注意其中的一些重复元素,以及成员变量重复。
2.1 TreeSet实现Comparator接口
为TreeSet实现Comparator接口,如果我们希望按照Player的name属性进行去重,就去在Comparator接口中比较name。下文中写了两种实现Comparator接口方法:
- lambda表达式:
(o1, o2) -> o1.getName().compareTo(o2.getName())
- 方法引用:
Comparator.comparing(Player::getName)
@Test
void testRemove5() {
//Set<Player> playerSet = new TreeSet<>((o1, o2) -> o1.getName().compareTo(o2.getName()));
Set<Player> playerSet = new TreeSet<>(Comparator.comparing(Player::getName));
playerSet.addAll(playerList);
/*new ArrayList<>(playerSet).forEach(player->{
System.out.println(player.toString());
});*/
//将去重之后的结果打印出来
new ArrayList<>(playerSet).forEach(System.out::println);
}
输出结果如下:三个zimug因为name重复,另外两个被去重。但是因为使用到了TreeSet,list中元素被重新排序。
Player{name='curry', age='30'}
Player{name='james', age='32'}
Player{name='kobe', age='10000'}
Player{name='zimug', age='27'}
2.2 使用Predicate
Predicate(有人管这个叫断言,从英文的角度作为名词可以翻译为谓词,作为动词可以翻译为断言)。谓词就是用来修饰主语的,比如:喜欢唱歌的小鸟,喜欢唱歌就是谓词,用来限定主语的范围。所以我们这里是用来filter过滤的,也是用来限制主语范围的,所以我认为翻译为谓词更合适。随便吧,看你怎么觉得怎么理解合理、好记,你就怎么来。
- 首先我们定义一个谓词Predicate用来过滤,过滤的条件是distinctByKey。谓词返回ture元素保留,返回false元素被过滤掉。
- 当然我们的需求是过滤掉重复元素。我们去重逻辑是通过map的putIfAbsent实现的。putIfAbsent方法添加键值对,如果map集合中没有该key对应的值,则直接添加,并返回null,如果已经存在对应的值,则依旧为原来的值。
- 如果putIfAbsent返回null表示添加数据成功(不重复),如果putIfAbsent返回value(value==null :false),则满足了distinctByKey谓词的条件元素被过滤掉。
这种方法虽然看上去代码量增大了,但是distinctByKey谓词方法只需要被定义一次,就可以无限复用。
@Test
void testRemove7() {
List<Player> newList = new ArrayList<>();
playerList.stream().filter(distinctByKey(p -> p.getName())) //filter保留true的值
.forEach(newList::add);
newList.forEach(System.out::println);
}
static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
Map<Object,Boolean> seen = new ConcurrentHashMap<>();
//putIfAbsent方法添加键值对,如果map集合中没有该key对应的值,则直接添加,并返回null,如果已经存在对应的值,则依旧为原来的值。
//如果返回null表示添加数据成功(不重复),不重复(null==null :TRUE)
return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}
输出结果如下:三个zimug因为name重复,另外两个被去重。并且没有打乱List的原始顺序
Player{name='kobe', age='10000'}
Player{name='james', age='32'}
Player{name='curry', age='30'}
Player{name='zimug', age='27'}
2.3 对某几个元素去重(改造上面的方法)
上面的例子都是按某一个对象属性进行去重,如果我们想按照某几个元素进行去重,就需要对上面的三种方法进行改造。 我只改造其中一个,另外几个改造的原理是一样的,就是把多个比较属性加起来,作为一个String属性进行比较。
@Test
void testRemove8() {
Set<Player> playerSet = new TreeSet<>(Comparator.comparing(o -> (o.getName() + "" + o.getAge())));
playerSet.addAll(playerList);
new ArrayList<>(playerSet).forEach(System.out::println);
}
三. 将一个表的某个字段值赋给另一个
update T_SLXF_APP_MENU_CONFIG t1 set t1.MERGE_LM_ID = (select t2.ID from T_SLXF_APP_MENU_CONFIG t2 where t2.id = t1.id);
四. 查看git项目是哪个分支的
1. 查看项目git服务器地址
输入git remote -v
即可查看git的服务器地址:
2. 查看是从哪个分支上拉的代码
git remote show origin