1

I have an arraylist of objects ArrayList<Tile> list Tile has attributes of new Tile("colour", value) I want to make a search function where I iterate though each Colour attribute of the Tile and each Value attribute within each colour in the arraylist (like a nested for each loop), is there an easy way of doing this?

5
  • How is Tile class defined? please share the code. Commented Oct 5, 2018 at 8:04
  • @NamrataShukla added Commented Oct 5, 2018 at 8:09
  • Have you looked into Java 8 streams? You can use filtering for example: mkyong.com/java8/java-8-streams-filter-examples Commented Oct 5, 2018 at 8:11
  • See stackoverflow.com/questions/22940416/… if you want to search for the first match. Commented Oct 5, 2018 at 8:49
  • Can you tell a simple example data of what the search function input and output might be? You can add it to the post. Commented Oct 5, 2018 at 8:59

1 Answer 1

3

Assuming Tile class has two attributes a String colour and an int value. It has a toString (java.lang.Object class's override method) like this:

@Override public String toString() {
    return colour + ":" + value;
}

Make some tiles:

Tile t1 = new Tile("red", 7); // constructor takes a colour and a value
Tile t2 = new Tile("red", 2);
Tile t3 = new Tile("blue", 9);
Tile t4 = new Tile("white", 17);
Tile t5 = new Tile("blue", 3);
Tile t6 = new Tile("red", 15);
Tile t7 = new Tile("white", 10);


Scenario 1:

The function takes a list of Tile objects and a String colour as input and returns all tiles with the input colour (and their values). There are two ways to do that and these are shown in two methods:

private static List<Tile> getTilesWithColor1(List<Tile> tilesList, String searchColor) {
    return tilesList.stream()
                     .filter(tile -> tile.getColour().equals(searchColor))
                     .collect(Collectors.toList());
}

private static List<Tile> getTilesWithColor2(List<Tile> tilesList, String searchColor) {
    List<Tile> result = new ArrayList<>();
    for (Tile t : tilesList) {
        if (t.getColour().equals(searchColor)) {
            result.add(t);
        }
    }
    return result;
}
  • The input: tilesList, colour="red"
  • The output (from both methods is same): [red:7, red:2, red:15]

I want to make a search function where I iterate though each Colour attribute of the Tile and each Value attribute within each colour in the arraylist (like a nested for each loop), is there an easy way of doing this?

One can alter this function to add additional conditions or filters to get required result.


Scenario 2:

Get all colors and their values:

private static Map<String, List<Integer>> getTileColorsAndValues(List<Tile> tilesList) {
    return tilesList.stream()
                     .collect(Collectors.groupingBy(Tile::getColour,
                         Collectors.mapping(Tile::getValue, Collectors.toList())));
}
  • The input: tilesList
  • The output: {red=[7, 2, 15], white=[17, 10], blue=[9, 3]}

Note one can get the values within the "red" tiles like this from the resulting map:

List<Integer> valuesList = map.get("red");


Scenario 3:

Get all tiles by color:

private static Map<String, List<Tile>> getTilesByColorsAndValues(List<Tile> tilesList) {
    return tilesList.stream()
                    .collect(Collectors.groupingBy(Tile::getColour));
}
  • The input: tilesList
  • The output: {red=[red:7, red:2, red:15], white=[white:17, white:10], blue=[blue:9, blue:3]}

Note one can get the tiles within the "red" tiles like this from the resulting map:

List<Tile> tilesList = map.get("red");



The Example's Code:

import java.util.*;
import java.util.stream.*;
import java.util.function.*;

public class TilesExample {

    public static void main(String [] args) {

        Tile t1 = new Tile("red", 7);
        Tile t2 = new Tile("red", 2);
        Tile t3 = new Tile("blue", 9);
        Tile t4 = new Tile("white", 17);
        Tile t5 = new Tile("blue", 3);
        Tile t6 = new Tile("red", 15);
        Tile t7 = new Tile("white", 10);
        List<Tile> tilesList = Arrays.asList(t1, t2, t3, t4, t5, t6, t7);

        System.out.println(getTilesWithColor1(tilesList, "red"));
        System.out.println(getTilesWithColor2(tilesList, "red"));

        System.out.println(getTileColorsAndValues(tilesList));

        System.out.println(getTilesByColorsAndValues(tilesList));
    }

    private static Map<String, List<Tile>> getTilesByColorsAndValues(List<Tile> tilesList) {
        return tilesList.stream()
                        .collect(Collectors.groupingBy(Tile::getColour));
    }

    private static Map<String, List<Integer>> getTileColorsAndValues(List<Tile> tilesList) {
        return tilesList.stream()
                        .collect(Collectors.groupingBy(Tile::getColour,
                            Collectors.mapping(Tile::getValue, Collectors.toList())));
    }

    private static List<Tile> getTilesWithColor1(List<Tile> tilesList, String searchColor) {
        return tilesList.stream()
                         .filter(tile -> tile.getColour().equals(searchColor))
                         .collect(Collectors.toList());
    }

    private static List<Tile> getTilesWithColor2(List<Tile> tilesList, String searchColor) {
        List<Tile> result = new ArrayList<>();
        for (Tile t : tilesList) {
            if (t.getColour().equals(searchColor)) {
                result.add(t);
            }
        }
        return result;
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks a bunch! this was very helpful. I really appreciate it
Did it answer your question? If so, which aspect of it?
all 3 solutions were helpful, solution 3 in particular helped me with the main search issue, and the other 2 solutions helped me with other problems I was having trouble with

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.