1

I have a member application, the data is going into an object and then the object is being stored in the array. I am using string and integers in the object.

I am writing a method to display all male members and sort them by their score but I am struggling with the logic for this.

I am thinking I might need to create another array to store the male members in once I have got them out of the main array but am not really sure.

Could anyone help please.

public static void displayAllMaleMembers(){     
    System.out.println("List of male members:\n");

    for (int i=0; i < memberCount; i++) {                    
        Member member = memberList[i];                  
        if (member.getGender().equals("male") && member.getScore() > 50){
            System.out.println("Name:  " +member.getName());
            System.out.println("Score: " +member.getScore());
            System.out.println();   
        }           
        Arrays.sort(memberList, Collections.reverseOrder()); 
    }
    System.out.println("The sorted names by score are:");

    for (Member member : memberList) {
        System.out.println("Name:     " +member.getName());
        System.out.println("Handicap: " +member.getScore());
    }
}
3
  • 1
    what's the current result? what do you expect instead? further, you probably don't want to do Arrays.sort(memberList, Collections.reverseOrder()); in each iteration. should be after the loop. Commented Dec 28, 2018 at 22:05
  • It's just showing the first member and then breaking with an Exception. I expect that it will print me all the male members only, then sort them into order of their scores and print them again. Commented Dec 28, 2018 at 22:11
  • 1
    what exception is that? please include it in your post. Commented Dec 28, 2018 at 22:13

5 Answers 5

1

The Problem

  1. You're sorting the entire memberList whereas you should first find all the students satisfying the said criteria and then sort the list once.
  2. You should not sort the memberList in each iteration as it's wrong and very inefficient.
  3. When it comes to printing, again you're printing the entire list not just the male members with scores greater than 50.

The Solution

First, you will need to copy only the male members with scores greater than 50 to a list:

List<Member> result = new ArrayList<>();
for(Member member : memberList)
    if ("male".equals(member.getGender()) 
                && member.getScore() > 50)
          result.add(member);

then sort it descending by member score:

result.sort(Comparator.comparingInt(Member::getScore).reversed());

then print:

result.forEach(member -> {
     System.out.println("Name:  " +member.getName());
     System.out.println("Score: " +member.getScore()); 
     System.out.println();   
});

Full code:

List<Member> result = new ArrayList<>();
for(Member member : memberList)
    if ("male".equals(member.getGender()) 
                && member.getScore() > 50)
      result.add(member);

result.sort(Comparator.comparingInt(Member::getScore).reversed());
result.forEach(member -> {
     System.out.println("Name:  " +member.getName());
     System.out.println("Score: " +member.getScore()); 
     System.out.println();   
});

Since you only want a result of male members sorted descending based on some criteria, you could also go with the stream approach simply because it's more readable and easier for this type of use case i.e. filtering and then applying further logic:

