想让String[]数组存入到一个map中,但是不能判断出已经存在的相同元素
lists中的内容如下:
最后wordsCount中包含有3个相同的(i,will):1的key-value值?
怎样使结果为(i,will):3
新手求助
把String数组换成一个类吧,拥有两个String属性的类,经测试可以实现,希望对你有帮助。另外可以查看一下对equals和hashcode重写的写法
public class OverHashcode {
static Map wordsCount = new HashMap<>();
static List list = new ArrayList();
public static void toMap() {
for (LikeStringArray tempStr : list) {
if (wordsCount.containsKey(tempStr)) {
wordsCount.put(tempStr, wordsCount.get(tempStr) + 1);
} else {
wordsCount.put(tempStr, 1);
}
}
for (Map.Entry<LikeStringArray, Integer> entry : wordsCount.entrySet())
System.out.printf("%s:%d\n", entry.getKey(), entry.getValue());
}
public static void main(String[] args) {
list.add(new LikeStringArray("i","do"));
list.add(new LikeStringArray("i","do"));
list.add(new LikeStringArray("i","will"));
list.add(new LikeStringArray("i","will"));
list.add(new LikeStringArray("i","will"));
list.add(new LikeStringArray("i","am"));
toMap();
}
}
class LikeStringArray{
String id;
String name;
LikeStringArray(String id,String name){
this.id= id;
this.name = name;
}
@Override
public int hashCode() {
//返回的hash值进行比较,若equals方法返回true则hashCode方法也应该返回true
return this.name.hashCode()+this.id.hashCode();
}
@Override
public boolean equals(Object obj) {
LikeStringArray other = (LikeStringArray) obj;
//id和name都相同就返回true即是内容上的比较
if(id.equals(other.id)&&name.equals(other.name)){
return true;
}
return super.equals(obj);
}
//输出时别忘了重写toString方法
public String toString() {
return "<"+id+","+name+">";
}
}
看一下containskey的方法,是怎么判断是否包含的。数组即使元素一样的,但是是不同的对象,equal返回的是false。
数组的equal方法
public boolean equals(Object obj) {
return (this == obj);
}
给个思路:
用java.util.Set实现,set的add方法,如果对象存在返回false,例如:
Map times = new HashMap();
for(Object o : Arrays){
String key = "i"+"_" + "will";
//如果添加成功
if(set.add(key){
times.put(key, 1);
}else{
//添加失败,加1
times.put(key, times.get(key)+1);
}
}
最后的times能达到你想要的效果。
数组是比较地址是否一致。你试试取key对应的Val,结果会是null。
建议循环判断下String[] temp中的元素
也可以建立一个自定义对象,把数组作为对象的成员变量,然后重写equals和hashcode函数就可以。
List<String[]> l = new ArrayList<>();
String[] s ="a,a,a,a,a,b,b,b,c,c,c,c".split(",");
String[] s1 ="d,e,f,d,e,d,a,a,a,a,a,b,b,b,c,c,c,c".split(",");
String[] s2 ="a,a,a,a,a,b,b,b,c,c,c,c".split(",");
String[] s3 ="d,e,f,d,e,d,a,a,a,a,a,b,b,b,c,c,c,c".split(",");
l.add(s);l.add(s);l.add(s);l.add(s);
l.add(s1);l.add(s1);
l.add(s2);l.add(s2);
l.add(s3);
Map map = new HashMap<String,Integer>();
for (String[] strings : l) {
map.put(strings,!map.containsKey(strings) ?1 :((Integer) map.get(strings))+1);
}
System.err.println(map.toString());
{[Ljava.lang.String;@7852e922=2, [Ljava.lang.String;@15db9742=4, [Ljava.lang.String;@6d06d69c=2, [Ljava.lang.String;@4e25154f=1}
结论:s与s2内容一致 ,s1与s3内容一致 简单来说Object作为key的话比较的是地址、楼主上面的例子6个对象有6个地址 所以均为1
package chapter2;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Test {
static Map<String, Integer> wordsCount = new HashMap<>();
static List<String[]> lists = new ArrayList<>();
public static void toMap() {
for (String[] temp : lists) {
String tempStr = Arrays.toString(temp);
if (wordsCount.containsKey(tempStr)) {
wordsCount.put(tempStr, wordsCount.get(tempStr) + 1);
} else {
wordsCount.put(tempStr, 1);
}
}
for (Map.Entry<String, Integer> entry : wordsCount.entrySet())
System.out.printf("%s:%d\n", entry.getKey(), entry.getValue());
}
public static void main(String[] args) {
String[] a = {"i","do"};
String[] b = {"i","do"};
String[] c = {"i","will"};
String[] d = {"i","will"};
String[] e = {"i","will"};
String[] f = {"i","am"};
lists.add(a);
lists.add(b);
lists.add(c);
lists.add(d);
lists.add(e);
lists.add(f);
toMap();
}
}
看下实现,你就知道为什么不行了。 数组对象里即使内容相同,对象还是不等
<>
HashMap是按照键排重的,但是,后添加的会覆盖前面添加的
你是没办法对String进行继承,重写方法的,因为String 被定义成fianl 。 你可以新建一个类,把String[] 作为其中的一个属性。然后重写这个类的 equals,compareTo,hashCode方法。让后将这个类作为map的key,我没有测试,感兴趣你可以研究一下。
集合Set是存放不重复的元素的。http://blog.csdn.net/qq_35473951/article/details/54136744
首先你不需要判断containsKey,因为HashMap内部值只允许key和value一一对应(这是基本概念),如果以对象作为key,是以对象的hashCode作为计算的,所以如果你想要判断两个不同对象是否相等,需要重写equals和hashCode方法。