Java 如何将关于T类字段的重复值列表转换为不同值列表

Java 如何将关于T类字段的重复值列表转换为不同值列表,java,arraylist,Java,Arraylist,我有一个列表,其中包含名称。我想将该列表转换为其他唯一名称列表。我找到了一种行之有效的方法,即: public class Main { public Main() { List<String> nameList = new ArrayList<>(); nameList.add("Ali"); nameList.add("Al"); nameList.add("Ali"); nameList.add("Al");

我有一个
列表
,其中包含名称。我想将该列表转换为其他唯一名称列表。我找到了一种行之有效的方法,即:

public class Main {

  public Main() {
    List<String> nameList = new ArrayList<>();

    nameList.add("Ali");
    nameList.add("Al");
    nameList.add("Ali");
    nameList.add("Al");
    nameList.add("Ai");
    nameList.add("li");
    nameList.add("li");
    nameList.add("Ai");
    System.out.print("All names are: ");
    for (String string : nameList) {
      System.out.print(string + ", ");
    }
    System.out.println("");

    System.out.print("Unique names are: ");

    for (String string : convertToUniqueList(nameList)) {
      System.out.print(string + ", ");
    }

  }

  public List<String> convertToUniqueList(List<String> listInts) {
    List<String> listDistinctInts = new ArrayList<>(listInts.size());
    for (String i : listInts) {
      if (!listDistinctInts.contains(i)) {
        listDistinctInts.add(i);
      }
    }
    return listDistinctInts;
  }

  public static void main(String[] args) {
    new Main();
  }

}
公共类主{
公用干管(){
列表名称列表=新的ArrayList();
姓名列表。添加(“阿里”);
姓名列表。添加(“Al”);
姓名列表。添加(“阿里”);
姓名列表。添加(“Al”);
姓名列表。添加(“Ai”);
姓名列表。添加(“li”);
姓名列表。添加(“li”);
姓名列表。添加(“Ai”);
System.out.print(“所有名称均为:”);
for(字符串:名称列表){
系统输出打印(字符串+“,”);
}
System.out.println(“”);
System.out.print(“唯一名称为:”);
for(字符串:convertToUniqueList(名称列表)){
系统输出打印(字符串+“,”);
}
}
公共列表convertToUniqueList(列表输入){
List ListDifferentics=新的ArrayList(listInts.size());
for(字符串i:listInts){
如果(!ListDifferentions.contains(i)){
添加(i);
}
}
返回列表的区别;
}
公共静态void main(字符串[]args){
新的Main();
}
}
所有的事情都进行得很好,我得到了预期的结果,但我想在以下场景中实现与上面相同的逻辑:

  @Data // lombok annotation
  public class Foo {
    String name;
    int age;    
    List<Bar> barList = new ArrayList<>();    
  }

  @Data // lombok annotation
  public class Bar {
    String bloodGroup;
    String dayOfPassing;
  }
@Data//lombok注释
公开课Foo{
字符串名;
智力年龄;
List barList=新建ArrayList();
}
@Data//lombok注释
公共类酒吧{
线状血型;
字符串传递日期;
}
我想从Main.java中的misc list中获取一个具有唯一日期名称的列表,我尝试了:

public class Main {

  public Main() {
    Foo foo1 = new Foo();

    foo1.setName("Foo One");
    foo1.setAge(21);

    List<Bar> barList = new ArrayList<>();

    Bar bar1 = new Bar();
    bar1.setBloodGroup("O +ve");
    bar1.setDayOfPassing("Wednesday");

    Bar bar2 = new Bar();
    bar2.setBloodGroup("O +ve");
    bar2.setDayOfPassing("Wednesday");

    Bar bar3 = new Bar();
    bar3.setBloodGroup("O +ve");
    bar3.setDayOfPassing("Thursday");

    Bar bar4 = new Bar();
    bar4.setBloodGroup("O -ve");
    bar4.setDayOfPassing("Friday");

    barList.add(bar1);
    barList.add(bar2);
    barList.add(bar3);
    barList.add(bar4);

    System.out.print("All Bars with all days are: ");
    for (Bar bar : barList) {
      System.out.print(bar.dayOfPassing + ", ");
    }
    System.out.println("");

    System.out.print("Bars with Unique days are: ");
    int count = 0;
    for (Bar bar : getBarsWithUniqueDays(barList, count)) {
      System.out.print(bar.dayOfPassing + ", ");
      count++;
    }

  }

  public List<Bar> getBarsWithUniqueDays(List<Bar> barList, int count) {
    List<Bar> listDistinctBars = new ArrayList<>(barList.size());

    for (Bar bar : barList) {
      if (!listDistinctBars.get(count).getDayOfPassing().contains(bar.dayOfPassing)) {
        listDistinctBars.add(bar);
      }
      count++;
    }
    return listDistinctBars;
  }

  public static void main(String[] args) {
    new Main();
  }
}
公共类主{
公用干管(){
Foo foo1=新的Foo();
foo1.setName(“Foo One”);
foo1.设置(21);
List barList=新建ArrayList();
Bar bar1=新的Bar();
bar1.setBloodGroup(“O+ve”);
bar1.假期的设定日(“星期三”);
Bar bar2=新的Bar();
bar2.setBloodGroup(“O+ve”);
2.假期的设定日(“星期三”);
Bar bar3=新的Bar();
bar3.setBloodGroup(“O+ve”);
bar3.假期的设定日(“星期四”);
Bar bar4=新的Bar();
bar4.setBloodGroup(“O-ve”);
bar4.假期的设定日(“星期五”);
添加(bar1);
barList.add(bar2);
添加(bar3);
添加(bar4);
System.out.print(“包含所有日期的所有条均为:”);
用于(条形图:条形图列表){
系统输出打印(bar.dayOfPassing+“,”);
}
System.out.println(“”);
System.out.print(“具有唯一日期的条为:”);
整数计数=0;
for(条形图:getBarsWithUniqueDays(条形图列表,计数)){
系统输出打印(bar.dayOfPassing+“,”);
计数++;
}
}
公共列表getBarsWithUniqueDays(列表barList,整数计数){
List listDistinctBars=新的ArrayList(barList.size());
用于(条形图:条形图列表){
如果(!listDistinctBars.get(count).getDayOfPassing()包含(bar.dayOfPassing)){
listDistinctBars.add(条);
}
计数++;
}
返回listDistinctBars;
}
公共静态void main(字符串[]args){
新的Main();
}
}
有了上面的代码,我得到了一个例外:

All Bars with all days are: Wednesday, Wednesday, Thursday, Friday, 
Bars with Unique days are: Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
    at java.util.ArrayList.rangeCheck(Unknown Source)
    at java.util.ArrayList.get(Unknown Source)
    at Main.getBarsWithUniqueDays(Main.java:124)
    at Main.<init>(Main.java:113)
    at Main.main(Main.java:133)
所有日期的所有条形图为:星期三、星期三、星期四、星期五、,
具有唯一天数的条是:线程“main”java.lang.IndexOutOfBoundsException中的异常:索引:0,大小:0
位于java.util.ArrayList.rangeCheck(未知源)
位于java.util.ArrayList.get(未知源)
在Main.getBarsWithUniqueDays(Main.java:124)
在Main(Main.java:113)
Main.Main(Main.java:133)

我已经搜索和尝试了很多,但没有结果,任何解决这个问题的方法

您将获得一个
索引自动边界异常
,因为您的代码正在调用
listDistinctBars.get(count)
ArrayList
上的
count
等于
0
。但是,要正确地消除对象的重复数据,您应该研究
java.util.Set

最好的做法是使用
HashSet
LinkedHashSet
(当顺序很重要时)(实现
Set
)来处理唯一的元素

您只需将
ArrayList
转换为
HashSet
,然后覆盖类
等于
hashcode
。 下面是重写的示例

我找到了一种行之有效的方法,即:

public class Main {

  public Main() {
    List<String> nameList = new ArrayList<>();

    nameList.add("Ali");
    nameList.add("Al");
    nameList.add("Ali");
    nameList.add("Al");
    nameList.add("Ai");
    nameList.add("li");
    nameList.add("li");
    nameList.add("Ai");
    System.out.print("All names are: ");
    for (String string : nameList) {
      System.out.print(string + ", ");
    }
    System.out.println("");

    System.out.print("Unique names are: ");

    for (String string : convertToUniqueList(nameList)) {
      System.out.print(string + ", ");
    }

  }

  public List<String> convertToUniqueList(List<String> listInts) {
    List<String> listDistinctInts = new ArrayList<>(listInts.size());
    for (String i : listInts) {
      if (!listDistinctInts.contains(i)) {
        listDistinctInts.add(i);
      }
    }
    return listDistinctInts;
  }

  public static void main(String[] args) {
    new Main();
  }

}
我不这么认为,相反,你可以使用
Set

public Set<String> convertToUniqueList(List<String> listInts) {
    return new HashSet<>(listInts);
}
public Set convertToUniqueList(列表项){
返回新的哈希集(listInts);
}
对于第二个问题,您可以使用stream,根据您的解决方案可以是:

public List<Bar> getBarsWithUniqueDays(List<Bar> barList) {
    return barList.stream().filter(distinctByKey(Bar::getDayOfPassing))
            .collect(Collectors.toList());

}

public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
    Set<Object> seen = ConcurrentHashMap.newKeySet();
    return t -> seen.add(keyExtractor.apply(t));
}
public List getBarsWithUniqueDays(List barList){
返回barList.stream().filter(distinctByKey(Bar::getDayOfPassing))
.collect(Collectors.toList());
}
公共静态谓词distinctByKey(函数键提取器){
Set seen=ConcurrentHashMap.newKeySet();
返回t->seen.add(keydextractor.apply(t));
}
Map Map=newlinkedhashmap();
适用于(酒吧日:酒吧列表){
地图放置日期(天。通行日,天);
}
barList.clear();
addAll(map.values());
适用于(酒吧日:酒吧列表){
System.out.println(“唯一名称为:“+ays.dayOfPassing”);
}

预期的输出是什么?@YCF\u L应该像
条一样,具有唯一的日期:星期三、星期四、星期五。
我也尝试过,但不幸的是,该技术需要覆盖
hashCode()
当我这样做时,最终会得到一些重复的值……我也尝试过,但不幸的是,这种技术需要重写hashCode(),当我这样做时,最终会得到一些重复的值……这意味着重写不正确。下面是我的答案中重写的工作示例。您能否以与java 6或7 iff兼容的格式发布第二部分。@ArshadAli您可以在类中使用比较器,或者遵循sasikumar发布的解决方案