1.Java对象为什么重写equals和hashcode方法?有什么作用?
答:默认equals在比较两个对象时,是看他们是否指向同一个地址的。但有些时候,我们希望两个对象只要是某些属性相同就认为他们的equals为true
比如:学生对象,在某种情况下,我们认为学号一样的对象是同一学生,那么重写之后,两个同学号的对象比较就是相同
2.java集合进行排序的两种方式
答:java集合的工具类Collections中提供了两种排序的方法,分别是:
- Collections.sort(List list)
- Collections.sort(List list,Comparator c)
第一种称为自然排序,参与排序的对象需实现comparable接口,重写其compareTo()方法,方法体中实现对象的比较大小规则
public class Emp implements Comparable { @Override public int compareTo(Object o) { if(o instanceof Emp){ Emp emp = (Emp) o; // return this.age-emp.getAge();//按照年龄升序排序 } throw new ClassCastException("不能转换为Emp类型的对象..."); } }
第二种叫定制排序,或自定义排序,需编写匿名内部类,先new一个Comparator接口的比较器对象c,同时实现compare()其方法; 然后将比较器对象c传给Collections.sort()方法的参数列表中,实现排序功能;
/**使用Comparator比较器按age升序排序*/ @Test public void testComparatorSortAge(){ Collections.sort(list,new Comparator () { @Override public int compare(Object o1, Object o2) { if(o1 instanceof Emp && o2 instanceof Emp){ Emp e1 = (Emp) o1; Emp e2 = (Emp) o2; return e1.getAge() - e2.getAge(); } throw new ClassCastException("不能转换为Emp类型"); } }); }
说明:第一种方法不够灵活,实体类实现了comparable接口后,会增加耦合,如果在项目中不同的位置需要根据不同的属性调用排序方法时,需要反复修改比较规则,二者只能选择其一,会起冲突.
第二种就很好地解决了这个问题.在需要的地方,创建个内部类的实例,重写其比较方法即可.
3.禁止在 foreach 循环里进行元素的 remove/add 操作?
答:是因为触发了一个 Java 集合的错误检测机制——fail-fastfail-fast,即快速失败,它是 Java 集合的一种错误检测机制。当多个线程对集合(非 fail-safe 的集合类)进行结构上的改变的操作时,有可能会产生 fail-fast 机制,这个时候就会抛出 ConcurrentModificationException(当方法检测到对象的并发修改,但不允许这种修改时就抛出该异常)。同时需要注意的是,即使不是多线程环境,如果单线程违反了规则,同样也有可能会抛出改异常。
因此,使用遍历删除或者添加时,使用一般的for循环
4.java中List集合去重的方法
1.双重for循环,然后remove
2.利用HashSet踢除重复元素
public static List removeDuplicate(List list) { HashSet h = new HashSet(list); list.clear(); list.addAll(h); return list; }
3.把list里的对象遍历一遍,用list.contains(),如果不存在就放入到另外一个list集合中
public static List removeDuplicate(List list){ List listTemp = new ArrayList(); for(int i=0;i<list.size();i++){ if(!listTemp.contains(list.get(i))){ listTemp.add(list.get(i)); } } return listTemp; }
4. Stream中对List进行去重:list.stream().distinct();
List list=(List) a.stream().distinct().collect(Collectors.toList());