0

i have a text file i want to add its data to priority queue and then print out 5 items with max value each line first has a name then a date then a value i want to print 5 max values with name and date

Queue<String> queue = new PriorityQueue<String>();
String file = "file";
String line;
int order = 1;
try{
    FileReader fr = new FileReader(file);
    BufferedReader br = new BufferedReader(fr);
    while ((line = br.readLine()) != null)   {
        queue.offer(line);
    }
    br.close();
} catch (IOException e){
    System.out.println("File not found");
}
while (!queue.isEmpty()){
    System.out.println(order + ".Number: " + queue.poll());
    order++;
}

data.txt :

tloxJcdiMqMWyDW 1976-11-24 3747
KWuHczAFXRGCeTZ 2015-12-5 1740
SyAckDyYyZhrsEK 1920-8-3 3164
pjKEnTTfcdoJwMy 2016-12-28 1941
ZsvJcYbmOFmdXfG 1923-10-10 8314
qkqDyFhObQVpByH 1934-7-21 4907
IRUMpmTSmJDVIJU 2012-12-26 376
nOCCDAmTilqnukW 1968-5-3 5811
uecbYlaCeaTSAsr 1937-4-1 9305
AMdPXptNGayPPAM 1949-2-25 1130
afTQNxogdxpQRpF 1912-11-18 5637
hBUJpjBJgyShNqk 2011-12-9 4075
dMGDWfIrPctuwBs 2005-3-15 8567
UBELfqonZOmmEGf 1954-7-29 7875
EuMbAKoKwYYERxy 1902-3-4 8291
OXvvwLXJjsXrfVI 1927-4-29 4693
amHPTQXCqHkYtXW 1991-8-24 8778
gfAcsQpChfukGlK 1971-7-14 4204
WHguJUYeLBYoton 1987-11-24 9664
ZvMoXwJqLhBlWiG 2006-6-7 7893

i have tried some other ways to save data to PQ and still didnt get any result

TheMurteza
  • 13
  • 6
  • 1
    *i want to print 5 max values* "Max" by what criteria? – g00se Nov 27 '22 at 14:01
  • 1
    You have created a `Queue` of `String`s. Although I guess you could store full lines from the file in there, a more idiomatic approach would involve defining a class representing the structure of the lines, with three fields of appropriate types. You would then use a `Queue` of objects of that type. – John Bollinger Nov 27 '22 at 14:05
  • ... plus, your objects ought to implement `Comparable` – g00se Nov 27 '22 at 14:08
  • This post may help you https://stackoverflow.com/a/12917598/12405221 – cha_lar Nov 27 '22 at 14:09

2 Answers2

0

Once you have your data class (let's call it Order) then you can do:

    Queue<Order> orders = Files.lines(Path.of(args[0]))
        .map(line -> line.split(" +"))
        .map(Order::new)
        .collect(Collectors.toCollection(PriorityQueue::new));

If you've made your class Comparable then all should be well.

g00se
  • 3,207
  • 2
  • 5
  • 9
0

Assuming you want compare by "value" i.e last value in input record e.g. 3747 from given input record "tloxJcdiMqMWyDW 1976-11-24 3747".

Queue<MyData> queue = new PriorityQueue<MyData>(new Comparator<MyData>()
        {
            @Override
            public int compare(MyData o1, MyData o2)
            {
                return o2.getValue() - o1.getValue();
            }
        });
        String file = "file";
        String line;
        int order = 1;
        DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                .appendOptional(DateTimeFormatter.ofPattern("yyyy-M-d"))
                .toFormatter();

        List<String> lines = new ArrayList<>();
        try{
            FileReader fr = new FileReader(file);
            BufferedReader br = new BufferedReader(fr);
            while ((line = br.readLine()) != null)   {
                lines.add(line);
                String data[] = line.split("\\s");
                MyData myData = new MyData(data[0],LocalDate.parse(data[1],formatter),Integer.parseInt(data[2]));
                queue.offer(myData);
            }
            br.close();
        } catch (IOException e){
            System.out.println("File not found");
        }

        while (!queue.isEmpty()){
           MyData result = queue.poll();
            System.out.println(order + ".Number: " + result.getValue() + " , Name: " + result.getName());
            order++;
        }

I created a class with three fields from input file assuming these are separated by space

import java.time.LocalDate;
import java.util.Objects;

public class MyData
{
    private String name;
    private LocalDate date;
    private int value;

    public MyData(String name, LocalDate date, int value)
    {
        this.name = name;
        this.date = date;
        this.value = value;
    }

    public int getValue()
    {
        return value;
    }
   
    public String getName()
    {
        return name;
    }

    @Override
    public boolean equals(Object o)
    {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        MyData myData = (MyData) o;
        return value == myData.value && Objects.equals(name, myData.name) && Objects.equals(date, myData.date);
    }

    @Override
    public int hashCode()
    {
        return Objects.hash(name, date, value);
    }
}

If you want only first 5 values then you can add if condition in below while loop and break once order reaches 5.

while (!queue.isEmpty()){
            System.out.println(order + ".Number: " + queue.poll().getValue());
            order++;
        }
  • its working and 5 max values but when i want to print the name witch belongs to the value its printing wrong name i did this while (!queue.isEmpty()){ System.out.println(order + ".Number: " + queue.poll().getValue() + "name :" + queue.poll().name); order++; } – TheMurteza Nov 27 '22 at 15:53
  • @TheMurteza : I have updated the solution to print the name . You are calling queue.poll() twice , that is the issue .If you are happy with solution please accept it as answer. – Knowledge_seeker Nov 28 '22 at 13:13