我有一个列表,其中包含字符串ABC:123,abc:123;当我将其转换为设置它给我2个不同的元素。有一个单行方式将此列表转换为设置忽略大小写以便我的Set只包含ABC:123。但是如果输入List包含ABC:123a4,abc:1234A4,它应该在Set中给出2个不同的元素:ABC:123a4,ABC:1234A4 我知道这可以在"上分割列表元素:"首先将abc转换为全部大写,然后将它们添加到新列表中,然后将其添加到新列表中。但只是想知道是否有更好的方法(小行代码)来做到这一点。感谢任何大脑提前思考的想法。
List<String> memlist = new ArrayList<String>(Arrays.asList(memberList.split(",")));
Set<String> memberSet = new HashSet<String>(memlist );
memlist = new ArrayList<String>(memberSet);
答案 0 :(得分:6)
您可以使用设置了TreeSet
标记的String.CASE_INSENSITIVE_ORDER
。
String startingString = "ABC:123,abc:123";
List<String> caseSensitiveList = Arrays.asList(startingString.split(","));
Set<String> caseInsensitiveSet = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
caseInsensitiveSet.addAll(caseSensitiveList);
for(String caseInsensitiveString : caseInsensitiveSet){
System.out.println(caseInsensitiveString);
}
此代码在运行时为我提供输出:
ABC:123
答案 1 :(得分:1)
替换
memberList.toUpperCase().split(",")
与
{{1}}
答案 2 :(得分:1)
最干净的解决方案是@SQLHacks建议的解决方案。但后来你说ABC:123a4
必须与abc:1234A4
不同。我想现在唯一的解决方案是为String
对象创建一个包装器,并覆盖equals()
和hashCode()
方法来执行您想要的操作,正如@PaulBoddington在他的评论中所建议的那样。
这就是我提出的(基于@nafas答案进行编辑和改进):
public class StringWrapper {
private String value;
private String beforeColon;
private String afterColon;
private int hash;
public StringWrapper(String value) {
this.value = value;
String[] splitted = value.split(":");
beforeColon = splitted[0];
afterColon = splitted[1];
hash = Objects.hash(beforeColon.toUpperCase(), afterColon);
}
public String getValue() {
return value;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof StringWrapper) {
StringWrapper other = (StringWrapper) obj;
return beforeColon.equalsIgnoreCase(other.beforeColon) && afterColon.equals(other.afterColon);
}
return false;
}
@Override
public int hashCode() {
return hash;
}
@Override
public String toString() {
return value;
}
}
然后:
// this method is just to help you building a List<StringWrapper> from your String (memberList variable)
public static List<StringWrapper> split(String string, String regex) {
List<StringWrapper> list = new ArrayList<>();
for (String element : string.split(regex)) {
list.add(new StringWrapper(element));
}
return list;
}
public static void main(String[] args) {
String memberList = "ABC:123,abc:123,ABC:123a4,ABC:123A4";
List<StringWrapper> memlist = new ArrayList<>(split(memberList, ","));
Set<StringWrapper> memberSet = new HashSet<>(memlist);
memlist = new ArrayList<StringWrapper>(memberSet);
for (StringWrapper element : memlist) {
System.out.println(element);
}
}
如果你运行这个,你得到以下输出:
ABC:123a4
ABC:123A4
ABC:123
abc:123
已经出局,但ABC:123a4
和ABC:123A4
都在场。
您可以更轻松地更改静态split
方法,为您创建Set
。我没有这样做的原因是让你看起来很熟悉。
答案 3 :(得分:0)
你可以试试这个Java 8 one liner
Set<String> memberSet = memlist.stream().map(s -> s.toUpperCase()).collect(Collectors.toSet());
它将遍历memlist中的所有字符串,将它们转换为大写并将它们放到一个集合中。
这当然意味着如果你的列表包含“abc:123”而不是“ABC:123”,你仍然会在集合中获得“ABC:123”。
答案 4 :(得分:0)
实际创建一个小Model
类来处理所有可能的情况有什么问题?
final class Model{
final String firstPart;
final String secondPart;
final int hashCode;
Model(String s){
String[] splitted=s.split(":");
firstPart=splitted[0];
secondPart=splitted[1];
hashCode=Objects.hash(firstPart.toLowerCase(),secondPart);
}
@Override
public boolean equals(Object o){
String[] splitted=o.toString().split(":");
return firstPart.equalsIgnoreCase(splitted[0]) && secondPard.equals(splitted[1]);
}
@Override
public int hashCode(){
return hashCode;
}
@Override
public String toString(){
return firstPart+":"+secondPart;
}
}
现在创建一个集合等:
Set<Model> set =new HashSet<Model>();