【问题标题】:replacing a string using comparator in java在java中使用比较器替换字符串
【发布时间】:2014-01-14 17:55:49
【问题描述】:

我想知道是否可以使用比较器递归地比较文件中的字符串并根据其中的元素替换字符串。我有一些数据:

331028124,24,7912,CF,1,1
331028124,24,7631,2B,2,1
331028124,24,5909,1B,3,1   
331028124,24,8394,P,3,2       
331028124,24,7245,LF,4,1
331028124,17,9194,SS,1,1

我想买

331028124,24,7912,CF,1,1
331028124,24,7631,2B,2,1
331028124,24,8394,P,3,2       
331028124,24,7245,LF,4,1
331028124,17,9194,SS,1,1

实际上应该做的是比较两个字符串,比如331028124,24,5909,1B,3,1331028124,24,8394,P,3,2

然后将第一个字符串替换为第二个字符串,因为字符串的最后一个值中的数字更大...

到目前为止,我有:

    import java.io.BufferedReader;
    import java.io.DataInputStream;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.List;

    public class BattingOrder {

    String game_ID;
    String team_ID;
    String player_ID;
    String position;
    String battingOrder;
    String subOrder;

    public BattingOrder(String game, String team, String player, String place,
        String batter, String sub) {
        game_ID = game;
        team_ID = team;
        player_ID = player;
        position = place;
        battingOrder = batter;
        subOrder = sub;
    }

    @Override
    public String toString() {
    return game_ID + "," + team_ID + "," + player_ID + "," + position + ","
            + battingOrder;
    }

    public static void main(String[] args) throws IOException {
            FileInputStream fstream = new FileInputStream(
            "BatterInfo.txt");
    DataInputStream in = new DataInputStream(fstream);
            BufferedReader br = new BufferedReader(new InputStreamReader(in));
            List<BattingOrder> sortList = new ArrayList<BattingOrder>();
                for (String line; (line = br.readLine()) != null;) {
                    String delims = "[,]";
                    String[] parsedData = line.split(delims);
                    sortList.add(new BattingOrder(parsedData[0], parsedData[1],
                parsedData[2], parsedData[3], parsedData[4], parsedData[5]));
    }
            System.out.println("Before Sort");
    for (BattingOrder order : sortList) {
        System.out.println(order);
    }

    Collections.sort(sortList, new Comparator<BattingOrder>() {
        @Override
        public int compare(BattingOrder one, BattingOrder two) {
            if (one.game_ID.equals(two.game_ID)
                    || one.team_ID.equals(two.team_ID)
                    || one.battingOrder.equals(two.battingOrder)) {
                return one.subOrder.compareTo(two.subOrder);
            } else {
                return one.team_ID.compareTo(two.team_ID);
            }

        }
    });
    System.out.println("After Sort");
    for (BattingOrder order : sortList) {
        System.out.println(order);
    }

    br.close();

}

}

输出:

Before Sort
  331028124,24,7912,CF,1,1
  331028124,24,7631,2B,2,1
  331028124,24,5909,1B,3,1   
  331028124,24,8394,P,3,2       
  331028124,24,7245,LF,4,1
  331028124,17,9194,SS,1,1    
    After Sort
  331028124,24,7912,CF,1,1
  331028124,24,7631,2B,2,1
  331028124,24,7245,LF,4,1
  331028124,24,5909,1B,3,1   
  331028124,17,9194,SS,1,1    
  331028124,24,8394,P,3,2

我想要:

331028124,24,7912,CF,1,1
331028124,24,7631,2B,2,1
331028124,24,8394,P,3,2       
331028124,24,7245,LF,4,1
331028124,17,9194,SS,1,1

我做错了什么?