Arrays.stream(memberList) // create a Stream<Member>
      .filter(m -> "male".equals(m.getGender()) &&
            m.getScore() > 50) // retain only male members with score greater than 50
      .sorted(Comparator.comparingInt(Member::getScore).reversed()) // sort based on score descending i.e. highest to lowest
      .forEachOrdered(m -> {
             System.out.println("Name:     " +m.getName());
             System.out.println("Handicap: " +m.getScore());
             System.out.println();   
      }); // print the result
  1. Arrays.stream creates a Stream<Member>
  2. filter retains only the male members with score greater than 50
  3. sorted sorts the members based on their scores from highest to lowest.
  4. forEachOrdered then prints the results.
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for that. I have tried your Full Code extract but am getting an Exception in thread "main" java.lang.NullPointerException on the if ("male".equals(member.getGender()) line of code.
@norniron that means member is null. is it expected for the array memberList to sometimes contain null references? if so then you can prevent it with Arrays.stream(memberList).filter(Objects::nonNull).filter(m -> "male".equals(m.getGender()) && m.getScore() > 50) .... using the last solution of the post. note the addition of .filter(Objects::nonNull). However, if a given member should not be null then you'll need to debug your program and find out the problem.
Yes it might. That has sorted it and it is working, @Aomine thanks so much for the detailed help, that's brilliant. Many thanks.
0

You need to have your Member class implement Comparable and then implement the compareTo function however you want

https://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html

Comments

0

If your Java version is 1.8 or greater , you can use Stream with an easiest way.

final List<Member> memberListWhichIsMaleAndScoreGreaterThan50 = Arrays.stream(memberList)
        .filter(member -> member.getGender().equals("male") && member.getScore() > 50)
        .collect(Collectors.toList());
//do  whatever you want on this list.

Here filter is filtering the list with gender and score. After that collecting to list to make an operation if you want.

Comments

0

I have a nice solution for you. Using constructors and getters and setters, without complex functions. Due to you only need to print name and score you can concatenate them as a single string, sort them and finally divide the string.

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;

public class foo {

public Member me = new Member();

public void displayAllMaleMembers() {

    System.out.println("List of male members:");
    for (Member member : me.getMembers()) {
        if (member.getGender().equals("male") && member.getScore() > 50) {
            System.out.println("Name:  " + member.getName());
            System.out.println("Score: " + member.getScore());
            System.out.println();
        }
    }

    System.out.println("The sorted names by score are:");
    String[] sort = new String[me.getMembers().size()];
    // concatenate name + comma + score
    for (int i = 0; i < sort.length; i++) {
        sort[i] = me.getMembers().get(i).getName() + "," + me.getMembers().get(i).getScore();
    }
    Arrays.sort(sort, Collections.reverseOrder()); // sort the concatenated string
    // prints
    for (String s : sort) {
// Split() divides the concatenated string, 
// [0] is the first position of the string[] returned by spit(",");
        System.out.println("Name:     " + s.split(",")[0]); // string before comma: name
        System.out.println("Handicap: " + s.split(",")[1]); // string after comma: score
    }
}

//Main
public static void main(String[] args) {

    foo f = new foo();
    ArrayList<Member> m = new ArrayList<Member>();
    // Creates an arraylist using the constructor field from Member class
    m.add(new Member("Criss", 80, "male"));
    m.add(new Member("Frank", 20, "male"));
    m.add(new Member("Ann", 80, "femmale"));

    // adds the arraylist through setMembers method
    f.me.setMembers(m);
    // print data
    f.displayAllMaleMembers();
}

}

Getters and setters class: The arraylist<Members> stores all attributtes you need (score, name, gender)

import java.util.ArrayList;
public class Member {

String Name;
int Score;
String Gender;
ArrayList<Member> members = new ArrayList<>();

//Constructor using fields
public Member(String name, int score, String gender) {
    super();
    Name = name;
    Score = score;
    Gender = gender;
} 

// default
Member(){
}

public ArrayList<Member> getMembers() {
    return members;
}

// Creates an arrayList of Members
public void setMembers(ArrayList<Member> members) {
    this.members.addAll(members); //adds all arraylist items
}

public String getName() {
    return Name;
}

public void setName(String name) {
    Name = name;
}

public int getScore() {
    return Score;
}

public void setScore(int score) {
    Score = score;
}

public String getGender() {
    return Gender;
}

public void setGender(String gender) {
    Gender = gender;
}
}

Output:

List of male members:
Name:  Criss
Score: 80

The sorted names by score are:
Name:     Frank
Handicap: 20
Name:     Criss
Handicap: 80
Name:     Ann
Handicap: 80

Comments

0

First, the sort operation should be outside the for loop as tyou want to do that only one time. Second, you can sort the list in this way:

memberList.sort(Comparator.comparing(Member::getScore));

If your data are not stored in a List you can sort them in this way:

Arrays.sort(memberList, Comparator.comparingInt(Member::getScore));

Otherwise let your Member class implement Combarable interface.

1 Comment

I am getting an error with this, Cannot invoke sort(Comparator.comparing(Member::getScore)) on the array type Member[]));

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.