【问题讨论】:

  • 它已经按照您的要求对您的数据进行了排序。我不确定您真正想要做什么是否足够清楚以提供答案。
  • 在我看来,您想保留一组 BattingOrder,每次遇到比该组更好的 BattingOrder 时,您都进行替换。
  • 我看到他们必须是同一支球队、同一场比赛和同一击球顺序才会发生冲突?而决定因素是子订单? (我说的对吗)?
  • @BoristheSpider 我已经更新了我希望输出的内容...基本上将第 3 行替换为第 4 行,因为最后一个数字 (2) 大于 (1) 即...更好
  • 好的,1) 将您的数据存储在 proper Object - 将数字存储为数字。 2)按照您的描述实现您的equals 方法。 3) 将数据放入Set 并使用contains 方法。

标签: java arrays string sorting comparator


【解决方案1】:

为了在某些字段上对BattingOrder对象进行相同处理(但仍然确定谁的排名更好)

您必须重写 equals 方法以及 hashCode 并放置一个 identifier

/** 
 *  Different BattingOrders who share these 3 fields
 *  will get the same identifier
 */
public String identifier() {
    return game_ID +"-" + team_ID + "-" + battingOrder;
}

@Override
public boolean equals(Object obj) {
    if (obj instanceof BattingOrder) {
        BattingOrder b = (BattingOrder) obj;
        if (this.game_ID.equals(game_ID) && this.team_ID.equals(b.team_ID) && this.battingOrder.equals(b.battingOrder)) {
            return true;
        }
    }
    return false;
}


@Override
public int hashCode() {
    int hash = 5;
    hash = 59 * hash + Objects.hashCode(this.game_ID);
    hash = 59 * hash + Objects.hashCode(this.team_ID);
    hash = 59 * hash + Objects.hashCode(this.battingOrder);
    return hash;
}

我也做了BattingOrder实现Comparable

@Override
public int compareTo(BattingOrder o) {
    if (this.identifier().equals(o.identifier())) {
        return this.subOrder.compareTo(o.subOrder);
    } else if (this.game_ID.equals(o.game_ID) && this.team_ID.equals(o.team_ID)) {
        return this.battingOrder.compareTo(o.battingOrder);
    } else {
        return o.team_ID.compareTo(this.team_ID);
    }
}

现在,在您的 main 中,您设置了一些 Set 集合,您可以在其中跟踪您的 BattingOrder 对象

我正在使用:

HashMap<String,BattingOrder> players = new HashMap<>();

Key 是 BattingOrder 的 identifierValue 是 BattingOrder

现在for-each line you are reading 执行以下操作:

 String[] parsedData = s.split(",");
 BattingOrder bo = new BattingOrder(parsedData[0], parsedData[1],parsedData[2], parsedData[3], parsedData[4], parsedData[5]);
 if(players.containsKey(bo.identifier())) {
     BattingOrder inMap = players.get(bo.identifier());
     if(bo.compareTo(inMap) > 0) {
         players.put(bo.identifier(), bo);
     }
 } else {
     players.put(bo.identifier(), bo);
 }

读完所有行后:

将您的HashMap 转换为List

List<BattingOrder> battingOrderList = new ArrayList<>(players.values());
Collections.sort(battingOrderList);

这里是the code and main tester

【讨论】:

  • 这行不通!! hashCode不是唯一的。您最终会在Map 中随机获取错误的元素。请阅读hashCode()equals() 的工作原理。
  • @BoristheSpider 实际上我希望在 hashCode() 上发生更高的冲突,因为我将它用作键...我希望不同的 BattingOrders 在特定字段上发生冲突,然后确定哪个具有更高的排名放在HashMap上
  • 是的,但是hashCode 溢出。您将在 other 字段上看似随机地发生冲突。当发生这种情况时,您认为冲突仅发生在subOrder 上的假设是错误的并且代码失败。哈希码的全部意义在于搜索空间小于所有对象的搜索空间。
  • @BoristheSpider my equals() 和 hashCode() 在相​​同的字段上执行检查,因此仍然尊重contract
  • 另外请注意,此定义与 equals 不一致,因此违反了 compareTo 方法协定的要求。
猜你喜欢
  • 1970-01-01
  • 2011-11-08
  • 1970-01-01
  • 2013-04-28
  • 2016-01-31
  • 1970-01-01
  • 1970-01-01
  • 2014-11-11
相关资源
最近更新 更多